All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pathNode.h
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 SDF_PATHNODE_H
25 #define SDF_PATHNODE_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/sdf/api.h"
29 #include "pxr/base/tf/token.h"
30 #include "pxr/base/tf/mallocTag.h"
31 
32 #include <boost/noncopyable.hpp>
33 #include <boost/intrusive_ptr.hpp>
34 
35 #include <tbb/atomic.h>
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
39 // Sdf_PathNode
40 //
41 // This class is the root of the path node hierarchy. It used to use ordinary
42 // C++ polymorphism, but it no longer does. This is primarily a space
43 // optimization: the set of node types is fixed, we already have an enum 'type'
44 // field, and we typically have lots (e.g. ~1e8) of these objects. Dropping the
45 // C++ polymorphism saves us the vtable pointer, and we can pack the '_nodeType'
46 // field in a much smaller space with other flags.
47 //
48 // We currently store PathNode objects in two prefix trees. The "prim like"
49 // path nodes (the root nodes '/' and '.', prim path nodes, and prim variant
50 // selection nodes are in one prefix tree, and the "property like" nodes are in
51 // another prefix tree (prim property nodes, target nodes, expression nodes,
52 // mapper arg nodes). We do this because there are far fewer unique property
53 // nodes (generally) than there are prim nodes. We allocate these in Sdf_Pools,
54 // so that the SdfPath class can store a handle to an element in each tree in 64
55 // bits total. (Sdf_Pool is designed so that we can refer to objects in memory
56 // using 32-bit indexes instead of 64-bit pointers). An SdfPath joins together
57 // these two elements to form a whole path. For example, the path
58 // '/Foo/Bar.attr' would store a prim-part handle to the '/Foo/Bar' node, and a
59 // property-part handle to 'attr'.
60 //
61 class Sdf_PathNode {
62  Sdf_PathNode(Sdf_PathNode const &) = delete;
63  Sdf_PathNode &operator=(Sdf_PathNode const &) = delete;
64 public:
65  // Node types identify what kind of path node a given instance is.
66  // There are restrictions on what type of children each node type
67  // can have,
68  enum NodeType {
69 
70  /********************************************************/
71  /******************************* Prim portion nodes *****/
72 
73  RootNode,
74  // Allowable child node types:
75  // PrimNode
76  // PrimPropertyNode (only for relative root)
77  // PrimVariantSelectionNode (only for relative root)
78 
79  PrimNode,
80  // Allowable child node types:
81  // PrimNode
82  // PrimPropertyNode
83  // PrimVariantSelectionNode
84 
85  PrimVariantSelectionNode,
86  // Allowable child node types:
87  // PrimNode
88  // PrimPropertyNode
89  // PrimVariantSelectionNode
90  // (for variants that contain variant sets)
91 
92  /********************************************************/
93  /******************************* Property portion nodes */
94 
95  PrimPropertyNode,
96  // Allowable child node types:
97  // TargetNode
98  // MapperNode
99  // ExpressionNode
100 
101  TargetNode,
102  // Allowable child node types:
103  // RelationalAttributeNode (only if parent is PrimPropertyNode)
104 
105  MapperNode,
106  // Allowable child node types:
107  // MapperArgNode
108 
109  RelationalAttributeNode,
110  // Allowable child node types:
111  // TargetNode
112  // MapperNode
113  // ExpressionNode
114 
115  MapperArgNode,
116  // Allowable child node types:
117  // <none>
118 
119  ExpressionNode,
120  // Allowable child node types:
121  // <none>
122 
123  NumNodeTypes
124  };
125 
126  static Sdf_PathPrimNodeHandle
127  FindOrCreatePrim(Sdf_PathNode const *parent, const TfToken &name);
128 
129  static Sdf_PathPropNodeHandle
130  FindOrCreatePrimProperty(Sdf_PathNode const *parent, const TfToken &name);
131 
132  static Sdf_PathPrimNodeHandle
133  FindOrCreatePrimVariantSelection(Sdf_PathNode const *parent,
134  const TfToken &variantSet,
135  const TfToken &variant);
136 
137  static Sdf_PathPropNodeHandle
138  FindOrCreateTarget(Sdf_PathNode const *parent,
139  SdfPath const &targetPath);
140 
141  static Sdf_PathPropNodeHandle
142  FindOrCreateRelationalAttribute(Sdf_PathNode const *parent,
143  const TfToken &name);
144 
145  static Sdf_PathPropNodeHandle
146  FindOrCreateMapper(Sdf_PathNode const *parent, SdfPath const &targetPath);
147 
148  static Sdf_PathPropNodeHandle
149  FindOrCreateMapperArg(Sdf_PathNode const *parent, const TfToken &name);
150 
151  static Sdf_PathPropNodeHandle
152  FindOrCreateExpression(Sdf_PathNode const *parent);
153 
154  static Sdf_PathNode const *GetAbsoluteRootNode();
155  static Sdf_PathNode const *GetRelativeRootNode();
156 
157  NodeType GetNodeType() const { return NodeType(_nodeType); }
158 
159  static std::pair<Sdf_PathNode const *, Sdf_PathNode const *>
160  RemoveCommonSuffix(Sdf_PathNode const *a,
161  Sdf_PathNode const *b,
162  bool stopAtRootPrim);
163 
164  // This method returns a node pointer
165  Sdf_PathNode const *GetParentNode() const { return _parent.get(); }
166 
167  size_t GetElementCount() const { return size_t(_elementCount); }
168  bool IsAbsolutePath() const { return _isAbsolute; }
169  bool ContainsTargetPath() const { return _containsTargetPath; }
170  bool IsNamespaced() const {
171  return (_nodeType == PrimPropertyNode ||
172  _nodeType == RelationalAttributeNode) && _IsNamespacedImpl();
173  }
174 
175  bool ContainsPrimVariantSelection() const {
176  return _containsPrimVariantSelection;
177  }
178 
179  // For PrimNode, PrimPropertyNode, RelationalAttributeNode, and
180  // MapperArgNode this is the name (with no "dot" for
181  // properties/relational attributes/mapper args). For others, it
182  // is EmptyToken.
183  inline const TfToken &GetName() const;
184 
185  // For TargetNode and MapperNode this is the target path.
186  // For others, it is InvalidPath.
187  inline const SdfPath &GetTargetPath() const;
188 
189  typedef std::pair<TfToken, TfToken> VariantSelectionType;
190  inline const VariantSelectionType& GetVariantSelection() const;
191 
192  // Returns the path element string (".name" for properties, "[path]" for
193  // targets, etc...)
194  inline TfToken GetElement() const;
195 
196  // Append this element's text (same as GetElement()) to \p str.
197  void AppendText(std::string *str) const;
198 
199  // Return the stringified path to this node as a TfToken.
200  SDF_API static const TfToken &
201  GetPathToken(Sdf_PathNode const *primPart, Sdf_PathNode const *propPart);
202 
203  // Lexicographic ordering for Compare().
204  struct LessThan {
205  template <class T>
206  inline bool operator()(T const &a, T const &b) const {
207  return a < b;
208  }
209  };
210 
211  // This operator only works properly when the rhs has the same parent
212  // as this node.
213  template <class Less>
214  inline bool Compare(const Sdf_PathNode &rhs) const;
215 
216  // Return the current ref-count.
217  // Meant for diagnostic use.
218  unsigned int GetCurrentRefCount() const { return _refCount; }
219 
220 protected:
221  Sdf_PathNode(Sdf_PathNode const *parent, NodeType nodeType)
222  : _parent(parent)
223  , _refCount(1)
224  , _elementCount(parent ? parent->_elementCount + 1 : 1)
225  , _nodeType(nodeType)
226  , _isAbsolute(parent && parent->IsAbsolutePath())
227  , _containsPrimVariantSelection(
228  nodeType == PrimVariantSelectionNode ||
229  (parent && parent->_containsPrimVariantSelection))
230  , _containsTargetPath(nodeType == TargetNode ||
231  nodeType == MapperNode ||
232  (parent && parent->_containsTargetPath))
233  , _hasToken(false)
234  {}
235 
236  // This constructor is used only to create the two special root nodes.
237  explicit Sdf_PathNode(bool isAbsolute);
238 
239  ~Sdf_PathNode() {
240  if (_hasToken)
241  _RemovePathTokenFromTable();
242  }
243 
244  // Helper to downcast and destroy the dynamic type of this object -- this is
245  // required since this class hierarchy doesn't use normal C++ polymorphism
246  // for space reasons.
247  inline void _Destroy() const;
248 
249  // // Helper function for GetPathToken, which lazily creates its token
250  static TfToken _CreatePathToken(Sdf_PathNode const *primPart,
251  Sdf_PathNode const *propPart);
252 
253  // Helper for dtor, removes this path node's token from the token table.
254  SDF_API void _RemovePathTokenFromTable() const;
255 
256  struct _EqualElement {
257  template <class T>
258  inline bool operator()(T const &a, T const &b) const {
259  return a == b;
260  }
261  };
262 
263  friend struct Sdf_PathNodePrivateAccess;
264 
265  // Ref-counting ops manage _refCount.
266  friend void intrusive_ptr_add_ref(const Sdf_PathNode*);
267  friend void intrusive_ptr_release(const Sdf_PathNode*);
268 
269 private:
270  // Downcast helper, just sugar to static_cast this to Derived const *.
271  template <class Derived>
272  Derived const *_Downcast() const {
273  return static_cast<Derived const *>(this);
274  }
275 
276  // Helper to scan this node's name for the property namespace delimiter.
277  bool _IsNamespacedImpl() const;
278 
279  // Helper to return a const lvalue variant selection.
280  VariantSelectionType const &_GetEmptyVariantSelection() const;
281 
282  // Instance variables. PathNode's size is important to keep small. Please
283  // be mindful of that when making any changes here.
284  const Sdf_PathNodeConstRefPtr _parent;
285  mutable tbb::atomic<unsigned int> _refCount;
286 
287  const short _elementCount;
288  const unsigned char _nodeType;
289  const bool _isAbsolute:1;
290  const bool _containsPrimVariantSelection:1;
291  const bool _containsTargetPath:1;
292 
293  // This is racy -- we ensure that the token creation code carefully
294  // synchronizes so that if we read 'true' from this flag, it guarantees that
295  // there's a token for this path node in the token table. If we read
296  // 'false' it means there may or may not be, unless we're in the destructor,
297  // which must run exclusively, then reading 'false' guarantees there is no
298  // token in the table. We use this flag to do that optimization in the
299  // destructor so we can avoid looking in the table in the case where we
300  // haven't created a token.
301  mutable bool _hasToken:1;
302 };
303 
304 class Sdf_PrimPartPathNode : public Sdf_PathNode {
305 public:
306  using Sdf_PathNode::Sdf_PathNode;
307  SDF_API void operator delete (void *p);
308 };
309 
310 class Sdf_PropPartPathNode : public Sdf_PathNode {
311 public:
312  using Sdf_PathNode::Sdf_PathNode;
313  SDF_API void operator delete (void *p);
314 };
315 
316 class Sdf_RootPathNode : public Sdf_PrimPartPathNode {
317 public:
318  typedef bool ComparisonType;
319  static const NodeType nodeType = Sdf_PathNode::RootNode;
320 
321  static SDF_API Sdf_PathNode const *New(bool isAbsolute);
322 
323 private:
324  // This constructor is used only to create the two special root nodes.
325  Sdf_RootPathNode(bool isAbsolute) : Sdf_PrimPartPathNode(isAbsolute) {}
326 
327  ComparisonType _GetComparisonValue() const {
328  // Root nodes, there are only two, one absolute and one relative.
329  // (absolute < relative...)
330  return !IsAbsolutePath();
331  }
332 
333  friend class Sdf_PathNode;
334  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
335 };
336 
337 class Sdf_PrimPathNode : public Sdf_PrimPartPathNode {
338 public:
339  typedef TfToken ComparisonType;
340  static const NodeType nodeType = Sdf_PathNode::PrimNode;
341 
342 private:
343  Sdf_PrimPathNode(Sdf_PathNode const *parent,
344  const TfToken &name)
345  : Sdf_PrimPartPathNode(parent, nodeType)
346  , _name(name) {}
347 
348  SDF_API ~Sdf_PrimPathNode();
349 
350  const ComparisonType &_GetComparisonValue() const { return _name; }
351 
352  friend class Sdf_PathNode;
353  friend struct Sdf_PathNodePrivateAccess;
354  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
355 
356  // Instance variables
357  TfToken _name;
358 };
359 
360 class Sdf_PrimPropertyPathNode : public Sdf_PropPartPathNode {
361 public:
362  typedef TfToken ComparisonType;
363  static const NodeType nodeType = Sdf_PathNode::PrimPropertyNode;
364 
365 private:
366  Sdf_PrimPropertyPathNode(Sdf_PathNode const *parent,
367  const TfToken &name)
368  : Sdf_PropPartPathNode(parent, nodeType)
369  , _name(name) {}
370 
371  SDF_API ~Sdf_PrimPropertyPathNode();
372 
373  friend class Sdf_PathNode;
374  friend struct Sdf_PathNodePrivateAccess;
375  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
376 
377  const ComparisonType &_GetComparisonValue() const { return _name; }
378 
379  // Instance variables
380  TfToken _name;
381 };
382 
383 class Sdf_PrimVariantSelectionNode : public Sdf_PrimPartPathNode {
384 public:
385  typedef VariantSelectionType ComparisonType;
386  static const NodeType nodeType = Sdf_PathNode::PrimVariantSelectionNode;
387 
388  const TfToken &_GetNameImpl() const;
389  void _AppendText(std::string *str) const;
390 
391 private:
392  Sdf_PrimVariantSelectionNode(Sdf_PathNode const *parent,
393  const VariantSelectionType &variantSelection)
394  : Sdf_PrimPartPathNode(parent, nodeType)
395  , _variantSelection(new VariantSelectionType(variantSelection)) {}
396 
397  SDF_API ~Sdf_PrimVariantSelectionNode();
398 
399  const ComparisonType &_GetComparisonValue() const {
400  return *_variantSelection;
401  }
402 
403  friend class Sdf_PathNode;
404  friend struct Sdf_PathNodePrivateAccess;
405  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
406 
407  // Instance variables
408  std::unique_ptr<VariantSelectionType> _variantSelection;
409 };
410 
411 class Sdf_TargetPathNode : public Sdf_PropPartPathNode {
412 public:
413  typedef SdfPath ComparisonType;
414  static const NodeType nodeType = Sdf_PathNode::TargetNode;
415 
416  void _AppendText(std::string *str) const;
417 
418 private:
419  Sdf_TargetPathNode(Sdf_PathNode const *parent,
420  const SdfPath &targetPath)
421  : Sdf_PropPartPathNode(parent, nodeType)
422  , _targetPath(targetPath) {}
423 
424  SDF_API ~Sdf_TargetPathNode();
425 
426  const ComparisonType& _GetComparisonValue() const { return _targetPath; }
427 
428  friend class Sdf_PathNode;
429  friend struct Sdf_PathNodePrivateAccess;
430  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
431 
432  // Instance variables
433  SdfPath _targetPath;
434 };
435 
436 class Sdf_RelationalAttributePathNode : public Sdf_PropPartPathNode {
437 public:
438  typedef TfToken ComparisonType;
439  static const NodeType nodeType = Sdf_PathNode::RelationalAttributeNode;
440 
441 private:
442  Sdf_RelationalAttributePathNode(Sdf_PathNode const *parent,
443  const TfToken &name)
444  : Sdf_PropPartPathNode(parent, nodeType)
445  , _name(name) {}
446 
447  SDF_API ~Sdf_RelationalAttributePathNode();
448 
449  const ComparisonType& _GetComparisonValue() const { return _name; }
450 
451  friend class Sdf_PathNode;
452  friend struct Sdf_PathNodePrivateAccess;
453  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
454 
455  // Instance variables
456  TfToken _name;
457 };
458 
459 class Sdf_MapperPathNode : public Sdf_PropPartPathNode {
460 public:
461  typedef SdfPath ComparisonType;
462  static const NodeType nodeType = Sdf_PathNode::MapperNode;
463 
464  void _AppendText(std::string *str) const;
465 
466 private:
467  Sdf_MapperPathNode(Sdf_PathNode const *parent,
468  const SdfPath &targetPath)
469  : Sdf_PropPartPathNode(parent, nodeType)
470  , _targetPath(targetPath) {}
471 
472  SDF_API ~Sdf_MapperPathNode();
473 
474  const ComparisonType& _GetComparisonValue() const { return _targetPath; }
475 
476  friend class Sdf_PathNode;
477  friend struct Sdf_PathNodePrivateAccess;
478  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
479 
480  // Instance variables
481  SdfPath _targetPath;
482 };
483 
484 class Sdf_MapperArgPathNode : public Sdf_PropPartPathNode {
485 public:
486  typedef TfToken ComparisonType;
487  static const NodeType nodeType = Sdf_PathNode::MapperArgNode;
488 
489  void _AppendText(std::string *str) const;
490 
491 private:
492  Sdf_MapperArgPathNode(Sdf_PathNode const *parent,
493  const TfToken &name)
494  : Sdf_PropPartPathNode(parent, nodeType)
495  , _name(name) {}
496 
497  SDF_API ~Sdf_MapperArgPathNode();
498 
499  const ComparisonType& _GetComparisonValue() const { return _name; }
500 
501  friend class Sdf_PathNode;
502  friend struct Sdf_PathNodePrivateAccess;
503  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
504 
505  // Instance variables
506  TfToken _name;
507 };
508 
509 class Sdf_ExpressionPathNode : public Sdf_PropPartPathNode {
510 public:
511  typedef void *ComparisonType;
512  static const NodeType nodeType = Sdf_PathNode::ExpressionNode;
513 
514  void _AppendText(std::string *str) const;
515 
516 private:
517  Sdf_ExpressionPathNode(Sdf_PathNode const *parent)
518  : Sdf_PropPartPathNode(parent, nodeType) {}
519 
520  SDF_API ~Sdf_ExpressionPathNode();
521 
522  ComparisonType _GetComparisonValue() const { return nullptr; }
523 
524  friend class Sdf_PathNode;
525  friend struct Sdf_PathNodePrivateAccess;
526  template <int nodeType, class Comp> friend struct Sdf_PathNodeCompare;
527 
528  // Instance variables
529  // <none>
530 };
531 
532 template <int nodeType>
533 struct Sdf_PathNodeTypeToType {
534 };
535 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimNode> {
536  typedef Sdf_PrimPathNode Type;
537 };
538 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimPropertyNode> {
539  typedef Sdf_PrimPropertyPathNode Type;
540 };
541 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::RelationalAttributeNode> {
542  typedef Sdf_RelationalAttributePathNode Type;
543 };
544 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperArgNode> {
545  typedef Sdf_MapperArgPathNode Type;
546 };
547 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::TargetNode> {
548  typedef Sdf_TargetPathNode Type;
549 };
550 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::MapperNode> {
551  typedef Sdf_MapperPathNode Type;
552 };
553 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::PrimVariantSelectionNode> {
554  typedef Sdf_PrimVariantSelectionNode Type;
555 };
556 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::ExpressionNode> {
557  typedef Sdf_ExpressionPathNode Type;
558 };
559 template <> struct Sdf_PathNodeTypeToType<Sdf_PathNode::RootNode> {
560  typedef Sdf_RootPathNode Type;
561 };
562 
563 template <int nodeType, class Comp>
564 struct Sdf_PathNodeCompare {
565  inline bool operator()(const Sdf_PathNode &lhs,
566  const Sdf_PathNode &rhs) const {
567  typedef typename Sdf_PathNodeTypeToType<nodeType>::Type Type;
568  return Comp()(static_cast<const Type&>(lhs)._GetComparisonValue(),
569  static_cast<const Type&>(rhs)._GetComparisonValue());
570  }
571 };
572 
573 template <class Comp>
574 inline bool
575 Sdf_PathNode::Compare(const Sdf_PathNode &rhs) const
576 {
577  // Compare two nodes.
578  // We first compare types, then, if types match, we compare
579  // based on the type-specific content.
580  // Names are compared lexicographically.
581 
582  // Compare types. If node types are different use Comp() on them, otherwise
583  // continue to node-specific comparisons.
584 
585  NodeType nodeType = GetNodeType(), rhsNodeType = rhs.GetNodeType();
586  if (nodeType != rhsNodeType) {
587  return Comp()(nodeType, rhsNodeType);
588  }
589 
590  // Types are the same. Avoid virtual function calls for performance.
591  switch (nodeType) {
592  case Sdf_PathNode::PrimNode:
593  return Sdf_PathNodeCompare<Sdf_PathNode::PrimNode,
594  Comp>()(*this, rhs);
595  case Sdf_PathNode::PrimPropertyNode:
596  return Sdf_PathNodeCompare<Sdf_PathNode::PrimPropertyNode,
597  Comp>()(*this, rhs);
598  case Sdf_PathNode::RelationalAttributeNode:
599  return Sdf_PathNodeCompare<Sdf_PathNode::RelationalAttributeNode,
600  Comp>()(*this, rhs);
601  case Sdf_PathNode::MapperArgNode:
602  return Sdf_PathNodeCompare<Sdf_PathNode::MapperArgNode,
603  Comp>()(*this, rhs);
604  case Sdf_PathNode::TargetNode:
605  return Sdf_PathNodeCompare<Sdf_PathNode::TargetNode,
606  Comp>()(*this, rhs);
607  case Sdf_PathNode::MapperNode:
608  return Sdf_PathNodeCompare<Sdf_PathNode::MapperNode,
609  Comp>()(*this, rhs);
610  case Sdf_PathNode::PrimVariantSelectionNode:
611  return Sdf_PathNodeCompare<Sdf_PathNode::PrimVariantSelectionNode,
612  Comp>()(*this, rhs);
613  case Sdf_PathNode::ExpressionNode:
614  return Sdf_PathNodeCompare<Sdf_PathNode::ExpressionNode,
615  Comp>()(*this, rhs);
616  case Sdf_PathNode::RootNode:
617  return Sdf_PathNodeCompare<Sdf_PathNode::RootNode,
618  Comp>()(*this, rhs);
619  default:
620  TF_CODING_ERROR("Unhandled Sdf_PathNode::NodeType enumerant");
621  return false;
622  }
623 }
624 
625 inline void
626 Sdf_PathNode::_Destroy() const
627 {
628  // Note: This function deletes this object!
629  switch (_nodeType) {
630  case RootNode:
631  return delete _Downcast<Sdf_RootPathNode>();
632  case PrimNode:
633  return delete _Downcast<Sdf_PrimPathNode>();
634  case PrimPropertyNode:
635  return delete _Downcast<Sdf_PrimPropertyPathNode>();
636  case PrimVariantSelectionNode:
637  return delete _Downcast<Sdf_PrimVariantSelectionNode>();
638  case TargetNode:
639  return delete _Downcast<Sdf_TargetPathNode>();
640  case RelationalAttributeNode:
641  return delete _Downcast<Sdf_RelationalAttributePathNode>();
642  case MapperNode:
643  return delete _Downcast<Sdf_MapperPathNode>();
644  case MapperArgNode:
645  return delete _Downcast<Sdf_MapperArgPathNode>();
646  case ExpressionNode:
647  return delete _Downcast<Sdf_ExpressionPathNode>();
648  default:
649  return;
650  };
651 }
652 
653 inline const TfToken &
654 Sdf_PathNode::GetName() const
655 {
656  switch (_nodeType) {
657  default:
658  return SdfPathTokens->empty;
659  case RootNode:
660  return IsAbsolutePath() ?
661  SdfPathTokens->absoluteIndicator : SdfPathTokens->relativeRoot;
662  case PrimNode:
663  return _Downcast<Sdf_PrimPathNode>()->_name;
664  case PrimPropertyNode:
665  return _Downcast<Sdf_PrimPropertyPathNode>()->_name;
666  case PrimVariantSelectionNode:
667  return _Downcast<Sdf_PrimVariantSelectionNode>()->_GetNameImpl();
668  case RelationalAttributeNode:
669  return _Downcast<Sdf_RelationalAttributePathNode>()->_name;
670  case MapperArgNode:
671  return _Downcast<Sdf_MapperArgPathNode>()->_name;
672  case ExpressionNode:
673  return SdfPathTokens->expressionIndicator;
674  }
675 }
676 
677 inline const SdfPath &
678 Sdf_PathNode::GetTargetPath() const
679 {
680  switch (_nodeType) {
681  default:
682  return SdfPath::EmptyPath();
683  case TargetNode:
684  return _Downcast<Sdf_TargetPathNode>()->_targetPath;
685  case MapperNode:
686  return _Downcast<Sdf_MapperPathNode>()->_targetPath;
687  };
688 }
689 
690 inline const Sdf_PathNode::VariantSelectionType &
691 Sdf_PathNode::GetVariantSelection() const
692 {
693  if (ARCH_LIKELY(_nodeType == PrimVariantSelectionNode)) {
694  return *_Downcast<Sdf_PrimVariantSelectionNode>()->_variantSelection;
695  }
696  return _GetEmptyVariantSelection();
697 }
698 
699 inline TfToken
700 Sdf_PathNode::GetElement() const
701 {
702  switch (_nodeType) {
703  case RootNode:
704  return TfToken();
705  case PrimNode:
706  return _Downcast<Sdf_PrimPathNode>()->_name;
707  default:
708  std::string str;
709  AppendText(&str);
710  return TfToken(str);
711  };
712 }
713 
715 SDF_API void Sdf_DumpPathStats();
716 
717 inline void intrusive_ptr_add_ref(const PXR_NS::Sdf_PathNode* p) {
718  ++p->_refCount;
719 }
720 inline void intrusive_ptr_release(const PXR_NS::Sdf_PathNode* p) {
721  if (p->_refCount.fetch_and_decrement() == 1)
722  p->_Destroy();
723 }
724 
725 PXR_NAMESPACE_CLOSE_SCOPE
726 
727 #endif // SDF_PATHNODE_H
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:87
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:287
static SDF_API const SdfPath & EmptyPath()
The empty path value, equivalent to SdfPath().