HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pathPattern.h
Go to the documentation of this file.
1 //
2 // Copyright 2023 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_SDF_PATH_PATTERN_H
8 #define PXR_USD_SDF_PATH_PATTERN_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/sdf/api.h"
12 #include "pxr/usd/sdf/path.h"
14 #include "pxr/base/tf/hash.h"
15 
16 #include <iosfwd>
17 #include <string>
18 #include <tuple>
19 #include <utility>
20 #include <vector>
21 
23 
24 /// \class SdfPathPattern
25 ///
26 /// Objects of this class represent SdfPath matching patterns, consisting of
27 /// an SdfPath prefix followed by a sequence of components, which may
28 /// contain wildcards and optional embedded predicate expressions (see
29 /// SdfPredicateExpression).
31 {
32 public:
33  /// Construct the empty pattern whose bool-conversion operator returns
34  /// false.
35  SDF_API
37 
38  /// Construct a SdfPathPattern with the \p prefix path.
39  SDF_API
40  explicit SdfPathPattern(SdfPath const &prefix);
41 
42  /// Construct a SdfPathPattern with the \p prefix path.
43  SDF_API
44  explicit SdfPathPattern(SdfPath &&prefix);
45 
46  /// Return the pattern "//" which matches all paths.
47  SDF_API
48  static SdfPathPattern const &Everything();
49 
50  /// Return the pattern ".//" which matches all paths descendant to an anchor
51  /// path.
52  SDF_API
53  static SdfPathPattern const &EveryDescendant();
54 
55  /// Return a default constructed SdfPathPattern that matches nothing.
56  static SdfPathPattern Nothing() {
57  return {};
58  }
59 
60  /// A component represents a pattern matching component past the initial
61  /// SdfPath prefix. A component's text can contain wildcard characters, and
62  /// if the component references a predicate expression, its predicateIndex
63  /// indicates which one in the owning SdfPathPattern's list of expressions.
64  /// A component that returns true for IsStretch() represents an "arbitrary
65  /// levels of hierarchy" element (the "//") in a path pattern.
66  struct Component {
67  bool IsStretch() const {
68  return predicateIndex == -1 && text.empty();
69  }
70 
71  std::string text;
72  int predicateIndex = -1;
73  bool isLiteral = false;
74 
75  friend bool operator==(Component const &l, Component const &r) {
76  return std::tie(l.text, l.predicateIndex, l.isLiteral) ==
77  std::tie(r.text, r.predicateIndex, r.isLiteral);
78  }
79 
80  friend bool operator!=(Component const &l, Component const &r) {
81  return !(l == r);
82  }
83 
84  template <class HashState>
85  friend void TfHashAppend(HashState &h, Component const &c) {
86  h.Append(c.text, c.predicateIndex, c.isLiteral);
87  }
88 
89  friend void swap(Component &l, Component &r) {
90  auto lt = std::tie(l.text, l.predicateIndex, l.isLiteral);
91  auto rt = std::tie(r.text, r.predicateIndex, r.isLiteral);
92  swap(lt, rt);
93  }
94  };
95 
96  /// Return true if it is valid to append the child element \p text to this
97  /// pattern. If not, and \p reason is not nullptr, set it to an explanatory
98  /// reason why not.
99  bool CanAppendChild(std::string const &text,
100  std::string *reason = nullptr) const {
101  return CanAppendChild(text, {}, reason);
102  }
103 
104  /// Return true if it is valid to append the child element \p text and \p
105  /// predExpr to this pattern. If not, and \p reason is not nullptr, set it
106  /// to an explanatory reason why not.
107  SDF_API
108  bool CanAppendChild(std::string const &text,
109  SdfPredicateExpression const &predExpr,
110  std::string *reason = nullptr) const;
111 
112  /// Append a prim child component to this pattern, with optional
113  /// predicate expression \p predExpr. If this pattern does not yet
114  /// contain any wildcards or components with predicate expressions, and
115  /// the input text does not contain wildcards, and \p predExpr is empty,
116  /// then append a child component to this pattern's prefix path (see
117  /// GetPrefix()). Otherwise append this component to the sequence of
118  /// components. Return *this.
119  SDF_API
120  SdfPathPattern &AppendChild(std::string const &text,
121  SdfPredicateExpression &&predExpr);
122  /// \overload
123  SDF_API
124  SdfPathPattern &AppendChild(std::string const &text,
125  SdfPredicateExpression const &predExpr);
126  /// \overload
127  SDF_API
128  SdfPathPattern &AppendChild(std::string const &text);
129 
130  /// Return true if it is valid to append the property element \p text to
131  /// this pattern. If not, and \p reason is not nullptr, set it to an
132  /// explanatory reason why not.
133  bool CanAppendProperty(std::string const &text,
134  std::string *reason = nullptr) const {
135  return CanAppendProperty(text, {}, reason);
136  }
137 
138  /// Return true if it is valid to append the property element \p text and \p
139  /// predExpr to this pattern. If not, and \p reason is not nullptr, set it
140  /// to an explanatory reason why not.
141  SDF_API
142  bool CanAppendProperty(std::string const &text,
143  SdfPredicateExpression const &predExpr,
144  std::string *reason = nullptr) const;
145 
146  /// Append a prim property component to this pattern, with optional
147  /// predicate expression \p predExpr. If this pattern does not yet
148  /// contain any wildcards or components with predicate expressions, and
149  /// the input text does not contain wildcards, and \p predExpr is empty,
150  /// then append a property component to this pattern's prefix path (see
151  /// GetPrefix()). Otherwise append this component to the sequence of
152  /// components. Return *this.
153  SDF_API
154  SdfPathPattern &AppendProperty(std::string const &text,
155  SdfPredicateExpression &&predExpr);
156  /// \overload
157  SDF_API
158  SdfPathPattern &AppendProperty(std::string const &text,
159  SdfPredicateExpression const &predExpr);
160  /// \overload
161  SDF_API
162  SdfPathPattern &AppendProperty(std::string const &text);
163 
164  /// Return this pattern's non-speculative prefix (leading path
165  /// components with no wildcards and no predicates).
166  SdfPath const &GetPrefix() const & {
167  return _prefix;
168  }
169 
170  /// \overload
172  return std::move(_prefix);
173  }
174 
175  /// Set this pattern's non-speculative prefix (leading path
176  /// components with no wildcards and no predicates). Return *this.
177  SDF_API
178  SdfPathPattern &SetPrefix(SdfPath &&p);
179 
180  /// \overload
181  SdfPathPattern &SetPrefix(SdfPath const &p) {
182  return SetPrefix(SdfPath(p));
183  }
184 
185  /// Return true if this pattern's prefix is the absolute root path and and
186  /// its first component is a stretch component -- that is, the pattern
187  /// starts with `//`, false otherwise.
188  SDF_API
189  bool HasLeadingStretch() const;
190 
191  /// Return true if this pattern ends with a stretch component: `//`, false
192  /// otherwise.
193  SDF_API
194  bool HasTrailingStretch() const;
195 
196  /// Append a stretch component (i.e. `//`) to this pattern if it's possible
197  /// to do so. Otherwise do nothing. It is not possible to append a stretch
198  /// component to a pattern that already ends in a stretch component, or a
199  /// pattern that identifies a property. Return *this.
200  SDF_API
201  SdfPathPattern &AppendStretchIfPossible();
202 
203  /// Remove trailing stretch from this pattern if it has trailing stretch.
204  /// Otherwise do nothing. Return *this. See HasTrailingStretch().
205  SDF_API
206  SdfPathPattern &RemoveTrailingStretch();
207 
208  /// If this pattern has components, remove the final component. Otherwise
209  /// do nothing. Return *this. To inspect and modify the prefix path, use
210  /// GetPrefix(), SetPrefix().
211  SDF_API
212  SdfPathPattern &RemoveTrailingComponent();
213 
214  /// Return the string representation of this pattern.
215  SDF_API
216  std::string GetText() const;
217 
218  /// Return this pattern's components that follow its non-speculative prefix
219  /// path.
220  std::vector<Component> const &GetComponents() const & {
221  return _components;
222  }
223 
224  /// \overload
225  std::vector<Component> GetComponents() && {
226  return std::move(_components);
227  }
228 
229  /// Return the predicate expressions used by this pattern. These are
230  /// indexed by a Component's predicateIndex member, if it is not -1.
231  std::vector<SdfPredicateExpression> const &
232  GetPredicateExprs() const & {
233  return _predExprs;
234  }
235 
236  /// \overload
237  std::vector<SdfPredicateExpression>
239  return std::move(_predExprs);
240  }
241 
242  /// Return true if this pattern identifies properties exclusively, false
243  /// otherwise.
244  bool IsProperty() const {
245  return _isProperty;
246  }
247 
248  /// Return true if this pattern is not empty, false if it is.
249  explicit operator bool() const {
250  return !_prefix.IsEmpty();
251  }
252 
253 private:
254  SdfPathPattern(SdfPath prefix,
255  std::vector<Component> &&components,
256  std::vector<SdfPredicateExpression> &&predExprs,
257  bool isProperty);
258 
259  template <class HashState>
260  friend void TfHashAppend(HashState &h, SdfPathPattern const &pat) {
261  h.Append(pat._prefix, pat._components,
262  pat._predExprs, pat._isProperty);
263  }
264 
265  friend bool
266  operator==(SdfPathPattern const &l, SdfPathPattern const &r) {
267  return std::tie(l._prefix, l._components,
268  l._predExprs, l._isProperty) ==
269  std::tie(r._prefix, r._components,
270  r._predExprs, r._isProperty);
271  }
272 
273  friend bool
274  operator!=(SdfPathPattern const &l, SdfPathPattern const &r) {
275  return !(l == r);
276  }
277 
278  friend void swap(SdfPathPattern &l, SdfPathPattern &r) {
279  auto lt = std::tie(
280  l._prefix, l._components, l._predExprs, l._isProperty);
281  auto rt = std::tie(
282  r._prefix, r._components, r._predExprs, r._isProperty);
283  swap(lt, rt);
284  }
285 
286  SdfPath _prefix;
287  std::vector<Component> _components;
288  std::vector<SdfPredicateExpression> _predExprs;
289  bool _isProperty;
290 };
291 
292 
294 
295 #endif // PXR_USD_SDF_PATH_PATTERN_H
friend bool operator!=(SdfPathPattern const &l, SdfPathPattern const &r)
Definition: pathPattern.h:274
friend bool operator==(SdfPathPattern const &l, SdfPathPattern const &r)
Definition: pathPattern.h:266
SDF_API SdfPathPattern & AppendChild(std::string const &text, SdfPredicateExpression &&predExpr)
friend void swap(Component &l, Component &r)
Definition: pathPattern.h:89
SdfPath const & GetPrefix() const &
Definition: pathPattern.h:166
bool IsEmpty() const noexcept
Returns true if this is the empty path (SdfPath::EmptyPath()).
Definition: path.h:398
bool IsProperty() const
Definition: pathPattern.h:244
static SDF_API SdfPathPattern const & Everything()
Return the pattern "//" which matches all paths.
SDF_API SdfPathPattern & SetPrefix(SdfPath &&p)
OutGridT const XformOp bool bool
friend void TfHashAppend(HashState &h, Component const &c)
Definition: pathPattern.h:85
SdfPath GetPrefix()&&
Definition: pathPattern.h:171
friend bool operator==(Component const &l, Component const &r)
Definition: pathPattern.h:75
SDF_API bool HasLeadingStretch() const
SDF_API SdfPathPattern & RemoveTrailingStretch()
bool CanAppendChild(std::string const &text, std::string *reason=nullptr) const
Definition: pathPattern.h:99
std::vector< Component > GetComponents()&&
Definition: pathPattern.h:225
Definition: path.h:273
static SdfPathPattern Nothing()
Return a default constructed SdfPathPattern that matches nothing.
Definition: pathPattern.h:56
std::vector< SdfPredicateExpression > const & GetPredicateExprs() const &
Definition: pathPattern.h:232
std::vector< Component > const & GetComponents() const &
Definition: pathPattern.h:220
#define SDF_API
Definition: api.h:23
SdfPathPattern & SetPrefix(SdfPath const &p)
Definition: pathPattern.h:181
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
static SDF_API SdfPathPattern const & EveryDescendant()
friend void TfHashAppend(HashState &h, SdfPathPattern const &pat)
Definition: pathPattern.h:260
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
SDF_API std::string GetText() const
Return the string representation of this pattern.
friend bool operator!=(Component const &l, Component const &r)
Definition: pathPattern.h:80
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
bool IsStretch() const
Definition: pathPattern.h:67
SDF_API SdfPathPattern()
std::vector< SdfPredicateExpression > GetPredicateExprs()&&
Definition: pathPattern.h:238
friend void swap(SdfPathPattern &l, SdfPathPattern &r)
Definition: pathPattern.h:278
SDF_API SdfPathPattern & AppendStretchIfPossible()
SDF_API SdfPathPattern & AppendProperty(std::string const &text, SdfPredicateExpression &&predExpr)
GLboolean r
Definition: glcorearb.h:1222
SDF_API bool HasTrailingStretch() const
bool CanAppendProperty(std::string const &text, std::string *reason=nullptr) const
Definition: pathPattern.h:133
SDF_API SdfPathPattern & RemoveTrailingComponent()