HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
path.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 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_USD_SDF_PATH_H
25 #define PXR_USD_SDF_PATH_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/sdf/api.h"
29 #include "pxr/usd/sdf/pool.h"
30 #include "pxr/usd/sdf/tokens.h"
31 #include "pxr/base/arch/defines.h"
32 #include "pxr/base/tf/stl.h"
33 #include "pxr/base/tf/token.h"
34 #include "pxr/base/vt/traits.h"
35 
36 #include <hboost/intrusive_ptr.hpp>
37 #include <hboost/operators.hpp>
38 
39 #include <algorithm>
40 #include <iterator>
41 #include <set>
42 #include <string>
43 #include <type_traits>
44 #include <utility>
45 #include <vector>
46 
48 
49 class Sdf_PathNode;
51 
52 // Ref-counting pointer to a path node.
53 // Intrusive ref-counts are used to keep the size of SdfPath
54 // the same as a raw pointer. (shared_ptr, by comparison,
55 // is the size of two pointers.)
56 
57 typedef hboost::intrusive_ptr<const Sdf_PathNode> Sdf_PathNodeConstRefPtr;
58 
61 
62 // Tags used for the pools of path nodes.
63 struct Sdf_PathPrimTag;
64 struct Sdf_PathPropTag;
65 
66 // These are validated below.
67 static constexpr size_t Sdf_SizeofPrimPathNode = sizeof(void *) * 3;
68 static constexpr size_t Sdf_SizeofPropPathNode = sizeof(void *) * 3;
69 
71  Sdf_PathPrimTag, Sdf_SizeofPrimPathNode, /*regionBits=*/8>;
72 
74  Sdf_PathPropTag, Sdf_SizeofPropPathNode, /*regionBits=*/8>;
75 
78 
79 // This handle class wraps up the raw Prim/PropPartPool handles.
80 template <class Handle, bool Counted, class PathNode=Sdf_PathNode const>
82 private:
84 
85 public:
86  static constexpr bool IsCounted = Counted;
87 
88  constexpr Sdf_PathNodeHandleImpl() noexcept {};
89 
90  explicit
91  Sdf_PathNodeHandleImpl(Sdf_PathNode const *p, bool add_ref = true)
92  : _poolHandle(Handle::GetHandle(reinterpret_cast<char const *>(p))) {
93  if (p && add_ref) {
94  _AddRef(p);
95  }
96  }
97 
98  explicit
99  Sdf_PathNodeHandleImpl(Handle h, bool add_ref = true)
100  : _poolHandle(h) {
101  if (h && add_ref) {
102  _AddRef();
103  }
104  }
105 
107  : _poolHandle(rhs._poolHandle) {
108  if (_poolHandle) {
109  _AddRef();
110  }
111  }
112 
114  if (_poolHandle) {
115  _DecRef();
116  }
117  }
118 
121  if (Counted && *this == rhs) {
122  return *this;
123  }
124  this_type(rhs).swap(*this);
125  return *this;
126  }
127 
129  : _poolHandle(rhs._poolHandle) {
130  rhs._poolHandle = nullptr;
131  }
132 
135  this_type(std::move(rhs)).swap(*this);
136  return *this;
137  }
138 
140  operator=(Sdf_PathNode const *rhs) noexcept {
141  this_type(rhs).swap(*this);
142  return *this;
143  }
144 
145  void reset() noexcept {
146  _poolHandle = Handle { nullptr };
147  }
148 
149  inline Sdf_PathNode const *
150  get() const noexcept {
151  return reinterpret_cast<Sdf_PathNode *>(_poolHandle.GetPtr());
152  }
153 
154  Sdf_PathNode const &
155  operator*() const {
156  return *get();
157  }
158 
159  Sdf_PathNode const *
160  operator->() const {
161  return get();
162  }
163 
164  explicit operator bool() const noexcept {
165  return static_cast<bool>(_poolHandle);
166  }
167 
168  void swap(Sdf_PathNodeHandleImpl &rhs) noexcept {
169  _poolHandle.swap(rhs._poolHandle);
170  }
171 
172  inline bool operator==(Sdf_PathNodeHandleImpl const &rhs) const noexcept {
173  return _poolHandle == rhs._poolHandle;
174  }
175  inline bool operator!=(Sdf_PathNodeHandleImpl const &rhs) const noexcept {
176  return _poolHandle != rhs._poolHandle;
177  }
178  inline bool operator<(Sdf_PathNodeHandleImpl const &rhs) const noexcept {
179  return _poolHandle < rhs._poolHandle;
180  }
181 private:
182 
183  inline void _AddRef(Sdf_PathNode const *p) const {
184  if (Counted) {
186  }
187  }
188 
189  inline void _AddRef() const {
190  _AddRef(get());
191  }
192 
193  inline void _DecRef() const {
194  if (Counted) {
195  intrusive_ptr_release(get());
196  }
197  }
198 
199  Handle _poolHandle { nullptr };
200 };
201 
204 
207 
208 
209 /// A set of SdfPaths.
210 typedef std::set<class SdfPath> SdfPathSet;
211 /// A vector of SdfPaths.
212 typedef std::vector<class SdfPath> SdfPathVector;
213 
214 // Tell VtValue that SdfPath is cheap to copy.
216 
217 /// \class SdfPath
218 ///
219 /// A path value used to locate objects in layers or scenegraphs.
220 ///
221 /// \section sec_SdfPath_Overview Overview
222 ///
223 /// SdfPath is used in several ways:
224 /// \li As a storage key for addressing and accessing values held in a SdfLayer
225 /// \li As a namespace identity for scenegraph objects
226 /// \li As a way to refer to other scenegraph objects through relative paths
227 ///
228 /// The paths represented by an SdfPath class may be either relative or
229 /// absolute. Relative paths are relative to the prim object that contains them
230 /// (that is, if an SdfRelationshipSpec target is relative, it is relative to
231 /// the SdfPrimSpec object that owns the SdfRelationshipSpec object).
232 ///
233 /// SdfPath objects can be readily created from and converted back to strings,
234 /// but as SdfPath objects, they have behaviors that make it easy and efficient
235 /// to work with them. The SdfPath class provides a full range of methods for
236 /// manipulating scene paths by appending a namespace child, appending a
237 /// relationship target, getting the parent path,
238 /// and so on. Since the SdfPath class uses a node-based representation
239 /// internally, you should use the editing functions rather than converting to
240 /// and from strings if possible.
241 ///
242 /// \section sec_SdfPath_Syntax Path Syntax
243 ///
244 /// Like a filesystem path, an SdfPath is conceptually just a sequence of
245 /// path components. Unlike a filesystem path, each component has a type,
246 /// and the type is indicated by the syntax.
247 ///
248 /// Two separators are used between parts of a path. A slash ("/") following an
249 /// identifier is used to introduce a namespace child. A period (".") following
250 /// an identifier is used to introduce a property. A property may also have
251 /// several non-sequential colons (':') in its name to provide a rudimentary
252 /// namespace within properties but may not end or begin with a colon.
253 ///
254 /// A leading slash in the string representation of an SdfPath object indicates
255 /// an absolute path. Two adjacent periods indicate the parent namespace.
256 ///
257 /// Brackets ("[" and "]") are used to indicate relationship target paths for
258 /// relational attributes.
259 ///
260 /// The first part in a path is assumed to be a namespace child unless
261 /// it is preceded by a period. That means:
262 /// \li <c>/Foo</c> is an absolute path specifying the root prim Foo.
263 /// \li <c>/Foo/Bar</c> is an absolute path specifying namespace child Bar
264 /// of root prim Foo.
265 /// \li <c>/Foo/Bar.baz</c> is an absolute path specifying property \c baz of
266 /// namespace child Bar of root prim Foo.
267 /// \li <c>Foo</c> is a relative path specifying namespace child Foo of
268 /// the current prim.
269 /// \li <c>Foo/Bar</c> is a relative path specifying namespace child Bar of
270 /// namespace child Foo of the current prim.
271 /// \li <c>Foo/Bar.baz</c> is a relative path specifying property \c baz of
272 /// namespace child Bar of namespace child Foo of the current prim.
273 /// \li <c>.foo</c> is a relative path specifying the property \c foo of the
274 /// current prim.
275 /// \li <c>/Foo.bar[/Foo.baz].attrib</c> is a relational attribute path. The
276 /// relationship <c>/Foo.bar</c> has a target <c>/Foo.baz</c>. There is a
277 /// relational attribute \c attrib on that relationship-&gt;target pair.
278 ///
279 /// \section sec_SdfPath_ThreadSafety A Note on Thread-Safety
280 ///
281 /// SdfPath is strongly thread-safe, in the sense that zero additional
282 /// synchronization is required between threads creating or using SdfPath
283 /// values. Just like TfToken, SdfPath values are immutable. Internally,
284 /// SdfPath uses a global prefix tree to efficiently share representations
285 /// of paths, and provide fast equality/hashing operations, but
286 /// modifications to this table are internally synchronized. Consequently,
287 /// as with TfToken, for best performance it is important to minimize
288 /// the number of values created (since it requires synchronized access to
289 /// this table) or copied (since it requires atomic ref-counting operations).
290 ///
291 class SdfPath
292 {
293 public:
294  /// The empty path value, equivalent to SdfPath().
295  SDF_API static const SdfPath & EmptyPath();
296 
297  /// The absolute path representing the top of the
298  /// namespace hierarchy.
299  SDF_API static const SdfPath & AbsoluteRootPath();
300 
301  /// The relative path representing "self".
302  SDF_API static const SdfPath & ReflexiveRelativePath();
303 
304  /// \name Constructors
305  /// @{
306 
307  /// Constructs the default, empty path.
308  ///
309 #if defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR <= 6
310  SdfPath() noexcept {
311  // This generates a single instruction instead of 2 on gcc 6.3. Seems
312  // to be fixed on gcc 7+ and newer clangs.
313  memset(this, 0, sizeof(*this));
314  }
315 #else
316  SdfPath() noexcept = default;
317 #endif
318 
319  /// Creates a path from the given string.
320  ///
321  /// If the given string is not a well-formed path, this will raise
322  /// a Tf error. Note that passing an empty std::string() will also
323  /// raise an error; the correct way to get the empty path is SdfPath().
324  ///
325  /// Internal dot-dots will be resolved by removing the first dot-dot,
326  /// the element preceding it, and repeating until no internal dot-dots
327  /// remain.
328  ///
329  /// Note that most often new paths are expected to be created by
330  /// asking existing paths to return modified versions of themselves.
331  //
332  // XXX We may want to revisit the behavior when constructing
333  // a path with an empty string ("") to accept it without error and
334  // return EmptyPath.
335  SDF_API explicit SdfPath(const std::string &path);
336 
337  /// @}
338 
339  /// \name Querying paths
340  /// @{
341 
342  /// Returns the number of path elements in this path.
343  SDF_API size_t GetPathElementCount() const;
344 
345  /// Returns whether the path is absolute.
346  SDF_API bool IsAbsolutePath() const;
347 
348  /// Return true if this path is the AbsoluteRootPath().
349  SDF_API bool IsAbsoluteRootPath() const;
350 
351  /// Returns whether the path identifies a prim.
352  SDF_API bool IsPrimPath() const;
353 
354  /// Returns whether the path identifies a prim or the absolute root.
355  SDF_API bool IsAbsoluteRootOrPrimPath() const;
356 
357  /// Returns whether the path identifies a root prim.
358  ///
359  /// the path must be absolute and have a single element
360  /// (for example <c>/foo</c>).
361  SDF_API bool IsRootPrimPath() const;
362 
363  /// Returns whether the path identifies a property.
364  ///
365  /// A relational attribute is considered to be a property, so this
366  /// method will return true for relational attributes as well
367  /// as properties of prims.
368  SDF_API bool IsPropertyPath() const;
369 
370  /// Returns whether the path identifies a prim's property.
371  ///
372  /// A relational attribute is not a prim property.
373  SDF_API bool IsPrimPropertyPath() const;
374 
375  /// Returns whether the path identifies a namespaced property.
376  ///
377  /// A namespaced property has colon embedded in its name.
378  SDF_API bool IsNamespacedPropertyPath() const;
379 
380  /// Returns whether the path identifies a variant selection for a
381  /// prim.
382  SDF_API bool IsPrimVariantSelectionPath() const;
383 
384  /// Return true if this path is a prim path or is a prim variant
385  /// selection path.
387 
388  /// Returns whether the path or any of its parent paths identifies
389  /// a variant selection for a prim.
391 
392  /// Return true if this path contains any property elements, false
393  /// otherwise. A false return indicates a prim-like path, specifically a
394  /// root path, a prim path, or a prim variant selection path. A true return
395  /// indicates a property-like path: a prim property path, a target path, a
396  /// relational attribute path, etc.
398  return static_cast<bool>(_propPart);
399  }
400 
401  /// Return true if this path is or has a prefix that's a target path or a
402  /// mapper path.
403  SDF_API bool ContainsTargetPath() const;
404 
405  /// Returns whether the path identifies a relational attribute.
406  ///
407  /// If this is true, IsPropertyPath() will also be true.
408  SDF_API bool IsRelationalAttributePath() const;
409 
410  /// Returns whether the path identifies a relationship or
411  /// connection target.
412  SDF_API bool IsTargetPath() const;
413 
414  /// Returns whether the path identifies a connection mapper.
415  SDF_API bool IsMapperPath() const;
416 
417  /// Returns whether the path identifies a connection mapper arg.
418  SDF_API bool IsMapperArgPath() const;
419 
420  /// Returns whether the path identifies a connection expression.
421  SDF_API bool IsExpressionPath() const;
422 
423  /// Returns true if this is the empty path (SdfPath::EmptyPath()).
424  inline bool IsEmpty() const noexcept {
425  // No need to check _propPart, because it can only be non-null if
426  // _primPart is non-null.
427  return !_primPart;
428  }
429 
430  /// Return the string representation of this path as a TfToken.
431  ///
432  /// This function is recommended only for human-readable or diagnostic
433  /// output. Use the SdfPath API to manipulate paths. It is less
434  /// error-prone and has better performance.
435  SDF_API TfToken GetAsToken() const;
436 
437  /// Return the string representation of this path as a TfToken lvalue.
438  ///
439  /// This function returns a persistent lvalue. If an rvalue will suffice,
440  /// call GetAsToken() instead. That avoids populating internal data
441  /// structures to hold the persistent token.
442  ///
443  /// This function is recommended only for human-readable or diagnostic
444  /// output. Use the SdfPath API to manipulate paths. It is less
445  /// error-prone and has better performance.
446  SDF_API TfToken const &GetToken() const;
447 
448  /// Return the string representation of this path as a std::string.
449  ///
450  /// This function is recommended only for human-readable or diagnostic
451  /// output. Use the SdfPath API to manipulate paths. It is less
452  /// error-prone and has better performance.
454 
455  /// Return the string representation of this path as a std::string.
456  ///
457  /// This function returns a persistent lvalue. If an rvalue will suffice,
458  /// call GetAsString() instead. That avoids populating internal data
459  /// structures to hold the persistent string.
460  ///
461  /// This function is recommended only for human-readable or diagnostic
462  /// output. Use the SdfPath API to manipulate paths. It is less
463  /// error-prone and has better performance.
464  SDF_API const std::string &GetString() const;
465 
466  /// Returns the string representation of this path as a c string.
467  ///
468  /// This function returns a pointer to a persistent c string. If a
469  /// temporary c string will suffice, call GetAsString().c_str() instead.
470  /// That avoids populating internal data structures to hold the persistent
471  /// string.
472  ///
473  /// This function is recommended only for human-readable or diagnostic
474  /// output. Use the SdfPath API to manipulate paths. It is less
475  /// error-prone and has better performance.
476  SDF_API const char *GetText() const;
477 
478  /// Returns the prefix paths of this path.
479  ///
480  /// Prefixes are returned in order of shortest to longest. The path
481  /// itself is returned as the last prefix.
482  /// Note that if the prefix order does not need to be from shortest to
483  /// longest, it is more efficient to use GetAncestorsRange, which
484  /// produces an equivalent set of paths, ordered from longest to shortest.
485  SDF_API SdfPathVector GetPrefixes() const;
486 
487  /// Return up to \p numPrefixes prefix paths of this path.
488  ///
489  /// Prefixes are returned in order of shortest to longest. The path itself
490  /// is returned as the last prefix. Note that if the prefix order does not
491  /// need to be from shortest to longest, it is more efficient to use
492  /// GetAncestorsRange, which produces an equivalent set of paths, ordered
493  /// from longest to shortest. If \p numPrefixes is 0 or greater than the
494  /// number of this path's prefixes, fill all prefixes.
495  SDF_API SdfPathVector GetPrefixes(size_t numPrefixes) const;
496 
497  /// Fills prefixes with prefixes of this path.
498  ///
499  /// This avoids copy constructing the return value.
500  ///
501  /// Prefixes are returned in order of shortest to longest. The path
502  /// itself is returned as the last prefix.
503  /// Note that if the prefix order does not need to be from shortest to
504  /// longest, it is more efficient to use GetAncestorsRange(), which
505  /// produces an equivalent set of paths, ordered from longest to shortest.
506  SDF_API void GetPrefixes(SdfPathVector *prefixes) const;
507 
508  /// Fill \p prefixes with up to \p numPrefixes prefixes of this path.
509  ///
510  /// Prefixes are filled in order of shortest to longest. The path itself is
511  /// included as the last prefix. Note that if the prefix order does not
512  /// need to be from shortest to longest, it can be more efficient to use
513  /// GetAncestorsRange(), which produces an equivalent set of paths, ordered
514  /// from longest to shortest. If \p numPrefixes is 0 or greater than the
515  /// number of this path's prefixes, fill all prefixes.
516  SDF_API void GetPrefixes(SdfPathVector *prefixes, size_t numPrefixes) const;
517 
518  /// Return a range for iterating over the ancestors of this path.
519  ///
520  /// The range provides iteration over the prefixes of a path, ordered
521  /// from longest to shortest (the opposite of the order of the prefixes
522  /// returned by GetPrefixes).
524 
525  /// Returns the name of the prim, property or relational
526  /// attribute identified by the path.
527  ///
528  /// Returns EmptyPath if this path is a target or mapper path.
529  ///
530  /// <ul>
531  /// <li>Returns "" for EmptyPath.</li>
532  /// <li>Returns "." for ReflexiveRelativePath.</li>
533  /// <li>Returns ".." for a path ending in ParentPathElement.</li>
534  /// </ul>
535  SDF_API const std::string &GetName() const;
536 
537  /// Returns the name of the prim, property or relational
538  /// attribute identified by the path, as a token.
539  SDF_API const TfToken &GetNameToken() const;
540 
541  /// Returns an ascii representation of the "terminal" element
542  /// of this path, which can be used to reconstruct the path using
543  /// \c AppendElementString() on its parent.
544  ///
545  /// EmptyPath(), AbsoluteRootPath(), and ReflexiveRelativePath() are
546  /// \em not considered elements (one of the defining properties of
547  /// elements is that they have a parent), so \c GetElementString() will
548  /// return the empty string for these paths.
549  ///
550  /// Unlike \c GetName() and \c GetTargetPath(), which provide you "some"
551  /// information about the terminal element, this provides a complete
552  /// representation of the element, for all element types.
553  ///
554  /// Also note that whereas \c GetName(), \c GetNameToken(), \c GetText(),
555  /// \c GetString(), and \c GetTargetPath() return cached results,
556  /// \c GetElementString() always performs some amount of string
557  /// manipulation, which you should keep in mind if performance is a concern.
559 
560  /// Like GetElementString() but return the value as a TfToken.
562 
563  /// Return a copy of this path with its final component changed to
564  /// \a newName. This path must be a prim or property path.
565  ///
566  /// This method is shorthand for path.GetParentPath().AppendChild(newName)
567  /// for prim paths, path.GetParentPath().AppendProperty(newName) for
568  /// prim property paths, and
569  /// path.GetParentPath().AppendRelationalAttribute(newName) for relational
570  /// attribute paths.
571  ///
572  /// Note that only the final path component is ever changed. If the name of
573  /// the final path component appears elsewhere in the path, it will not be
574  /// modified.
575  ///
576  /// Some examples:
577  ///
578  /// ReplaceName('/chars/MeridaGroup', 'AngusGroup') -> '/chars/AngusGroup'
579  /// ReplaceName('/Merida.tx', 'ty') -> '/Merida.ty'
580  /// ReplaceName('/Merida.tx[targ].tx', 'ty') -> '/Merida.tx[targ].ty'
581  ///
582  SDF_API SdfPath ReplaceName(TfToken const &newName) const;
583 
584  /// Returns the relational attribute or mapper target path
585  /// for this path.
586  ///
587  /// Returns EmptyPath if this is not a target, relational attribute or
588  /// mapper path.
589  ///
590  /// Note that it is possible for a path to have multiple "target" paths.
591  /// For example a path that identifies a connection target for a
592  /// relational attribute includes the target of the connection as well
593  /// as the target of the relational attribute. In these cases, the
594  /// "deepest" or right-most target path will be returned (the connection
595  /// target in this example).
596  SDF_API const SdfPath &GetTargetPath() const;
597 
598  /// Returns all the relationship target or connection target
599  /// paths contained in this path, and recursively all the target paths
600  /// contained in those target paths in reverse depth-first order.
601  ///
602  /// For example, given the path: '/A/B.a[/C/D.a[/E/F.a]].a[/A/B.a[/C/D.a]]'
603  /// this method produces: '/A/B.a[/C/D.a]', '/C/D.a', '/C/D.a[/E/F.a]',
604  /// '/E/F.a'
605  SDF_API void GetAllTargetPathsRecursively(SdfPathVector *result) const;
606 
607  /// Returns the variant selection for this path, if this is a variant
608  /// selection path.
609  /// Returns a pair of empty strings if this path is not a variant
610  /// selection path.
611  SDF_API
612  std::pair<std::string, std::string> GetVariantSelection() const;
613 
614  /// Return true if both this path and \a prefix are not the empty
615  /// path and this path has \a prefix as a prefix. Return false otherwise.
616  SDF_API bool HasPrefix( const SdfPath &prefix ) const;
617 
618  /// @}
619 
620  /// \name Creating new paths by modifying existing paths
621  /// @{
622 
623  /// Return the path that identifies this path's namespace parent.
624  ///
625  /// For a prim path (like '/foo/bar'), return the prim's parent's path
626  /// ('/foo'). For a prim property path (like '/foo/bar.property'), return
627  /// the prim's path ('/foo/bar'). For a target path (like
628  /// '/foo/bar.property[/target]') return the property path
629  /// ('/foo/bar.property'). For a mapper path (like
630  /// '/foo/bar.property.mapper[/target]') return the property path
631  /// ('/foo/bar.property). For a relational attribute path (like
632  /// '/foo/bar.property[/target].relAttr') return the relationship target's
633  /// path ('/foo/bar.property[/target]'). For a prim variant selection path
634  /// (like '/foo/bar{var=sel}') return the prim path ('/foo/bar'). For a
635  /// root prim path (like '/rootPrim'), return AbsoluteRootPath() ('/'). For
636  /// a single element relative prim path (like 'relativePrim'), return
637  /// ReflexiveRelativePath() ('.'). For ReflexiveRelativePath(), return the
638  /// relative parent path ('..').
639  ///
640  /// Note that the parent path of a relative parent path ('..') is a relative
641  /// grandparent path ('../..'). Use caution writing loops that walk to
642  /// parent paths since relative paths have infinitely many ancestors. To
643  /// more safely traverse ancestor paths, consider iterating over an
644  /// SdfPathAncestorsRange instead, as returend by GetAncestorsRange().
645  SDF_API SdfPath GetParentPath() const;
646 
647  /// Creates a path by stripping all relational attributes, targets,
648  /// properties, and variant selections from the leafmost prim path, leaving
649  /// the nearest path for which \a IsPrimPath() returns true.
650  ///
651  /// See \a GetPrimOrPrimVariantSelectionPath also.
652  ///
653  /// If the path is already a prim path, the same path is returned.
654  SDF_API SdfPath GetPrimPath() const;
655 
656  /// Creates a path by stripping all relational attributes, targets,
657  /// and properties, leaving the nearest path for which
658  /// \a IsPrimOrPrimVariantSelectionPath() returns true.
659  ///
660  /// See \a GetPrimPath also.
661  ///
662  /// If the path is already a prim or a prim variant selection path, the same
663  /// path is returned.
665 
666  /// Creates a path by stripping all properties and relational
667  /// attributes from this path, leaving the path to the containing prim.
668  ///
669  /// If the path is already a prim or absolute root path, the same
670  /// path is returned.
671  SDF_API SdfPath GetAbsoluteRootOrPrimPath() const;
672 
673  /// Create a path by stripping all variant selections from all
674  /// components of this path, leaving a path with no embedded variant
675  /// selections.
676  SDF_API SdfPath StripAllVariantSelections() const;
677 
678  /// Creates a path by appending a given relative path to this path.
679  ///
680  /// If the newSuffix is a prim path, then this path must be a prim path
681  /// or a root path.
682  ///
683  /// If the newSuffix is a prim property path, then this path must be
684  /// a prim path or the ReflexiveRelativePath.
685  SDF_API SdfPath AppendPath(const SdfPath &newSuffix) const;
686 
687  /// Creates a path by appending an element for \p childName
688  /// to this path.
689  ///
690  /// This path must be a prim path, the AbsoluteRootPath
691  /// or the ReflexiveRelativePath.
692  SDF_API SdfPath AppendChild(TfToken const &childName) const;
693 
694  /// Creates a path by appending an element for \p propName
695  /// to this path.
696  ///
697  /// This path must be a prim path or the ReflexiveRelativePath.
698  SDF_API SdfPath AppendProperty(TfToken const &propName) const;
699 
700  /// Creates a path by appending an element for \p variantSet
701  /// and \p variant to this path.
702  ///
703  /// This path must be a prim path.
704  SDF_API
705  SdfPath AppendVariantSelection(const std::string &variantSet,
706  const std::string &variant) const;
707 
708  /// Creates a path by appending an element for
709  /// \p targetPath.
710  ///
711  /// This path must be a prim property or relational attribute path.
712  SDF_API SdfPath AppendTarget(const SdfPath &targetPath) const;
713 
714  /// Creates a path by appending an element for
715  /// \p attrName to this path.
716  ///
717  /// This path must be a target path.
718  SDF_API
719  SdfPath AppendRelationalAttribute(TfToken const &attrName) const;
720 
721  /// Replaces the relational attribute's target path
722  ///
723  /// The path must be a relational attribute path.
724  SDF_API
725  SdfPath ReplaceTargetPath( const SdfPath &newTargetPath ) const;
726 
727  /// Creates a path by appending a mapper element for
728  /// \p targetPath.
729  ///
730  /// This path must be a prim property or relational attribute path.
731  SDF_API SdfPath AppendMapper(const SdfPath &targetPath) const;
732 
733  /// Creates a path by appending an element for
734  /// \p argName.
735  ///
736  /// This path must be a mapper path.
737  SDF_API SdfPath AppendMapperArg(TfToken const &argName) const;
738 
739  /// Creates a path by appending an expression element.
740  ///
741  /// This path must be a prim property or relational attribute path.
742  SDF_API SdfPath AppendExpression() const;
743 
744  /// Creates a path by extracting and appending an element
745  /// from the given ascii element encoding.
746  ///
747  /// Attempting to append a root or empty path (or malformed path)
748  /// or attempting to append \em to the EmptyPath will raise an
749  /// error and return the EmptyPath.
750  ///
751  /// May also fail and return EmptyPath if this path's type cannot
752  /// possess a child of the type encoded in \p element.
753  SDF_API SdfPath AppendElementString(const std::string &element) const;
754 
755  /// Like AppendElementString() but take the element as a TfToken.
756  SDF_API SdfPath AppendElementToken(const TfToken &elementTok) const;
757 
758  /// Returns a path with all occurrences of the prefix path
759  /// \p oldPrefix replaced with the prefix path \p newPrefix.
760  ///
761  /// If fixTargetPaths is true, any embedded target paths will also
762  /// have their paths replaced. This is the default.
763  ///
764  /// If this is not a target, relational attribute or mapper path this
765  /// will do zero or one path prefix replacements, if not the number of
766  /// replacements can be greater than one.
767  SDF_API
768  SdfPath ReplacePrefix(const SdfPath &oldPrefix,
769  const SdfPath &newPrefix,
770  bool fixTargetPaths=true) const;
771 
772  /// Returns a path with maximal length that is a prefix path of
773  /// both this path and \p path.
774  SDF_API SdfPath GetCommonPrefix(const SdfPath &path) const;
775 
776  /// Find and remove the longest common suffix from two paths.
777  ///
778  /// Returns this path and \p otherPath with the longest common suffix
779  /// removed (first and second, respectively). If the two paths have no
780  /// common suffix then the paths are returned as-is. If the paths are
781  /// equal then this returns empty paths for relative paths and absolute
782  /// roots for absolute paths. The paths need not be the same length.
783  ///
784  /// If \p stopAtRootPrim is \c true then neither returned path will be
785  /// the root path. That, in turn, means that some common suffixes will
786  /// not be removed. For example, if \p stopAtRootPrim is \c true then
787  /// the paths /A/B and /B will be returned as is. Were it \c false
788  /// then the result would be /A and /. Similarly paths /A/B/C and
789  /// /B/C would return /A/B and /B if \p stopAtRootPrim is \c true but
790  /// /A and / if it's \c false.
791  SDF_API
792  std::pair<SdfPath, SdfPath>
793  RemoveCommonSuffix(const SdfPath& otherPath,
794  bool stopAtRootPrim = false) const;
795 
796  /// Returns the absolute form of this path using \p anchor
797  /// as the relative basis.
798  ///
799  /// \p anchor must be an absolute prim path.
800  ///
801  /// If this path is a relative path, resolve it using \p anchor as the
802  /// relative basis.
803  ///
804  /// If this path is already an absolute path, just return a copy.
805  SDF_API SdfPath MakeAbsolutePath(const SdfPath & anchor) const;
806 
807  /// Returns the relative form of this path using \p anchor
808  /// as the relative basis.
809  ///
810  /// \p anchor must be an absolute prim path.
811  ///
812  /// If this path is an absolute path, return the corresponding relative path
813  /// that is relative to the absolute path given by \p anchor.
814  ///
815  /// If this path is a relative path, return the optimal relative
816  /// path to the absolute path given by \p anchor. (The optimal
817  /// relative path from a given prim path is the relative path
818  /// with the least leading dot-dots.
819  SDF_API SdfPath MakeRelativePath(const SdfPath & anchor) const;
820 
821  /// @}
822 
823  /// \name Valid path strings, prim and property names
824  /// @{
825 
826  /// Returns whether \p name is a legal identifier for any
827  /// path component.
828  SDF_API static bool IsValidIdentifier(const std::string &name);
829 
830  /// Returns whether \p name is a legal namespaced identifier.
831  /// This returns \c true if IsValidIdentifier() does.
833 
834  /// Tokenizes \p name by the namespace delimiter.
835  /// Returns the empty vector if \p name is not a valid namespaced
836  /// identifier.
837  SDF_API static std::vector<std::string> TokenizeIdentifier(const std::string &name);
838 
839  /// Tokenizes \p name by the namespace delimiter.
840  /// Returns the empty vector if \p name is not a valid namespaced
841  /// identifier.
842  SDF_API
844 
845  /// Join \p names into a single identifier using the namespace delimiter.
846  /// Any empty strings present in \p names are ignored when joining.
847  SDF_API
848  static std::string JoinIdentifier(const std::vector<std::string> &names);
849 
850  /// Join \p names into a single identifier using the namespace delimiter.
851  /// Any empty strings present in \p names are ignored when joining.
852  SDF_API
853  static std::string JoinIdentifier(const TfTokenVector& names);
854 
855  /// Join \p lhs and \p rhs into a single identifier using the
856  /// namespace delimiter.
857  /// Returns \p lhs if \p rhs is empty and vice verse.
858  /// Returns an empty string if both \p lhs and \p rhs are empty.
859  SDF_API
860  static std::string JoinIdentifier(const std::string &lhs,
861  const std::string &rhs);
862 
863  /// Join \p lhs and \p rhs into a single identifier using the
864  /// namespace delimiter.
865  /// Returns \p lhs if \p rhs is empty and vice verse.
866  /// Returns an empty string if both \p lhs and \p rhs are empty.
867  SDF_API
868  static std::string JoinIdentifier(const TfToken &lhs, const TfToken &rhs);
869 
870  /// Returns \p name stripped of any namespaces.
871  /// This does not check the validity of the name; it just attempts
872  /// to remove anything that looks like a namespace.
873  SDF_API
875 
876  /// Returns \p name stripped of any namespaces.
877  /// This does not check the validity of the name; it just attempts
878  /// to remove anything that looks like a namespace.
879  SDF_API
880  static TfToken StripNamespace(const TfToken &name);
881 
882  /// Returns (\p name, \c true) where \p name is stripped of the prefix
883  /// specified by \p matchNamespace if \p name indeed starts with
884  /// \p matchNamespace. Returns (\p name, \c false) otherwise, with \p name
885  /// unmodified.
886  ///
887  /// This function deals with both the case where \p matchNamespace contains
888  /// the trailing namespace delimiter ':' or not.
889  ///
890  SDF_API
891  static std::pair<std::string, bool>
893  const std::string &matchNamespace);
894 
895  /// Return true if \p pathString is a valid path string, meaning that
896  /// passing the string to the \a SdfPath constructor will result in a valid,
897  /// non-empty SdfPath. Otherwise, return false and if \p errMsg is not NULL,
898  /// set the pointed-to string to the parse error.
899  SDF_API
900  static bool IsValidPathString(const std::string &pathString,
901  std::string *errMsg = 0);
902 
903  /// @}
904 
905  /// \name Operators
906  /// @{
907 
908  /// Equality operator.
909  inline bool operator==(const SdfPath &rhs) const {
910  return _AsInt() == rhs._AsInt();
911  }
912 
913  /// Inequality operator.
914  inline bool operator!=(const SdfPath &rhs) const {
915  return !(*this == rhs);
916  }
917 
918  /// Comparison operator.
919  ///
920  /// This orders paths lexicographically, aka dictionary-style.
921  ///
922  inline bool operator<(const SdfPath &rhs) const {
923  if (_AsInt() == rhs._AsInt()) {
924  return false;
925  }
926  if (!_primPart || !rhs._primPart) {
927  return !_primPart && rhs._primPart;
928  }
929  // Valid prim parts -- must walk node structure, etc.
930  return _LessThanInternal(*this, rhs);
931  }
932 
933  /// Greater than operator.
934  /// \sa SdfPath::operator<(const SdfPath&)
935  inline bool operator>(const SdfPath& rhs) const {
936  return rhs < *this;
937  }
938 
939  /// Less than or equal operator.
940  /// \sa SdfPath::operator<(const SdfPath&)
941  inline bool operator<=(const SdfPath& rhs) const {
942  return !(rhs < *this);
943  }
944 
945  /// Greater than or equal operator.
946  /// \sa SdfPath::operator<(const SdfPath&)
947  inline bool operator>=(const SdfPath& rhs) const {
948  return !(*this < rhs);
949  }
950 
951  template <class HashState>
952  friend void TfHashAppend(HashState &h, SdfPath const &path) {
953  // The hash function is pretty sensitive performance-wise. Be
954  // careful making changes here, and run tests.
955  uint32_t primPart, propPart;
956  memcpy(&primPart, &path._primPart, sizeof(primPart));
957  memcpy(&propPart, &path._propPart, sizeof(propPart));
958  h.Append(primPart);
959  h.Append(propPart);
960  }
961 
962  // For hash maps and sets
963  struct Hash {
964  inline size_t operator()(const SdfPath& path) const {
965  return TfHash()(path);
966  }
967  };
968 
969  inline size_t GetHash() const {
970  return Hash()(*this);
971  }
972 
973  // For cases where an unspecified total order that is not stable from
974  // run-to-run is needed.
975  struct FastLessThan {
976  inline bool operator()(const SdfPath& a, const SdfPath& b) const {
977  return a._AsInt() < b._AsInt();
978  }
979  };
980 
981  /// @}
982 
983  /// \name Utilities
984  /// @{
985 
986  /// Given some vector of paths, get a vector of concise unambiguous
987  /// relative paths.
988  ///
989  /// GetConciseRelativePaths requires a vector of absolute paths. It
990  /// finds a set of relative paths such that each relative path is
991  /// unique.
992  SDF_API static SdfPathVector
993  GetConciseRelativePaths(const SdfPathVector& paths);
994 
995  /// Remove all elements of \a paths that are prefixed by other
996  /// elements in \a paths. As a side-effect, the result is left in sorted
997  /// order.
998  SDF_API static void RemoveDescendentPaths(SdfPathVector *paths);
999 
1000  /// Remove all elements of \a paths that prefix other elements in
1001  /// \a paths. As a side-effect, the result is left in sorted order.
1002  SDF_API static void RemoveAncestorPaths(SdfPathVector *paths);
1003 
1004  /// @}
1005 
1006 private:
1007 
1008  // This is used for all internal path construction where we do operations
1009  // via nodes and then want to return a new path with a resulting prim and
1010  // property parts.
1011 
1012  // Accept rvalues.
1013  explicit SdfPath(Sdf_PathPrimNodeHandle &&primNode)
1014  : _primPart(std::move(primNode)) {}
1015 
1016  SdfPath(Sdf_PathPrimNodeHandle &&primPart,
1017  Sdf_PathPropNodeHandle &&propPart)
1018  : _primPart(std::move(primPart))
1019  , _propPart(std::move(propPart)) {}
1020 
1021  // Construct from prim & prop parts.
1022  SdfPath(Sdf_PathPrimNodeHandle const &primPart,
1023  Sdf_PathPropNodeHandle const &propPart)
1024  : _primPart(primPart)
1025  , _propPart(propPart) {}
1026 
1027  // Construct from prim & prop node pointers.
1028  SdfPath(Sdf_PathNode const *primPart,
1029  Sdf_PathNode const *propPart)
1030  : _primPart(primPart)
1031  , _propPart(propPart) {}
1032 
1033  friend class Sdf_PathNode;
1034  friend class Sdfext_PathAccess;
1036 
1037  // converts elements to a string for parsing (unfortunate)
1038  static std::string
1039  _ElementsToString(bool absolute, const std::vector<std::string> &elements);
1040 
1041  SdfPath _ReplacePrimPrefix(SdfPath const &oldPrefix,
1042  SdfPath const &newPrefix) const;
1043 
1044  SdfPath _ReplaceTargetPathPrefixes(SdfPath const &oldPrefix,
1045  SdfPath const &newPrefix) const;
1046 
1047  SdfPath _ReplacePropPrefix(SdfPath const &oldPrefix,
1048  SdfPath const &newPrefix,
1049  bool fixTargetPaths) const;
1050 
1051  // Helper to implement the uninlined portion of operator<.
1052  SDF_API static bool
1053  _LessThanInternal(SdfPath const &lhs, SdfPath const &rhs);
1054 
1055  inline uint64_t _AsInt() const {
1056  static_assert(sizeof(*this) == sizeof(uint64_t), "");
1057  uint64_t ret;
1058  std::memcpy(&ret, this, sizeof(*this));
1059  return ret;
1060  }
1061 
1062  friend void swap(SdfPath &lhs, SdfPath &rhs) {
1063  lhs._primPart.swap(rhs._primPart);
1064  lhs._propPart.swap(rhs._propPart);
1065  }
1066 
1067  SDF_API friend char const *
1068  Sdf_PathGetDebuggerPathText(SdfPath const &);
1069 
1070  Sdf_PathPrimNodeHandle _primPart;
1071  Sdf_PathPropNodeHandle _propPart;
1072 
1073 };
1074 
1075 
1076 /// \class SdfPathAncestorsRange
1077 ///
1078 /// Range representing a path and ancestors, and providing methods for
1079 /// iterating over them.
1080 ///
1081 /// An ancestor range represents a path and all of its ancestors ordered from
1082 /// nearest to furthest (root-most).
1083 /// For example, given a path like `/a/b.prop`, the range represents paths
1084 /// `/a/b.prop`, `/a/b` and `/a`, in that order.
1085 /// A range accepts relative paths as well: For path `a/b.prop`, the range
1086 /// represents paths 'a/b.prop`, `a/b` and `a`.
1087 /// If a path contains parent path elements, (`..`), those elements are treated
1088 /// as elements of the range. For instance, given path `../a/b`, the range
1089 /// represents paths `../a/b`, `../a` and `..`.
1090 /// This represents the same of set of `prefix` paths as SdfPath::GetPrefixes,
1091 /// but in reverse order.
1093 {
1094 public:
1095 
1096  SdfPathAncestorsRange(const SdfPath& path)
1097  : _path(path) {}
1098 
1099  const SdfPath& GetPath() const { return _path; }
1100 
1101  struct iterator {
1102  using iterator_category = std::forward_iterator_tag;
1103  using value_type = SdfPath;
1104  using difference_type = std::ptrdiff_t;
1105  using reference = const SdfPath&;
1106  using pointer = const SdfPath*;
1107 
1108  iterator(const SdfPath& path) : _path(path) {}
1109 
1110  iterator() = default;
1111 
1112  SDF_API
1113  iterator& operator++();
1114 
1115  const SdfPath& operator*() const { return _path; }
1116 
1117  const SdfPath* operator->() const { return &_path; }
1118 
1119  bool operator==(const iterator& o) const { return _path == o._path; }
1120 
1121  bool operator!=(const iterator& o) const { return _path != o._path; }
1122 
1123  /// Return the distance between two iterators.
1124  /// It is only valid to compute the distance between paths
1125  /// that share a common prefix.
1126  SDF_API friend difference_type
1127  distance(const iterator& first, const iterator& last);
1128 
1129  private:
1130  SdfPath _path;
1131  };
1132 
1133  iterator begin() const { return iterator(_path); }
1134 
1135  iterator end() const { return iterator(); }
1136 
1137 private:
1138  SdfPath _path;
1139 };
1140 
1141 
1142 // Overload hash_value for SdfPath. Used by things like hboost::hash.
1143 inline size_t hash_value(SdfPath const &path)
1144 {
1145  return path.GetHash();
1146 }
1147 
1148 /// Writes the string representation of \p path to \p out.
1149 SDF_API std::ostream & operator<<( std::ostream &out, const SdfPath &path );
1150 
1151 // Helper for SdfPathFindPrefixedRange & SdfPathFindLongestPrefix. A function
1152 // object that returns an SdfPath const & unchanged.
1154  inline SdfPath const &operator()(SdfPath const &arg) const {
1155  return arg;
1156  }
1157 };
1158 
1159 /// Find the subrange of the sorted range [\a begin, \a end) that includes all
1160 /// paths prefixed by \a path. The input range must be ordered according to
1161 /// SdfPath::operator<. If your range's iterators' value_types are not SdfPath,
1162 /// but you can obtain SdfPaths from them (e.g. map<SdfPath, X>::iterator), you
1163 /// can pass a function to extract the path from the dereferenced iterator in
1164 /// \p getPath.
1165 template <class ForwardIterator, class GetPathFn = Sdf_PathIdentity>
1166 std::pair<ForwardIterator, ForwardIterator>
1167 SdfPathFindPrefixedRange(ForwardIterator begin, ForwardIterator end,
1168  SdfPath const &prefix,
1169  GetPathFn const &getPath = GetPathFn()) {
1170  using IterRef =
1171  typename std::iterator_traits<ForwardIterator>::reference;
1172 
1173  struct Compare {
1174  Compare(GetPathFn const &getPath) : _getPath(getPath) {}
1175  GetPathFn const &_getPath;
1176  bool operator()(IterRef a, SdfPath const &b) const {
1177  return _getPath(a) < b;
1178  }
1179  };
1180 
1181  std::pair<ForwardIterator, ForwardIterator> result;
1182 
1183  // First, use lower_bound to find where \a prefix would go.
1184  result.first = std::lower_bound(begin, end, prefix, Compare(getPath));
1185 
1186  // Next, find end of range starting from the lower bound, using the
1187  // prefixing condition to define the boundary.
1188  result.second = TfFindBoundary(result.first, end,
1189  [&prefix, &getPath](IterRef iterRef) {
1190  return getPath(iterRef).HasPrefix(prefix);
1191  });
1192 
1193  return result;
1194 }
1195 
1196 template <class RandomAccessIterator, class GetPathFn>
1197 RandomAccessIterator
1199  RandomAccessIterator end,
1200  SdfPath const &path,
1201  bool strictPrefix,
1202  GetPathFn const &getPath)
1203 {
1204  using IterRef =
1205  typename std::iterator_traits<RandomAccessIterator>::reference;
1206 
1207  struct Compare {
1208  Compare(GetPathFn const &getPath) : _getPath(getPath) {}
1209  GetPathFn const &_getPath;
1210  bool operator()(IterRef a, SdfPath const &b) const {
1211  return _getPath(a) < b;
1212  }
1213  };
1214 
1215  // Search for the path in [begin, end). If present, return it. If not,
1216  // examine prior element in [begin, end). If none, return end. Else, is it
1217  // a prefix of path? If so, return it. Else find common prefix of that
1218  // element and path and recurse.
1219 
1220  // If empty sequence, return.
1221  if (begin == end)
1222  return end;
1223 
1224  Compare comp(getPath);
1225 
1226  // Search for where this path would lexicographically appear in the range.
1227  RandomAccessIterator result = std::lower_bound(begin, end, path, comp);
1228 
1229  // If we didn't get the end, check to see if we got the path exactly if
1230  // we're not looking for a strict prefix.
1231  if (!strictPrefix && result != end && getPath(*result) == path) {
1232  return result;
1233  }
1234 
1235  // If we got begin (and didn't match in the case of a non-strict prefix)
1236  // then there's no prefix.
1237  if (result == begin) {
1238  return end;
1239  }
1240 
1241  // If the prior element is a prefix, we're done.
1242  if (path.HasPrefix(getPath(*--result))) {
1243  return result;
1244  }
1245 
1246  // Otherwise, find the common prefix of the lexicographical predecessor and
1247  // look for its prefix in the preceding range.
1248  SdfPath newPath = path.GetCommonPrefix(getPath(*result));
1249  auto origEnd = end;
1250  do {
1251  end = result;
1252  result = std::lower_bound(begin, end, newPath, comp);
1253 
1254  if (result != end && getPath(*result) == newPath) {
1255  return result;
1256  }
1257  if (result == begin) {
1258  return origEnd;
1259  }
1260  if (newPath.HasPrefix(getPath(*--result))) {
1261  return result;
1262  }
1263  newPath = newPath.GetCommonPrefix(getPath(*result));
1264  } while (true);
1265 }
1266 
1267 /// Return an iterator to the element of [\a begin, \a end) that is the longest
1268 /// prefix of the given path (including the path itself), if there is such an
1269 /// element, otherwise \a end. The input range must be ordered according to
1270 /// SdfPath::operator<. If your range's iterators' value_types are not SdfPath,
1271 /// but you can obtain SdfPaths from them (e.g. vector<pair<SdfPath,
1272 /// X>>::iterator), you can pass a function to extract the path from the
1273 /// dereferenced iterator in \p getPath.
1274 template <class RandomAccessIterator, class GetPathFn = Sdf_PathIdentity,
1275  class = typename std::enable_if<
1276  std::is_base_of<
1277  std::random_access_iterator_tag,
1278  typename std::iterator_traits<
1279  RandomAccessIterator>::iterator_category
1280  >::value
1281  >::type
1282  >
1283 RandomAccessIterator
1284 SdfPathFindLongestPrefix(RandomAccessIterator begin,
1285  RandomAccessIterator end,
1286  SdfPath const &path,
1287  GetPathFn const &getPath = GetPathFn())
1288 {
1290  begin, end, path, /*strictPrefix=*/false, getPath);
1291 }
1292 
1293 /// Return an iterator to the element of [\a begin, \a end) that is the longest
1294 /// prefix of the given path (excluding the path itself), if there is such an
1295 /// element, otherwise \a end. The input range must be ordered according to
1296 /// SdfPath::operator<. If your range's iterators' value_types are not SdfPath,
1297 /// but you can obtain SdfPaths from them (e.g. vector<pair<SdfPath,
1298 /// X>>::iterator), you can pass a function to extract the path from the
1299 /// dereferenced iterator in \p getPath.
1300 template <class RandomAccessIterator, class GetPathFn = Sdf_PathIdentity,
1301  class = typename std::enable_if<
1302  std::is_base_of<
1303  std::random_access_iterator_tag,
1304  typename std::iterator_traits<
1305  RandomAccessIterator>::iterator_category
1306  >::value
1307  >::type
1308  >
1309 RandomAccessIterator
1310 SdfPathFindLongestStrictPrefix(RandomAccessIterator begin,
1311  RandomAccessIterator end,
1312  SdfPath const &path,
1313  GetPathFn const &getPath = GetPathFn())
1314 {
1316  begin, end, path, /*strictPrefix=*/true, getPath);
1317 }
1318 
1319 template <class Iter, class MapParam, class GetPathFn = Sdf_PathIdentity>
1320 Iter
1322  MapParam map, SdfPath const &path, bool strictPrefix,
1323  GetPathFn const &getPath = GetPathFn())
1324 {
1325  // Search for the path in map. If present, return it. If not, examine
1326  // prior element in map. If none, return end. Else, is it a prefix of
1327  // path? If so, return it. Else find common prefix of that element and
1328  // path and recurse.
1329 
1330  const Iter mapEnd = map.end();
1331 
1332  // If empty, return.
1333  if (map.empty())
1334  return mapEnd;
1335 
1336  // Search for where this path would lexicographically appear in the range.
1337  Iter result = map.lower_bound(path);
1338 
1339  // If we didn't get the end, check to see if we got the path exactly if
1340  // we're not looking for a strict prefix.
1341  if (!strictPrefix && result != mapEnd && getPath(*result) == path)
1342  return result;
1343 
1344  // If we got begin (and didn't match in the case of a non-strict prefix)
1345  // then there's no prefix.
1346  if (result == map.begin())
1347  return mapEnd;
1348 
1349  // If the prior element is a prefix, we're done.
1350  if (path.HasPrefix(getPath(*--result)))
1351  return result;
1352 
1353  // Otherwise, find the common prefix of the lexicographical predecessor and
1354  // recurse looking for it or its longest prefix in the preceding range. We
1355  // always pass strictPrefix=false, since now we're operating on prefixes of
1356  // the original caller's path.
1357  return Sdf_PathFindLongestPrefixImpl<Iter, MapParam>(
1358  map, path.GetCommonPrefix(getPath(*result)), /*strictPrefix=*/false,
1359  getPath);
1360 }
1361 
1362 /// Return an iterator pointing to the element of \a set whose key is the
1363 /// longest prefix of the given path (including the path itself). If there is
1364 /// no such element, return \a set.end().
1365 SDF_API
1366 typename std::set<SdfPath>::const_iterator
1367 SdfPathFindLongestPrefix(std::set<SdfPath> const &set, SdfPath const &path);
1368 
1369 /// Return an iterator pointing to the element of \a map whose key is the
1370 /// longest prefix of the given path (including the path itself). If there is
1371 /// no such element, return \a map.end().
1372 template <class T>
1373 typename std::map<SdfPath, T>::const_iterator
1374 SdfPathFindLongestPrefix(std::map<SdfPath, T> const &map, SdfPath const &path)
1375 {
1377  typename std::map<SdfPath, T>::const_iterator,
1378  std::map<SdfPath, T> const &>(map, path, /*strictPrefix=*/false,
1379  TfGet<0>());
1380 }
1381 template <class T>
1382 typename std::map<SdfPath, T>::iterator
1383 SdfPathFindLongestPrefix(std::map<SdfPath, T> &map, SdfPath const &path)
1384 {
1386  typename std::map<SdfPath, T>::iterator,
1387  std::map<SdfPath, T> &>(map, path, /*strictPrefix=*/false,
1388  TfGet<0>());
1389 }
1390 
1391 /// Return an iterator pointing to the element of \a set whose key is the
1392 /// longest prefix of the given path (excluding the path itself). If there is
1393 /// no such element, return \a set.end().
1394 SDF_API
1395 typename std::set<SdfPath>::const_iterator
1396 SdfPathFindLongestStrictPrefix(std::set<SdfPath> const &set,
1397  SdfPath const &path);
1398 
1399 /// Return an iterator pointing to the element of \a map whose key is the
1400 /// longest prefix of the given path (excluding the path itself). If there is
1401 /// no such element, return \a map.end().
1402 template <class T>
1403 typename std::map<SdfPath, T>::const_iterator
1405  std::map<SdfPath, T> const &map, SdfPath const &path)
1406 {
1408  typename std::map<SdfPath, T>::const_iterator,
1409  std::map<SdfPath, T> const &>(map, path, /*strictPrefix=*/true,
1410  TfGet<0>());
1411 }
1412 template <class T>
1413 typename std::map<SdfPath, T>::iterator
1415  std::map<SdfPath, T> &map, SdfPath const &path)
1416 {
1418  typename std::map<SdfPath, T>::iterator,
1419  std::map<SdfPath, T> &>(map, path, /*strictPrefix=*/true,
1420  TfGet<0>());
1421 }
1422 
1423 // A helper function for debugger pretty-printers, etc. This function is *not*
1424 // thread-safe. It writes to a static buffer and returns a pointer to it.
1425 // Subsequent calls to this function overwrite the memory written in prior
1426 // calls. If the given path's string representation exceeds the static buffer
1427 // size, return a pointer to a message indicating so.
1428 SDF_API
1429 char const *
1430 Sdf_PathGetDebuggerPathText(SdfPath const &);
1431 
1433 
1434 // Sdf_PathNode is not public API, but we need to include it here
1435 // so we can inline the ref-counting operations, which must manipulate
1436 // its internal _refCount member.
1437 #include "pxr/usd/sdf/pathNode.h"
1438 
1440 
1441 static_assert(Sdf_SizeofPrimPathNode == sizeof(Sdf_PrimPathNode), "");
1442 static_assert(Sdf_SizeofPropPathNode == sizeof(Sdf_PrimPropertyPathNode), "");
1443 
1445 
1446 #endif // PXR_USD_SDF_PATH_H
SDF_API const char * GetText() const
GLint first
Definition: glcorearb.h:405
SDF_API bool IsPrimOrPrimVariantSelectionPath() const
SDF_API SdfPath AppendTarget(const SdfPath &targetPath) const
SDF_API bool IsMapperPath() const
Returns whether the path identifies a connection mapper.
friend void swap(SdfPath &lhs, SdfPath &rhs)
Definition: path.h:1062
SDF_API iterator & operator++()
SDF_API const std::string & GetName() const
static SDF_API const SdfPath & AbsoluteRootPath()
friend class Sdfext_PathAccess
Definition: path.h:1034
static constexpr bool IsCounted
Definition: path.h:86
Sdf_PathNodeHandleImpl(Sdf_PathNodeHandleImpl const &rhs) noexcept
Definition: path.h:106
SDF_API std::string GetElementString() const
SDF_API bool IsExpressionPath() const
Returns whether the path identifies a connection expression.
SDF_API SdfPath AppendExpression() const
iterator(const SdfPath &path)
Definition: path.h:1108
Sdf_PathNodeHandleImpl(Handle h, bool add_ref=true)
Definition: path.h:99
SDF_API SdfPath AppendMapper(const SdfPath &targetPath) const
STATIC_INLINE size_t Hash(const char *s, size_t len)
Definition: farmhash.h:2038
SDF_API char const * Sdf_PathGetDebuggerPathText(SdfPath const &)
bool operator==(const SdfPath &rhs) const
Equality operator.
Definition: path.h:909
Sdf_PathPropPartPool::Handle Sdf_PathPropHandle
Definition: path.h:77
SDF_API SdfPath ReplaceTargetPath(const SdfPath &newTargetPath) const
void reset() noexcept
Definition: path.h:145
std::pair< ForwardIterator, ForwardIterator > SdfPathFindPrefixedRange(ForwardIterator begin, ForwardIterator end, SdfPath const &prefix, GetPathFn const &getPath=GetPathFn())
Definition: path.h:1167
static SDF_API bool IsValidPathString(const std::string &pathString, std::string *errMsg=0)
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
RandomAccessIterator Sdf_PathFindLongestPrefixImpl(RandomAccessIterator begin, RandomAccessIterator end, SdfPath const &path, bool strictPrefix, GetPathFn const &getPath)
Definition: path.h:1198
SDF_API bool IsAbsoluteRootPath() const
Return true if this path is the AbsoluteRootPath().
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
SDF_API bool IsMapperArgPath() const
Returns whether the path identifies a connection mapper arg.
SDF_API const SdfPath & GetTargetPath() const
SDF_API bool IsPrimPropertyPath() const
SDF_API SdfPath GetAbsoluteRootOrPrimPath() const
SdfPathAncestorsRange(const SdfPath &path)
Definition: path.h:1096
SDF_API TfToken GetAsToken() const
Sdf_PathNodeHandleImpl & operator=(Sdf_PathNodeHandleImpl &&rhs) noexcept
Definition: path.h:134
bool operator==(const iterator &o) const
Definition: path.h:1119
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
static SDF_API void RemoveDescendentPaths(SdfPathVector *paths)
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:424
bool operator==(Sdf_PathNodeHandleImpl const &rhs) const noexcept
Definition: path.h:172
**But if you need a result
Definition: thread.h:613
Sdf_PathNodeHandleImpl(Sdf_PathNode const *p, bool add_ref=true)
Definition: path.h:91
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
SdfPath const & operator()(SdfPath const &arg) const
Definition: path.h:1154
size_t GetHash() const
Equality operator.
Definition: path.h:969
SDF_API std::pair< std::string, std::string > GetVariantSelection() const
SDF_API SdfPath StripAllVariantSelections() const
bool operator!=(const iterator &o) const
Definition: path.h:1121
SDF_API SdfPath AppendRelationalAttribute(TfToken const &attrName) const
Definition: hash.h:504
static SDF_API std::vector< std::string > TokenizeIdentifier(const std::string &name)
static SDF_API const SdfPath & EmptyPath()
The empty path value, equivalent to SdfPath().
const SdfPath & operator*() const
Definition: path.h:1115
Definition: token.h:87
bool operator<(const SdfPath &rhs) const
Definition: path.h:922
void swap(Sdf_PathNodeHandleImpl &rhs) noexcept
Definition: path.h:168
friend void TfHashAppend(HashState &h, SdfPath const &path)
Equality operator.
Definition: path.h:952
SDF_API void GetAllTargetPathsRecursively(SdfPathVector *result) const
bool ContainsPropertyElements() const
Definition: path.h:397
SDF_API bool IsPrimVariantSelectionPath() const
bool operator!=(Sdf_PathNodeHandleImpl const &rhs) const noexcept
Definition: path.h:175
void intrusive_ptr_add_ref(Sdf_PathNode const *)
SDF_API SdfPath AppendChild(TfToken const &childName) const
static SDF_API bool IsValidNamespacedIdentifier(const std::string &name)
Sdf_PathNode const & operator*() const
Definition: path.h:155
bool operator>=(const SdfPath &rhs) const
Definition: path.h:947
GLuint GLuint end
Definition: glcorearb.h:475
SDF_API SdfPath AppendVariantSelection(const std::string &variantSet, const std::string &variant) const
SDF_API SdfPath AppendMapperArg(TfToken const &argName) const
SDF_API bool IsAbsolutePath() const
Returns whether the path is absolute.
static SDF_API std::string JoinIdentifier(const std::vector< std::string > &names)
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
SDF_API bool ContainsTargetPath() const
static SDF_API bool IsValidIdentifier(const std::string &name)
SdfPath() noexcept=default
SDF_API size_t GetPathElementCount() const
Returns the number of path elements in this path.
GLuint const GLchar * name
Definition: glcorearb.h:786
Definition: stl.h:378
Definition: path.h:291
SDF_API TfToken GetElementToken() const
Like GetElementString() but return the value as a TfToken.
SDF_API const std::string & GetString() const
SDF_API bool IsPrimPath() const
Returns whether the path identifies a prim.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
size_t operator()(const SdfPath &path) const
Definition: path.h:964
Sdf_PathPrimPartPool::Handle Sdf_PathPrimHandle
Definition: path.h:76
Sdf_PathNodeHandleImpl & operator=(Sdf_PathNode const *rhs) noexcept
Definition: path.h:140
std::vector< class SdfPath > SdfPathVector
A vector of SdfPaths.
Definition: path.h:212
constexpr Sdf_PathNodeHandleImpl() noexcept
Definition: path.h:88
SDF_API const TfToken & GetNameToken() const
SDF_API bool HasPrefix(const SdfPath &prefix) const
SDF_API bool IsRelationalAttributePath() const
std::set< class SdfPath > SdfPathSet
A set of SdfPaths.
Definition: path.h:210
SDF_API SdfPath AppendProperty(TfToken const &propName) const
SDF_API bool ContainsPrimVariantSelection() const
hboost::intrusive_ptr< const Sdf_PathNode > Sdf_PathNodeConstRefPtr
Definition: path.h:50
std::forward_iterator_tag iterator_category
Definition: path.h:1102
#define SDF_API
Definition: api.h:40
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
bool operator<(Sdf_PathNodeHandleImpl const &rhs) const noexcept
Definition: path.h:178
SDF_API std::ostream & operator<<(std::ostream &out, const SdfPath &path)
Writes the string representation of path to out.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
const SdfPath * operator->() const
Definition: path.h:1117
SDF_API SdfPathAncestorsRange GetAncestorsRange() const
SDF_API SdfPath GetCommonPrefix(const SdfPath &path) const
SDF_API TfToken const & GetToken() const
SDF_API bool IsTargetPath() const
iterator end() const
Definition: path.h:1135
Sdf_PathNodeHandleImpl & operator=(Sdf_PathNodeHandleImpl const &rhs)
Definition: path.h:120
SDF_API std::pair< SdfPath, SdfPath > RemoveCommonSuffix(const SdfPath &otherPath, bool stopAtRootPrim=false) const
size_t hash_value(SdfPath const &path)
Definition: path.h:1143
SDF_API bool IsRootPrimPath() const
SDF_API SdfPath AppendPath(const SdfPath &newSuffix) const
SDF_API std::string GetAsString() const
const SdfPath & GetPath() const
Definition: path.h:1099
iterator begin() const
Definition: path.h:1133
void intrusive_ptr_release(Sdf_PathNode const *)
SDF_API SdfPath MakeAbsolutePath(const SdfPath &anchor) const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
SDF_API bool IsNamespacedPropertyPath() const
SDF_API SdfPath AppendElementToken(const TfToken &elementTok) const
Like AppendElementString() but take the element as a TfToken.
SDF_API SdfPath GetParentPath() const
static SDF_API SdfPathVector GetConciseRelativePaths(const SdfPathVector &paths)
SDF_API SdfPath GetPrimOrPrimVariantSelectionPath() const
SDF_API bool IsPropertyPath() const
static SDF_API std::pair< std::string, bool > StripPrefixNamespace(const std::string &name, const std::string &matchNamespace)
Definition: core.h:1131
SDF_API friend char const * Sdf_PathGetDebuggerPathText(SdfPath const &)
SDF_API friend difference_type distance(const iterator &first, const iterator &last)
RandomAccessIterator SdfPathFindLongestPrefix(RandomAccessIterator begin, RandomAccessIterator end, SdfPath const &path, GetPathFn const &getPath=GetPathFn())
Definition: path.h:1284
static SDF_API void RemoveAncestorPaths(SdfPathVector *paths)
#define const
Definition: zconf.h:214
SDF_API bool IsAbsoluteRootOrPrimPath() const
Returns whether the path identifies a prim or the absolute root.
RandomAccessIterator SdfPathFindLongestStrictPrefix(RandomAccessIterator begin, RandomAccessIterator end, SdfPath const &path, GetPathFn const &getPath=GetPathFn())
Definition: path.h:1310
Sdf_PathNode const * operator->() const
Definition: path.h:160
bool operator!=(const SdfPath &rhs) const
Inequality operator.
Definition: path.h:914
Sdf_PathNodeHandleImpl(Sdf_PathNodeHandleImpl &&rhs) noexcept
Definition: path.h:128
SDF_API SdfPathVector GetPrefixes() const
static SDF_API std::string StripNamespace(const std::string &name)
friend struct Handle
Definition: pool.h:94
SDF_API SdfPath ReplaceName(TfToken const &newName) const
bool operator<=(const SdfPath &rhs) const
Definition: path.h:941
type
Definition: core.h:1059
static SDF_API const SdfPath & ReflexiveRelativePath()
The relative path representing "self".
bool operator>(const SdfPath &rhs) const
Definition: path.h:935
SDF_API SdfPath AppendElementString(const std::string &element) const
bool operator()(const SdfPath &a, const SdfPath &b) const
Definition: path.h:976
VT_TYPE_IS_CHEAP_TO_COPY(class SdfPath)
Definition: pool.h:79
std::ptrdiff_t difference_type
Definition: path.h:1104
SDF_API SdfPath MakeRelativePath(const SdfPath &anchor) const
SDF_API SdfPath ReplacePrefix(const SdfPath &oldPrefix, const SdfPath &newPrefix, bool fixTargetPaths=true) const
SDF_API SdfPath GetPrimPath() const
void * Handle
Definition: plugin.h:27
static SDF_API TfTokenVector TokenizeIdentifierAsTokens(const std::string &name)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:483