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 Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HD_DATASOURCELOCATOR_H
25 #define PXR_IMAGING_HD_DATASOURCELOCATOR_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/base/tf/token.h"
30 #include "pxr/base/tf/hash.h"
31 
32 #include "pxr/imaging/hd/api.h"
33 
34 #include <iosfwd>
35 
37 
38 /// \class HdDataSourceLocator
39 ///
40 /// Represents an object that can identify the location of a data source.
41 /// Data Source Locators are meant to be short lists of tokens that, taken
42 /// together, can represent the location of a given data source.
43 ///
45 {
46 public:
47 
48  /// Returns a common empty locator.
49  ///
50  /// This is an often needed locator and is quicker to get this way rather
51  /// than creating your own empty one.
52  HD_API
53  static const HdDataSourceLocator &EmptyLocator();
54 
55  /// Creates an empty locator.
56  ///
57  /// If all you need is an empty locator, see EmptyLocator().
58  ///
59  HD_API
61 
62  /// The following constructors take a number of tokens and build a locator
63  /// with the apporpriate number of tokens in the given order.
64  ///
65  /// These are convenience constructors for commonly used patterns. Note
66  /// that we generally expect a very small number of entities in a locator,
67  /// which is why we haven't gone with a more general N-way solution.
68  ///
69  HD_API
70  explicit HdDataSourceLocator(const TfToken &t1);
71  HD_API
72  HdDataSourceLocator(const TfToken &t1, const TfToken &t2);
73  HD_API
74  HdDataSourceLocator(const TfToken &t1, const TfToken &t2,
75  const TfToken &t3);
76  HD_API
77  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
78  const TfToken &t4);
79  HD_API
80  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
81  const TfToken &t4, const TfToken &t5);
82  HD_API
83  HdDataSourceLocator(const TfToken &t1, const TfToken &t2, const TfToken &t3,
84  const TfToken &t4, const TfToken &t5,
85  const TfToken &t6);
86 
87  /// Builds a data source locator from the \p tokens array of the given
88  /// \p count.
89  ///
90  HD_API
91  HdDataSourceLocator(size_t count, const TfToken *tokens);
92 
93  /// Copy constructor
94  HdDataSourceLocator(const HdDataSourceLocator &rhs) = default;
95 
96  /// Returns the number of elements (tokens) in this data source.
97  HD_API
98  size_t GetElementCount() const;
99 
100  /// Returns the element (token) at index \p i.
101  ///
102  /// If \p i is out of bounds, the behavior is undefined.
103  ///
104  HD_API
105  const TfToken &GetElement(size_t i) const;
106 
107  /// Returns the first element, or empty token if none.
108  HD_API
109  const TfToken &GetFirstElement() const;
110 
111  /// Returns the last element, or empty token if none.
112  HD_API
113  const TfToken &GetLastElement() const;
114 
115  /// Returns a copy of this data source locator with the last element
116  /// replaced by the one given by \p name. If this data source locator is
117  /// empty an identical copy is returned.
118  ///
119  HD_API
120  HdDataSourceLocator ReplaceLastElement(const TfToken &name) const;
121 
122  /// Returns a copy of this data source locator with the last element
123  /// removed.
124  ///
125  HD_API
126  HdDataSourceLocator RemoveLastElement() const;
127 
128  /// Returns a copy of this data source locator with the first element
129  /// removed.
130  ///
131  HD_API
132  HdDataSourceLocator RemoveFirstElement() const;
133 
134  /// Appends \p name to this data source locator.
135  HD_API
136  HdDataSourceLocator Append(const TfToken &name) const;
137 
138  /// Appends all of the elements in \p locator to this data source locator.
139  HD_API
140  HdDataSourceLocator Append(const HdDataSourceLocator &locator) const;
141 
142  /// Prepends \p name to this data source locator.
143  HD_API
144  HdDataSourceLocator Prepend(const TfToken &name) const;
145 
146  /// Prepends all of the elements in \p locator to this data source locator.
147  HD_API
148  HdDataSourceLocator Prepend(const HdDataSourceLocator &locator) const;
149 
150  /// Returns \c true if and only if this data source locator has \p prefix
151  /// as a prefix.
152  /// In particular, returns \c true if this locator is equal to \p prefix.
153  HD_API
154  bool HasPrefix(const HdDataSourceLocator &prefix) const;
155 
156  /// Returns a data source locator that represents the common prefix
157  /// between this data source and \p other.
158  ///
159  HD_API
160  HdDataSourceLocator GetCommonPrefix(const HdDataSourceLocator &other) const;
161 
162  /// Returns a copy of this data source locator with \p oldPrefix replaced
163  /// by \p newPrefix.
164  ///
165  HD_API
166  HdDataSourceLocator ReplacePrefix(
167  const HdDataSourceLocator &oldPrefix,
168  const HdDataSourceLocator &newPrefix) const;
169 
170  /// Returns \c true if and only if either of the two locators is a prefix
171  /// of the other one - in the sense of HasPrefix.
172  /// In particular, it is true if the two locators are equal.
173  ///
174  HD_API
175  bool Intersects(const HdDataSourceLocator &other) const;
176 
177  inline bool operator==(const HdDataSourceLocator &rhs) const {
178  return _tokens == rhs._tokens;
179  }
180 
181  inline bool operator!=(const HdDataSourceLocator &rhs) const {
182  return _tokens != rhs._tokens;
183  }
184 
185  /// Lexicographic order. If y has x as prefix, x < y.
186  HD_API
187  bool operator<(const HdDataSourceLocator &rhs) const;
188 
189  inline bool IsEmpty() const {
190  return _tokens.empty();
191  }
192 
193  /// Returns a string representation of this data source locator with the
194  /// given \p delimiter inserted between each element.
195  ///
196  HD_API
197  std::string GetString(const char *delimiter = "/") const;
198 
199  template <class HashState>
200  friend void TfHashAppend(HashState &h, HdDataSourceLocator const &myObj) {
201  h.AppendContiguous(myObj._tokens.data(), myObj._tokens.size());
202  }
203 
204  inline size_t Hash() const;
205 
206 private:
207  using _TokenVector = TfSmallVector<TfToken, 6>;
208  _TokenVector _tokens;
209 };
210 
211 inline size_t
213 {
214  return TfHash()(*this);
215 }
216 
217 HD_API std::ostream& operator<<(std::ostream& out,
218  const HdDataSourceLocator &self);
219 
220 //-----------------------------------------------------------------------------
221 
222 ///
223 /// \class HdDataSourceLocatorSet
224 ///
225 /// Represents a set of data source locators closed under descendancy. That is,
226 /// if a data source locator x is in the set (that is
227 /// HdDataSourceLocatorSet::Contains returns true), then every data source
228 /// locator y that has x as a prefix is implicitly also assumed to be in the set.
229 ///
230 /// In particular, the data source locator set <x, y> generated by x and y is
231 /// equivalent to (and will be simplified to) just <x> if x is a prefix of y.
232 ///
233 /// Note that HdDataSourceLocatorSet{HdDataSourceLocator()} is the universal
234 /// set containing every data source locator.
235 ///
237 {
238 private:
240 public:
242 
243  /// The empty set.
245 
246  /// The set containing everything.
247  HD_API
248  static const HdDataSourceLocatorSet &UniversalSet();
249 
250  HD_API
252 
253  // Initializer list constructor.
254  HD_API
256  const std::initializer_list<const HdDataSourceLocator> &l);
257 
258  /// Copy Ctor
259  HdDataSourceLocatorSet(const HdDataSourceLocatorSet &rhs) = default;
260 
261  /// Move Ctor.
263 
264  /// Move assignment operator.
266 
267  /// Copy assignment operator.
269  = default;
270 
271  HD_API
272  void insert(const HdDataSourceLocator &locator);
273 
274  /// Changes this set to be the union of this set and the given set.
275  HD_API
276  void insert(const HdDataSourceLocatorSet &locatorSet);
277 
278  /// Changes this set to be the union of this set and the given set.
279  HD_API
280  void insert(HdDataSourceLocatorSet &&locatorSet);
281 
282  /// append() is semantically equivalent to insert(), but works much faster
283  /// if \p locator would be added to the end of the set, lexicographically.
284  HD_API
285  void append(const HdDataSourceLocator &locator);
286 
287  bool operator==(const HdDataSourceLocatorSet &rhs) const {
288  return _locators == rhs._locators;
289  }
290 
291  bool operator!=(const HdDataSourceLocatorSet &rhs) const {
292  return !(*this == rhs);
293  }
294 
295  /// Iterates through minimal, lexicographically sorted list of
296  /// data source locators generating this set.
297  HD_API
298  const_iterator begin() const;
299  HD_API
300  const_iterator end() const;
301 
302  /// True if and only if locator or any of its descendants is
303  /// in the set (closed under descendancy).
304  ///
305  /// In other words, true if and only if there is a generator of this
306  /// set that intersects the given locator in the sense of
307  /// HdDataSourceLocator::Intersects.
308  HD_API
309  bool Intersects(const HdDataSourceLocator &locator) const;
310 
311  /// True if and only if the two sets (closed under descendancy) intersect.
312  ///
313  /// In other words, true if and only if there is a generator x in this
314  /// set and a generator y in the given set such that x and y intersect
315  /// in the sense of HdDataSourceLocator::Intersects. That is, one of the
316  /// two sets contains a prefix of the other set.
317  HD_API
318  bool Intersects(const HdDataSourceLocatorSet &locatorSet) const;
319 
320  /// True if and only if this set contains no data source locator.
321  HD_API
322  bool IsEmpty() const;
323 
324  /// True if the set (closed under descendancy) contains the given
325  /// locator.
326  ///
327  /// In other words, a prefix of the locator is a generator of
328  /// the set in the sense of HdDataSourceLocator::HasPrefix.
329  HD_API
330  bool Contains(const HdDataSourceLocator &locator) const;
331 
332  /// Returns a lexicographically sorted locator set wherein locators in this
333  /// set that have \p oldPrefix as a prefix use \p newPrefix instead. The
334  /// returned set is closed under descendancy and may have equal or fewer
335  /// data source locators as a result.
336  HD_API
338  const HdDataSourceLocator &oldPrefix,
339  const HdDataSourceLocator &newPrefix) const;
340 
341  class IntersectionIterator;
342  class IntersectionView;
343 
344  /// Returns intersection with a locator as a range-like object so that it
345  /// can be used in a for-loop.
346  ///
347  /// Every element in the intersection has locator as a prefix.
348  ///
349  /// Examples:
350  /// Intersection of { primvars:color } with primvars is
351  /// { primvars:color }.
352  /// Intersection of { primvars:color } with primvars:color:interpolation is
353  /// { primvars:color:interpolation }.
354  ///
355  HD_API
356  IntersectionView Intersection(const HdDataSourceLocator &locator) const;
357 
358 private:
359  // Sort and uniquify it.
360  void _Normalize();
361 
362  void _InsertAndDeleteSuffixes(_Locators::iterator *position,
363  const HdDataSourceLocator &locator);
364 
365  const_iterator _FirstIntersection(const HdDataSourceLocator &locator) const;
366 
367  // Lexicographically sorted minimal list of locators generating
368  // the set.
369  _Locators _locators;
370 };
371 
373 {
374 public:
375  using iterator_category = std::forward_iterator_tag;
378  using pointer = value_type*;
379  using difference_type = std::ptrdiff_t;
380 
382  : _isFirst(false)
383  {
384  }
385 
386  IntersectionIterator(const bool isFirst,
387  const const_iterator &iterator,
388  const const_iterator &end,
389  const HdDataSourceLocator &locator)
390  : _isFirst(isFirst)
391  , _iterator(iterator)
392  , _end(end)
393  , _locator(locator)
394  {
395  }
396 
397  HD_API
398  const HdDataSourceLocator &operator*() const;
399 
401  {
402  return std::addressof(**this);
403  }
404 
405  HD_API
407 
408  HD_API
410 
411  bool operator==(const IntersectionIterator &other) const noexcept
412  {
413  return _iterator == other._iterator;
414  }
415 
416  bool operator!=(const IntersectionIterator &other) const noexcept
417  {
418  return _iterator != other._iterator;
419  }
420 
421 private:
422  bool _isFirst;
423  const_iterator _iterator;
424  const_iterator _end;
425  HdDataSourceLocator _locator;
426 };
427 
429 {
430 public:
432  const IntersectionIterator &end)
433  : _begin(begin)
434  , _end(end)
435  {
436  }
437 
438  const IntersectionIterator &begin() const { return _begin; }
439 
440  const IntersectionIterator &end() const { return _end; }
441 
442 private:
443  const IntersectionIterator _begin;
444  const IntersectionIterator _end;
445 };
446 
447 HD_API std::ostream& operator<<(std::ostream& out,
448  const HdDataSourceLocatorSet &self);
449 
451 
452 #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
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
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:40
size_type size() const
Definition: smallVector.h:629
bool empty() const
Definition: smallVector.h:641
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:504
HD_API const TfToken & GetLastElement() const
Returns the last element, or empty token if none.
HD_API HdDataSourceLocator RemoveLastElement() const
Definition: token.h:87
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:1441
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:91
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:202
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:768