Loading...
Searching...
No Matches
variableExpression.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_VARIABLE_EXPRESSION
8#define PXR_USD_SDF_VARIABLE_EXPRESSION
9
11
12#include "pxr/pxr.h"
13#include "pxr/usd/sdf/api.h"
14
15#include "pxr/base/vt/array.h"
17#include "pxr/base/vt/value.h"
18
19#include <memory>
20#include <string>
21#include <unordered_set>
22#include <vector>
23
24PXR_NAMESPACE_OPEN_SCOPE
25
26namespace Sdf_VariableExpressionImpl {
27 class Node;
28}
29
64{
65public:
69 SDF_API
70 explicit SdfVariableExpression(const std::string& expr);
71
72 SDF_API
73 explicit SdfVariableExpression(std::string&& expr);
74
76 SDF_API
78
79 SDF_API
81
88 SDF_API
89 static bool IsExpression(const std::string& s);
90
98 SDF_API
99 static bool IsValidVariableType(const VtValue& value);
100
108 SDF_API
109 explicit operator bool() const;
110
112 SDF_API
113 const std::string& GetString() const;
114
120 SDF_API
121 const std::vector<std::string>& GetErrors() const;
122
125
128 class EmptyList { };
129
131 class Result
132 {
133 public:
141 VtValue value;
142
144 std::vector<std::string> errors;
145
154 std::unordered_set<std::string> usedVariables;
155 };
156
178 SDF_API
179 Result Evaluate(const VtDictionary& variables) const;
180
199 template <class ResultType>
200 Result EvaluateTyped(const VtDictionary& variables) const
201 {
202 Result r = Evaluate(variables);
203
205 r.value = VtValue(ResultType());
206 }
207 else if (!r.value.IsEmpty() && !r.value.IsHolding<ResultType>()) {
208 r.errors.push_back(
209 _FormatUnexpectedTypeError(r.value, VtValue(ResultType())));
210 r.value = VtValue();
211 }
212 return r;
213 }
214
216
242
247 {
248 public:
249 SDF_API operator SdfVariableExpression() const;
250
251 private:
252 friend class SdfVariableExpression;
253 Builder(std::string&& expr) : _expr(std::move(expr)) { }
254 std::string _expr;
255 };
256
261 {
262 public:
265 template <class Argument>
266 FunctionBuilder& AddArgument(Argument&& arg);
267
268 SDF_API operator SdfVariableExpression() const;
269 SDF_API operator Builder() const &;
270 SDF_API operator Builder() &&;
271
272 private:
273 friend class SdfVariableExpression;
274 FunctionBuilder(const std::string& name) : _expr(name + '(') { }
275 std::string _expr;
276 };
277
282 {
283 public:
286 template <class Element>
287 ListBuilder& AddElement(Element&& elem);
288
291 template <class T>
292 ListBuilder& AddLiteralValues(const std::vector<T>& values);
293
294 SDF_API operator SdfVariableExpression() const;
295 SDF_API operator Builder() const &;
296 SDF_API operator Builder() &&;
297
298 private:
299 friend class SdfVariableExpression;
300 ListBuilder() : _expr("[") { }
301
302 std::string _expr;
303 };
304
310 template <class... Arguments>
311 static FunctionBuilder
312 MakeFunction(const std::string& fnName, Arguments&&... fnArgs)
313 {
314 FunctionBuilder b(fnName);
315 (b.AddArgument(std::forward<Arguments>(fnArgs)), ...);
316 return b;
317 }
318
324 template <class... Elements>
325 static ListBuilder
326 MakeList(Elements&&... elems)
327 {
328 ListBuilder b;
329 (b.AddElement(std::forward<Elements>(elems)), ...);
330 return b;
331 }
332
338 template <class T>
339 static ListBuilder
340 MakeListOfLiterals(const std::vector<T>& values)
341 {
342 return ListBuilder().AddLiteralValues(values);
343 }
344
346 SDF_API static Builder MakeLiteral(int64_t value);
347 SDF_API static Builder MakeLiteral(bool value);
348 SDF_API static Builder MakeLiteral(const std::string& value);
349 SDF_API static Builder MakeLiteral(const char* value);
350
352 SDF_API static Builder MakeNone();
353
356 SDF_API static Builder MakeVariable(const std::string& name);
357
360 SDF_API static Builder MakeVariable(const std::string& name,
361 const Builder& fallbackValue);
362
366 SDF_API static Builder MakeVariable(const std::string& name,
367 const SdfVariableExpression& fallbackValue);
369
370private:
371 SDF_API
372 static std::string
373 _FormatUnexpectedTypeError(const VtValue& got, const VtValue& expected);
374
375 SDF_API
376 static void
377 _AppendExpression(
378 std::string* expr, const SdfVariableExpression& arg, bool first);
379
380 SDF_API
381 static void
382 _AppendBuilder(std::string* expr, const Builder& b, bool first);
383
384 template <class Argument>
385 static void
386 _Append(std::string* expr, Argument&& arg, bool first)
387 {
388 // Avoid implicitly converting arg to an SdfVariableExpression
389 // since that would incur unnecessary parsing costs.
390 if constexpr (std::is_same_v<
391 std::decay_t<Argument>, SdfVariableExpression>) {
392 _AppendExpression(expr, std::forward<Argument>(arg), first);
393 }
394 else {
395 _AppendBuilder(expr, std::forward<Argument>(arg), first);
396 }
397 }
398
399 std::vector<std::string> _errors;
400 std::shared_ptr<Sdf_VariableExpressionImpl::Node> _expression;
401 std::string _expressionStr;
402};
403
404inline bool
405operator==(
408{
409 return true;
410}
411
412inline bool
413operator!=(
416{
417 return false;
418}
419
420template <class Argument>
423{
424 SdfVariableExpression::_Append(
425 &_expr, std::forward<Argument>(arg),
426 /* first = */ *_expr.rbegin() == '(');
427 return *this;
428}
429
430template <class Element>
433{
434 SdfVariableExpression::_Append(
435 &_expr, std::forward<Element>(arg),
436 /* first = */ *_expr.rbegin() == '[');
437 return *this;
438}
439
440template <class T>
443 const std::vector<T>& values)
444{
445 for (const T& v : values) {
447 }
448 return *this;
449}
450
451PXR_NAMESPACE_CLOSE_SCOPE
452
453#endif
Helper class for storing intermediate results when building a variable expression.
Helper class for storing intermediate results when building a function variable expression.
FunctionBuilder & AddArgument(Argument &&arg)
Add an expression as an argument to the function call.
Helper class for storing intermediate results when building a list variable expression.
ListBuilder & AddElement(Element &&elem)
Add an expression as an element to the list.
ListBuilder & AddLiteralValues(const std::vector< T > &values)
Add values in values as literal expressions to the list.
Class responsible for parsing and evaluating variable expressions.
SDF_API const std::string & GetString() const
Returns the expression string used to construct this object.
static SDF_API bool IsExpression(const std::string &s)
Returns true if s is a variable expression, false otherwise.
SDF_API SdfVariableExpression()
Construct an object representing an invalid expression.
static ListBuilder MakeListOfLiterals(const std::vector< T > &values)
Create a list expression with the values in values as literal elements.
static FunctionBuilder MakeFunction(const std::string &fnName, Arguments &&... fnArgs)
Create a function expression that calls the function named fnName with fnArgs as arguments,...
static SDF_API Builder MakeVariable(const std::string &name, const Builder &fallbackValue)
Create a variable reference expression for the variable named name and fallbackValue,...
static SDF_API bool IsValidVariableType(const VtValue &value)
Returns true if value holds a type that is supported by variable expressions, false otherwise.
SDF_API Result Evaluate(const VtDictionary &variables) const
Evaluates this expression using the variables in variables and returns a Result object with the final...
SDF_API const std::vector< std::string > & GetErrors() const
Returns a list of errors encountered when parsing this expression.
static SDF_API Builder MakeVariable(const std::string &name)
Create a variable reference expression for the variable named name, i.e.
static SDF_API Builder MakeNone()
Create a "None" literal expression.
static SDF_API Builder MakeVariable(const std::string &name, const SdfVariableExpression &fallbackValue)
Create a variable reference expression whose fallback is the expression fallbackValue.
static ListBuilder MakeList(Elements &&... elems)
Create a list expression with listElems as elements, i.e.
Result EvaluateTyped(const VtDictionary &variables) const
Evaluates this expression using the variables in variables and returns a Result object with the final...
static SDF_API Builder MakeLiteral(int64_t value)
Create a literal expression for value.
SDF_API SdfVariableExpression(const std::string &expr)
Construct using the expression expr.
A result value representing an empty list.
A map with string keys and VtValue values.
Definition dictionary.h:52
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition value.h:90
bool IsEmpty() const
Returns true iff this value is empty.
Definition value.h:1286
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
Definition value.h:1061
STL namespace.
A trait to detect instantiations of VtArray, specialized in array.h.
Definition traits.h:22