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