HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dataSourceLocator.h
Go to the documentation of this file.
1 //
2 // Copyright 2021 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_IMAGING_HD_DATASOURCELOCATOR_H
8 #define PXR_IMAGING_HD_DATASOURCELOCATOR_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/base/tf/token.h"
13 #include "pxr/base/tf/hash.h"
14 
15 #include "pxr/imaging/hd/api.h"
16 
17 #include <iosfwd>
18 
20 
21 /// \class HdDataSourceLocator
22 ///
23 /// Represents an object that can identify the location of a data source.
24 /// Data Source Locators are meant to be short lists of tokens that, taken
25 /// together, can represent the location of a given data source.
26 ///
28 {
29 public:
30 
31  /// Returns a common empty locator.
32  ///
33  /// This is an often needed locator and is quicker to get this way rather
34  /// than creating your own empty one.
35  HD_API
36  static const HdDataSourceLocator &EmptyLocator();
37 
38  /// Creates an empty locator.
39  ///
40  /// If all you need is an empty locator, see EmptyLocator().
41  ///
42  HD_API
44 
45  /// The following constructors take a number of tokens and build a locator
46  /// with the apporpriate number of tokens in the given order.
47  ///
48  /// These are convenience constructors for commonly used patterns. Note
49  /// that we generally expect a very small number of entities in a locator,
50  /// which is why we haven't gone with a more general N-way solution.
51  ///
52  HD_API
53  explicit HdDataSourceLocator(const TfToken &t1);
54  HD_API
55  HdDataSourceLocator(const TfToken &t1, const TfToken &t2);
56  HD_API
57  HdDataSourceLocator(const TfToken &t1, const TfToken &t2,
58  const TfToken &t3);
59  HD_API
60  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
61  const TfToken &t4);
62  HD_API
63  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
64  const TfToken &t4, const TfToken &t5);
65  HD_API
66  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
67  const TfToken &t4, const TfToken &t5,
68  const TfToken &t6);
69 
70  /// Builds a data source locator from the \p tokens array of the given
71  /// \p count.
72  ///
73  HD_API
74  HdDataSourceLocator(size_t count, const TfToken *tokens);
75 
76  /// Copy constructor
77  HdDataSourceLocator(const HdDataSourceLocator &rhs) = default;
78 
79  /// Returns the number of elements (tokens) in this data source.
80  HD_API
81  size_t GetElementCount() const;
82 
83  /// Returns the element (token) at index \p i.
84  ///
85  /// If \p i is out of bounds, the behavior is undefined.
86  ///
87  HD_API
88  const TfToken &GetElement(size_t i) const;
89 
90  /// Returns the first element, or empty token if none.
91  HD_API
92  const TfToken &GetFirstElement() const;
93 
94  /// Returns the last element, or empty token if none.
95  HD_API
96  const TfToken &GetLastElement() const;
97 
98  /// Returns a copy of this data source locator with the last element
99  /// replaced by the one given by \p name. If this data source locator is
100  /// empty an identical copy is returned.
101  ///
102  HD_API
103  HdDataSourceLocator ReplaceLastElement(const TfToken &name) const;
104 
105  /// Returns a copy of this data source locator with the last element
106  /// removed.
107  ///
108  HD_API
109  HdDataSourceLocator RemoveLastElement() const;
110 
111  /// Returns a copy of this data source locator with the first element
112  /// removed.
113  ///
114  HD_API
115  HdDataSourceLocator RemoveFirstElement() const;
116 
117  /// Appends \p name to this data source locator.
118  HD_API
119  HdDataSourceLocator Append(const TfToken &name) const;
120 
121  /// Appends all of the elements in \p locator to this data source locator.
122  HD_API
123  HdDataSourceLocator Append(const HdDataSourceLocator &locator) const;
124 
125  /// Prepends \p name to this data source locator.
126  HD_API
127  HdDataSourceLocator Prepend(const TfToken &name) const;
128 
129  /// Prepends all of the elements in \p locator to this data source locator.
130  HD_API
131  HdDataSourceLocator Prepend(const HdDataSourceLocator &locator) const;
132 
133  /// Returns \c true if and only if this data source locator has \p prefix
134  /// as a prefix.
135  /// In particular, returns \c true if this locator is equal to \p prefix.
136  HD_API
137  bool HasPrefix(const HdDataSourceLocator &prefix) const;
138 
139  /// Returns a data source locator that represents the common prefix
140  /// between this data source and \p other.
141  ///
142  HD_API
143  HdDataSourceLocator GetCommonPrefix(const HdDataSourceLocator &other) const;
144 
145  /// Returns a copy of this data source locator with \p oldPrefix replaced
146  /// by \p newPrefix.
147  ///
148  HD_API
149  HdDataSourceLocator ReplacePrefix(
150  const HdDataSourceLocator &oldPrefix,
151  const HdDataSourceLocator &newPrefix) const;
152 
153  /// Returns \c true if and only if either of the two locators is a prefix
154  /// of the other one - in the sense of HasPrefix.
155  /// In particular, it is true if the two locators are equal.
156  ///
157  HD_API
158  bool Intersects(const HdDataSourceLocator &other) const;
159 
160  inline bool operator==(const HdDataSourceLocator &rhs) const {
161  return _tokens == rhs._tokens;
162  }
163 
164  inline bool operator!=(const HdDataSourceLocator &rhs) const {
165  return _tokens != rhs._tokens;
166  }
167 
168  /// Lexicographic order. If y has x as prefix, x < y.
169  HD_API
170  bool operator<(const HdDataSourceLocator &rhs) const;
171 
172  inline bool IsEmpty() const {
173  return _tokens.empty();
174  }
175 
176  /// Returns a string representation of this data source locator with the
177  /// given \p delimiter inserted between each element.
178  ///
179  HD_API
180  std::string GetString(const char *delimiter = "/") const;
181 
182  template <class HashState>
183  friend void TfHashAppend(HashState &h, HdDataSourceLocator const &myObj) {
184  h.AppendContiguous(myObj._tokens.data(), myObj._tokens.size());
185  }
186 
187  inline size_t Hash() const;
188 
189 private:
190  using _TokenVector = TfSmallVector<TfToken, 6>;
191  _TokenVector _tokens;
192 };
193 
194 inline size_t
196 {
197  return TfHash()(*this);
198 }
199 
200 HD_API std::ostream& operator<<(std::ostream& out,
201  const HdDataSourceLocator &self);
202 
203 //-----------------------------------------------------------------------------
204 
205 ///
206 /// \class HdDataSourceLocatorSet
207 ///
208 /// Represents a set of data source locators closed under descendancy. That is,
209 /// if a data source locator x is in the set (that is
210 /// HdDataSourceLocatorSet::Contains returns true), then every data source
211 /// locator y that has x as a prefix is implicitly also assumed to be in the set.
212 ///
213 /// In particular, the data source locator set <x, y> generated by x and y is
214 /// equivalent to (and will be simplified to) just <x> if x is a prefix of y.
215 ///
216 /// Note that HdDataSourceLocatorSet{HdDataSourceLocator()} is the universal
217 /// set containing every data source locator.
218 ///
220 {
221 private:
223 public:
225 
226  /// The empty set.
228 
229  /// The set containing everything.
230  HD_API
231  static const HdDataSourceLocatorSet &UniversalSet();
232 
233  HD_API
235 
236  // Initializer list constructor.
237  HD_API
239  const std::initializer_list<const HdDataSourceLocator> &l);
240 
241  /// Copy Ctor
242  HdDataSourceLocatorSet(const HdDataSourceLocatorSet &rhs) = default;
243 
244  /// Move Ctor.
246 
247  /// Move assignment operator.
249 
250  /// Copy assignment operator.
252  = default;
253 
254  HD_API
255  void insert(const HdDataSourceLocator &locator);
256 
257  /// Changes this set to be the union of this set and the given set.
258  HD_API
259  void insert(const HdDataSourceLocatorSet &locatorSet);
260 
261  /// Changes this set to be the union of this set and the given set.
262  HD_API
263  void insert(HdDataSourceLocatorSet &&locatorSet);
264 
265  /// append() is semantically equivalent to insert(), but works much faster
266  /// if \p locator would be added to the end of the set, lexicographically.
267  HD_API
268  void append(const HdDataSourceLocator &locator);
269 
270  bool operator==(const HdDataSourceLocatorSet &rhs) const {
271  return _locators == rhs._locators;
272  }
273 
274  bool operator!=(const HdDataSourceLocatorSet &rhs) const {
275  return !(*this == rhs);
276  }
277 
278  /// Iterates through minimal, lexicographically sorted list of
279  /// data source locators generating this set.
280  HD_API
281  const_iterator begin() const;
282  HD_API
283  const_iterator end() const;
284 
285  /// True if and only if locator or any of its descendants is
286  /// in the set (closed under descendancy).
287  ///
288  /// In other words, true if and only if there is a generator of this
289  /// set that intersects the given locator in the sense of
290  /// HdDataSourceLocator::Intersects.
291  HD_API
292  bool Intersects(const HdDataSourceLocator &locator) const;
293 
294  /// True if and only if the two sets (closed under descendancy) intersect.
295  ///
296  /// In other words, true if and only if there is a generator x in this
297  /// set and a generator y in the given set such that x and y intersect
298  /// in the sense of HdDataSourceLocator::Intersects. That is, one of the
299  /// two sets contains a prefix of the other set.
300  HD_API
301  bool Intersects(const HdDataSourceLocatorSet &locatorSet) const;
302 
303  /// True if and only if this set contains no data source locator.
304  HD_API
305  bool IsEmpty() const;
306 
307  /// True if the set (closed under descendancy) contains the given
308  /// locator.
309  ///
310  /// In other words, a prefix of the locator is a generator of
311  /// the set in the sense of HdDataSourceLocator::HasPrefix.
312  HD_API
313  bool Contains(const HdDataSourceLocator &locator) const;
314 
315  /// Returns a lexicographically sorted locator set wherein locators in this
316  /// set that have \p oldPrefix as a prefix use \p newPrefix instead. The
317  /// returned set is closed under descendancy and may have equal or fewer
318  /// data source locators as a result.
319  HD_API
321  const HdDataSourceLocator &oldPrefix,
322  const HdDataSourceLocator &newPrefix) const;
323 
324  class IntersectionIterator;
325  class IntersectionView;
326 
327  /// Returns intersection with a locator as a range-like object so that it
328  /// can be used in a for-loop.
329  ///
330  /// Every element in the intersection has locator as a prefix.
331  ///
332  /// Examples:
333  /// Intersection of { primvars:color } with primvars is
334  /// { primvars:color }.
335  /// Intersection of { primvars:color } with primvars:color:interpolation is
336  /// { primvars:color:interpolation }.
337  ///
338  HD_API
339  IntersectionView Intersection(const HdDataSourceLocator &locator) const;
340 
341 private:
342  // Sort and uniquify it.
343  void _Normalize();
344 
345  void _InsertAndDeleteSuffixes(_Locators::iterator *position,
346  const HdDataSourceLocator &locator);
347 
348  const_iterator _FirstIntersection(const HdDataSourceLocator &locator) const;
349 
350  // Lexicographically sorted minimal list of locators generating
351  // the set.
352  _Locators _locators;
353 };
354 
356 {
357 public:
358  using iterator_category = std::forward_iterator_tag;
361  using pointer = value_type*;
362  using difference_type = std::ptrdiff_t;
363 
365  : _isFirst(false)
366  {
367  }
368 
369  IntersectionIterator(const bool isFirst,
370  const const_iterator &iterator,
371  const const_iterator &end,
372  const HdDataSourceLocator &locator)
373  : _isFirst(isFirst)
374  , _iterator(iterator)
375  , _end(end)
376  , _locator(locator)
377  {
378  }
379 
380  HD_API
381  const HdDataSourceLocator &operator*() const;
382 
384  {
385  return std::addressof(**this);
386  }
387 
388  HD_API
390 
391  HD_API
393 
394  bool operator==(const IntersectionIterator &other) const noexcept
395  {
396  return _iterator == other._iterator;
397  }
398 
399  bool operator!=(const IntersectionIterator &other) const noexcept
400  {
401  return _iterator != other._iterator;
402  }
403 
404 private:
405  bool _isFirst;
406  const_iterator _iterator;
407  const_iterator _end;
408  HdDataSourceLocator _locator;
409 };
410 
412 {
413 public:
415  const IntersectionIterator &end)
416  : _begin(begin)
417  , _end(end)
418  {
419  }
420 
421  const IntersectionIterator &begin() const { return _begin; }
422 
423  const IntersectionIterator &end() const { return _end; }
424 
425 private:
426  const IntersectionIterator _begin;
427  const IntersectionIterator _end;
428 };
429 
430 HD_API std::ostream& operator<<(std::ostream& out,
431  const HdDataSourceLocatorSet &self);
432 
434 
435 #endif // PXR_IMAGING_HD_DATASOURCELOCATOR_H
HD_API bool Intersects(const HdDataSourceLocator &other) const
const IntersectionIterator & end() const
friend void TfHashAppend(HashState &h, HdDataSourceLocator const &myObj)
HD_API const HdDataSourceLocator & operator*() const
bool operator==(const HdDataSourceLocator &rhs) const
HD_API HdDataSourceLocator Append(const TfToken &name) const
Appends name to this data source locator.
HD_API bool Intersects(const HdDataSourceLocator &locator) const
HdDataSourceLocatorSet()
The empty set.
HD_API HdDataSourceLocator ReplacePrefix(const HdDataSourceLocator &oldPrefix, const HdDataSourceLocator &newPrefix) const
size_t Hash() const
HD_API const TfToken & GetElement(size_t i) const
HD_API const TfToken & GetFirstElement() const
Returns the first element, or empty token if none.
HD_API std::string GetString(const char *delimiter="/") const
IntersectionIterator(const bool isFirst, const const_iterator &iterator, const const_iterator &end, const HdDataSourceLocator &locator)
typename _Locators::const_iterator const_iterator
HD_API bool IsEmpty() const
True if and only if this set contains no data source locator.
#define HD_API
Definition: api.h:23
size_type size() const
Definition: smallVector.h:596
bool empty() const
Definition: smallVector.h:608
HD_API bool Contains(const HdDataSourceLocator &locator) const
bool operator!=(const HdDataSourceLocator &rhs) const
HD_API IntersectionView Intersection(const HdDataSourceLocator &locator) const
HD_API void append(const HdDataSourceLocator &locator)
HdDataSourceLocatorSet & operator=(HdDataSourceLocatorSet &&rhs)=default
Move assignment operator.
Definition: hash.h:472
HD_API const TfToken & GetLastElement() const
Returns the last element, or empty token if none.
HD_API HdDataSourceLocator RemoveLastElement() const
Definition: token.h:70
bool operator==(const IntersectionIterator &other) const noexcept
HD_API HdDataSourceLocatorSet ReplacePrefix(const HdDataSourceLocator &oldPrefix, const HdDataSourceLocator &newPrefix) const
GLuint GLuint end
Definition: glcorearb.h:475
HD_API std::ostream & operator<<(std::ostream &out, const HdDataSourceLocator &self)
HD_API HdDataSourceLocator Prepend(const TfToken &name) const
Prepends name to this data source locator.
HD_API IntersectionIterator & operator++()
IntersectionView(const IntersectionIterator &begin, const IntersectionIterator &end)
static HD_API const HdDataSourceLocatorSet & UniversalSet()
The set containing everything.
const HdDataSourceLocator * operator->() const
GLuint const GLchar * name
Definition: glcorearb.h:786
HD_API bool HasPrefix(const HdDataSourceLocator &prefix) const
HD_API const_iterator begin() const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
HD_API bool operator<(const HdDataSourceLocator &rhs) const
Lexicographic order. If y has x as prefix, x < y.
HD_API void insert(const HdDataSourceLocator &locator)
HD_API const_iterator end() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
HD_API HdDataSourceLocator ReplaceLastElement(const TfToken &name) const
bool operator!=(const IntersectionIterator &other) const noexcept
SIM_API const UT_StringHolder position
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
HD_API HdDataSourceLocator RemoveFirstElement() const
bool operator!=(const HdDataSourceLocatorSet &rhs) const
static HD_API const HdDataSourceLocator & EmptyLocator()
bool operator==(const HdDataSourceLocatorSet &rhs) const
HD_API HdDataSourceLocator()
const HdDataSourceLocator * const_iterator
Definition: smallVector.h:180
HD_API HdDataSourceLocator GetCommonPrefix(const HdDataSourceLocator &other) const
const IntersectionIterator & begin() const
GLint GLsizei count
Definition: glcorearb.h:405
HD_API size_t GetElementCount() const
Returns the number of elements (tokens) in this data source.
value_type * data()
Definition: smallVector.h:735