HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
predicateLibrary.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_PREDICATE_LIBRARY_H
8 #define PXR_USD_SDF_PREDICATE_LIBRARY_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/sdf/api.h"
12 
13 #include "pxr/base/tf/diagnostic.h"
16 #include "pxr/base/vt/value.h"
17 
19 
20 #include <initializer_list>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
26 
27 /// \class SdfPredicateParamNamesAndDefaults
28 ///
29 /// Represents named function parameters, with optional default values. These
30 /// are generally constructed via an initializer_list and specified in
31 /// SdfPredicateLibrary::Define().
32 ///
33 /// Valid parameter names and defaults have non-empty names, and all parameters
34 /// following the first one with a default value must also have default values.
36 
37  /// \class Param represents a single named parameter with an optional
38  /// default value.
39  struct Param {
40  /// Construct with or implicitly convert from name.
41  Param(char const *name) : name(name) {}
42 
43  /// Construct from name and default value.
44  template <class Val>
45  Param(char const *name, Val &&defVal)
46  : name(name), val(std::forward<Val>(defVal)) {}
47 
48  std::string name;
50  };
51 
52  /// Default constructor produces empty set of names & defaults.
53  SdfPredicateParamNamesAndDefaults() : _numDefaults(0) {}
54 
55  /// Construct or implicitly convert from initializer_list<Param>.
57  std::initializer_list<Param> const &params)
58  : _params(params.begin(), params.end())
59  , _numDefaults(_CountDefaults()) {}
60 
61  /// Check that all parameters have non-empty names and that all paramters
62  /// following the first with a default value also have default values.
63  /// Issue TF_CODING_ERROR()s and return false if these conditions are
64  /// violated, otherwise return true.
65  SDF_API
66  bool CheckValidity() const;
67 
68  /// Return a reference to the parameters in a vector.
69  std::vector<Param> const &GetParams() const & {
70  return _params;
71  }
72 
73  /// Move-return the parameters in a vector.
74  std::vector<Param> GetParams() const && {
75  return std::move(_params);
76  }
77 
78  /// Return the number of params with default values.
79  size_t GetNumDefaults() const {
80  return _numDefaults;
81  }
82 
83 private:
84  SDF_API
85  size_t _CountDefaults() const;
86 
87  std::vector<Param> _params;
88  size_t _numDefaults;
89 };
90 
91 
92 /// \class SdfPredicateFunctionResult
93 ///
94 /// Represents the result of a predicate function: a pair of the boolean result
95 /// and a Constancy token indicating whether the function result is constant
96 /// over "descendant" objects, or that it might vary over "descendant" objects.
98 {
99 public:
101 
102  /// Default construction produces a 'false' result that
103  /// 'MayVaryOverDescendants'.
105  : _value(false), _constancy(MayVaryOverDescendants) {}
106 
107  /// Construct with \p value and \p MayVaryOverDescendants constancy.
110 
111  /// Construct with \p value and \p constancy.
113  : _value(value), _constancy(constancy) {}
114 
115  /// Create with \p value and 'ConstantOverDescendants'
117  return { value, ConstantOverDescendants };
118  }
119 
120  /// Create with \p value and 'MayVaryOverDescendants'
122  return { value, MayVaryOverDescendants };
123  }
124 
125  /// Return the result value.
126  bool GetValue() const {
127  return _value;
128  }
129 
130  /// Return the result constancy.
132  return _constancy;
133  }
134 
135  /// Return true if this result's constancy is ConstantOverDescendants.
136  bool IsConstant() const {
138  }
139 
140 #if !defined(doxygen)
142 #endif //!doxygen
143 
144  /// Return GetValue().
145  operator UnspecifiedBoolType() const {
146  return _value ? &SdfPredicateFunctionResult::_value : nullptr;
147  }
148 
149  /// Return a result with the opposite value but the same constancy.
151  return { !_value, _constancy };
152  }
153 
154  /// Set this result's value to \p other's value, and propagate constancy; if
155  /// both this and \p other are ConstantOverDescendants, this object's
156  /// constancy remains ConstantOverDescendants. Otherwise set this object's
157  /// constancy to MayVaryOverDescendants.
159  _value = other._value;
160  if (_constancy == ConstantOverDescendants &&
161  other._constancy == MayVaryOverDescendants) {
162  _constancy = MayVaryOverDescendants;
163  }
164  }
165 
166 private:
169  return lhs._value == rhs._value &&
170  lhs._constancy == rhs._constancy;
171  }
174  return !(lhs == rhs);
175  }
176 
177  friend bool operator==(SdfPredicateFunctionResult pfr, bool rhs) {
178  return pfr._value == rhs;
179  }
180  friend bool operator==(bool lhs, SdfPredicateFunctionResult pfr) {
181  return lhs == pfr._value;
182  }
183  friend bool operator!=(SdfPredicateFunctionResult pfr, bool rhs) {
184  return pfr._value != rhs;
185  }
186  friend bool operator!=(bool lhs, SdfPredicateFunctionResult pfr) {
187  return lhs != pfr._value;
188  }
189 
190  bool _value;
191  Constancy _constancy;
192 };
193 
194 // fwd decl
195 template <class DomainType>
197 
198 // fwd decl
199 template <class DomainType>
201 
202 // fwd decl
203 template <class DomainType>
207 
208 /// \class SdfPredicateLibrary
209 ///
210 /// Represents a library of predicate functions for use with
211 /// SdfPredicateExpression. Call SdfLinkPredicateExpression() with an
212 /// expression and a library to produce a callable SdfPredicateProgram.
213 template <class DomainType>
215 {
217  SdfLinkPredicateExpression<DomainType>(
218  SdfPredicateExpression const &expr,
219  SdfPredicateLibrary const &lib);
220 
222 
223 public:
224  /// The type of a bound function, the result of binding passed arguments.
225  using PredicateFunction =
226  std::function<SdfPredicateFunctionResult (DomainType const &)>;
227 
228  /// Default constructor produces an empty library.
229  SdfPredicateLibrary() = default;
230 
231  /// Move-construct from an \p other library.
232  SdfPredicateLibrary(SdfPredicateLibrary &&other) = default;
233 
234  /// Copy-construct from an \p other library.
236  for (auto iter = other._binders.begin(), end = other._binders.end();
237  iter != end; ++iter) {
238  auto &theseBinders = _binders[iter->first];
239  for (auto const &otherBinder: iter->second) {
240  theseBinders.push_back(otherBinder->Clone());
241  }
242  }
243  }
244 
245  /// Move-assignment from an \p other library.
247 
248  /// Copy-assignment from an \p other library.
250  if (this != &other) {
251  SdfPredicateLibrary copy(other);
252  *this = std::move(copy);
253  }
254  return *this;
255  }
256 
257  /// Register a function with name \p name in this library. The first
258  /// argument must accept a DomainType instance. The remaining arguments
259  /// must be convertible from bool, int, float, string.
260  template <class Fn>
261  SdfPredicateLibrary &Define(char const *name, Fn &&fn) {
262  return Define(name, std::forward<Fn>(fn), {});
263  }
264 
265  /// Register a function with name \p name in this library. The first
266  /// argument must accept a DomainType instance. The remaining arguments
267  /// must be convertible from bool, int, float, string. Optional parameter
268  /// names and default values may be supplied in \p namesAndDefaults.
269  template <class Fn>
271  Define(std::string const &name, Fn &&fn,
272  NamesAndDefaults const &namesAndDefaults) {
273  // Try to create a new overload binder for 'name'. The main operation a
274  // binder does is, when "linking" a predicate expression, given a
275  // specific set of arguments from the expression, check to see if those
276  // arguments can be bound to 'fn', and if so return a type-erased
277  // callable that invokes fn with those arguments.
278  if (auto obinder = _OverloadBinder<std::decay_t<Fn>>
279  ::TryCreate(std::forward<Fn>(fn), namesAndDefaults)) {
280  _binders[name].push_back(std::move(obinder));
281  }
282  return *this;
283  }
284 
285  /// Register a custom binding function for \p name in this library. The
286  /// function must take a single argument of type
287  /// std::vector<SdfPredicateExpression::FnArg>. When invoked, it must
288  /// attempt to bind the arguments passed in the vector and return a bound
289  /// PredicateFunction object. If the arguments are invalid, return an empty
290  /// PredicateFunction.
291  template <class Fn>
293  DefineBinder(std::string const &name, Fn &&fn) {
294  auto binder = _CustomBinder<
295  std::decay_t<Fn>>::Create(std::forward<Fn>(fn));
296  _binders[name].push_back(std::move(binder));
297  return *this;
298  }
299 
300 private:
301 
303  _BindCall(std::string const &name,
304  std::vector<SdfPredicateExpression::FnArg> const &args) const {
305  PredicateFunction ret;
306  auto iter = _binders.find(name);
307  if (iter == _binders.end()) {
308  TF_RUNTIME_ERROR("No registered function '%s'", name.c_str());
309  return ret;
310  }
311  // Run thru optimistically first -- if we fail to bind to any overload,
312  // then produce an error message with all the overload signatures.
313  for (auto i = iter->second.rbegin(),
314  end = iter->second.rend(); i != end; ++i) {
315  ret = (*i)->Bind(args);
316  if (ret) {
317  break;
318  }
319  }
320  return ret;
321  }
322 
323  template <class ParamType>
324  static void _CheckOneNameAndDefault(
325  bool &valid, size_t index, size_t numParams,
326  NamesAndDefaults const &namesAndDefaults) {
327 
328  // If the namesIndex-th param has a default, it must be convertible to
329  // the ArgIndex-th type.
330  std::vector<NamesAndDefaults::Param> const &
331  params = namesAndDefaults.GetParams();
332 
333  size_t nFromEnd = numParams - index - 1;
334  if (nFromEnd >= params.size()) {
335  // No more names & defaults to check.
336  return;
337  }
338 
339  size_t namesIndex = params.size() - nFromEnd - 1;
340 
341  auto const &param = params[namesIndex];
342  if (!param.val.IsEmpty() && !param.val.CanCast<ParamType>()) {
343  TF_CODING_ERROR("Predicate default parameter '%s' value of "
344  "type '%s' cannot convert to c++ argument of "
345  "type '%s' at index %zu",
346  param.name.c_str(),
347  param.val.GetTypeName().c_str(),
348  ArchGetDemangled<ParamType>().c_str(),
349  index);
350  valid = false;
351  }
352  }
353 
354  template <class ParamsTuple, size_t... I>
355  static bool
356  _CheckNamesAndDefaultsImpl(
357  NamesAndDefaults const &namesAndDefaults,
358  std::index_sequence<I...>) {
359  // A fold expression would let us just do &&, but that's c++'17, so we
360  // just do all of them and set a bool.
361  bool valid = true;
362  constexpr size_t N = std::tuple_size<ParamsTuple>::value;
363  // Need an unused array so we can use an initializer list to invoke
364  // _CheckOneNameAndDefault N times.
365  int unused[] = {
366  0,
367  (_CheckOneNameAndDefault<std::tuple_element_t<N-I-1, ParamsTuple>>(
368  valid, N-I-1, N, namesAndDefaults), 0)...
369  };
370  TF_UNUSED(unused);
371  return valid;
372  }
373 
374  template <class Fn>
375  static bool
376  _CheckNamesAndDefaultsWithSignature(
377  NamesAndDefaults const &namesAndDefaults) {
378  // Basic check for declared names & defaults.
379  if (!namesAndDefaults.CheckValidity()) {
380  return false;
381  }
382 
383  using Traits = TfFunctionTraits<Fn>;
384 
385  // Return type must convert to bool.
386  static_assert(
387  std::is_same<typename Traits::ReturnType,
389  std::is_convertible<
390  typename Traits::ReturnType, bool>::value, "");
391 
392  // Fn must have at least one argument, and DomainType must be
393  // convertible to the first arg.
394  using DomainArgType = typename Traits::template NthArg<0>;
395  static_assert(
397 
398  // Issue an error if there are more named arguments than c++ function
399  // arguments. Subtract one from Arity to account for the leading
400  // DomainType argument.
401  std::vector<NamesAndDefaults::Param> const &
402  params = namesAndDefaults.GetParams();
403  if (params.size() > Traits::Arity-1) {
404  TF_CODING_ERROR("Predicate named arguments (%zu) exceed number of "
405  "C++ function arguments (%zu)",
406  params.size(), Traits::Arity-1);
407  return false;
408  }
409 
410  // Now check the names and defaults against the Fn signature, from back
411  // to front, since namesAndDefaults must be "right-aligned" -- that is,
412  // any unnamed arguments must come first.
413  if (!params.empty()) {
414  // Strip DomainType arg...
415  using FullParams = typename Traits::ArgTypes;
416  using Params =
418  using ParamsTuple = TfMetaApply<std::tuple, Params>;
419 
420  return _CheckNamesAndDefaultsImpl<ParamsTuple>(
421  namesAndDefaults, std::make_index_sequence<Traits::Arity-1> {});
422  }
423  return true;
424  }
425 
426  template <class ParamType>
427  static void _TryBindOne(
428  size_t index, size_t numParams,
429  ParamType &param,
430  bool &boundAllParams,
431  std::vector<SdfPredicateExpression::FnArg> const &args,
432  std::vector<bool> &boundArgs,
433  NamesAndDefaults const &namesAndDefaults) {
434 
435  // Bind the index-th 'param' from 'args' &
436  // 'namesAndDefaults'. 'boundArgs' corresponds to 'args' and indicates
437  // which have already been bound. This function sets one bit in
438  // 'boundArgs' if it binds one of them to a parameter. It may bind a
439  // default from 'namesAndDefaults', in which case it sets no bit. If no
440  // suitable binding can be determined for this parameter, set
441  // 'boundAllParams' false.
442 
443  // If we've already failed to bind, just return early.
444  if (!boundAllParams) {
445  return;
446  }
447 
448  // namesAndDefaults covers trailing parameters -- that is, there may be
449  // zero or more leading unnamed parameters.
450  std::vector<NamesAndDefaults::Param> const &
451  params = namesAndDefaults.GetParams();
452  size_t numUnnamed = params.size() - numParams;
453  NamesAndDefaults::Param const *paramNameAndDefault = nullptr;
454  if (index >= numUnnamed) {
455  paramNameAndDefault = &params[index - numUnnamed];
456  }
457 
458  // If this is a purely positional parameter (paramNameAndDefault is
459  // nullptr) or the caller supplied a positional arg (unnamed) then we
460  // use index-correspondence.
461  auto const *posArg =
462  (index < args.size() && args[index].argName.empty()) ?
463  &args[index] : nullptr;
464 
465  auto tryBind = [&](VtValue const &val, size_t argIndex) {
466  VtValue cast = VtValue::Cast<ParamType>(val);
467  if (!cast.IsEmpty()) {
468  param = cast.UncheckedRemove<ParamType>();
469  boundArgs[argIndex] = true;
470  return true;
471  }
472  boundAllParams = false;
473  return false;
474  };
475 
476  if (!paramNameAndDefault) {
477  // If this is a positional parameter, the arg must be too.
478  if (!posArg || !posArg->argName.empty()) {
479  boundAllParams = false;
480  return;
481  }
482  // Try to bind posArg.
483  tryBind(posArg->value, index);
484  return;
485  }
486  else if (posArg) {
487  // Passed a positional arg, try to bind.
488  tryBind(posArg->value, index);
489  return;
490  }
491 
492  // Only possibility is a keyword arg. If there's a matching name, try
493  // to bind that, otherwise try to fill a default.
494  for (size_t i = 0, end = args.size(); i != end; ++i) {
495  if (boundArgs[i]) {
496  // Already bound.
497  continue;
498  }
499  if (args[i].argName == paramNameAndDefault->name) {
500  // Matching name -- try to bind.
501  tryBind(args[i].value, i);
502  return;
503  }
504  }
505 
506  // No matching arg, try to fill default val.
507  VtValue cast = VtValue::Cast<ParamType>(paramNameAndDefault->val);
508  if (!cast.IsEmpty()) {
509  param = cast.UncheckedRemove<ParamType>();
510  }
511  else {
512  // Error, could not fill default.
513  boundAllParams = false;
514  }
515  }
516 
517  template <class ParamsTuple, size_t... I>
518  static bool
519  _TryBindArgs(ParamsTuple &params,
520  std::vector<SdfPredicateExpression::FnArg> const &args,
521  NamesAndDefaults const &namesAndDefaults,
522  std::index_sequence<I...>,
523  std::vector<bool> &boundArgs) {
524 
525  // A fold expression would let us just do &&, but that's '17, so we just
526  // do all of them and set a bool.
527  bool bound = true;
528  boundArgs.assign(args.size(), false);
529  // Need a unused array so we can use an initializer list to invoke
530  // _TryBindOne N times.
531  int unused[] = {
532  0,
533  (_TryBindOne(I, std::tuple_size<ParamsTuple>::value,
534  std::get<I>(params), bound,
535  args, boundArgs, namesAndDefaults), 0)...
536  };
537  TF_UNUSED(unused);
538  return bound;
539  }
540 
541  template <class Tuple>
542  static void
543  _FillArbitraryArgs(std::true_type,
544  std::vector<SdfPredicateExpression::FnArg> const &args,
545  std::vector<bool> const &boundArgs,
546  Tuple &typedArgs) {
547  std::vector<SdfPredicateExpression::FnArg> &rest =
549  // 'boundArgs' and 'args' correspond. Fill 'rest' with the elements of
550  // 'args' for which the corresponding element of 'boundArgs' is false,
551  // in order.
552  rest.clear();
553  for (size_t i = 0; i != args.size(); ++i) {
554  if (!boundArgs[i]) {
555  rest.push_back(args[i]);
556  }
557  }
558  }
559 
560  template <class T>
561  static void
562  _FillArbitraryArgs(std::false_type,
563  std::vector<SdfPredicateExpression::FnArg> const &,
564  std::vector<bool> const &,
565  T const &) {
566  // Do nothing.
567  }
568 
569  template <class ParamsTuple>
570  static constexpr bool
571  _TakesArbitraryArgs(std::true_type) { // arity >= 2.
572  return std::is_same<
574  ParamsTuple>,
575  std::vector<SdfPredicateExpression::FnArg>
576  >::value;
577  }
578 
579  template <class ParamsTuple>
580  static constexpr bool
581  _TakesArbitraryArgs(std::false_type) { // arity < 2.
582  return false;
583  }
584 
585  template <class Fn>
586  static PredicateFunction
587  _TryToBindCall(Fn const &fn,
588  std::vector<SdfPredicateExpression::FnArg> const &args,
589  NamesAndDefaults const &namesAndDefaults) {
590 
591  // We need to determine an argument for each parameter of Fn, then make
592  // a callable object that calls that function.
593 
594  // Strip DomainType arg...
595  using Traits = TfFunctionTraits<Fn>;
596  using FullParams = typename Traits::ArgTypes;
597  using Params =
599  using ParamsTuple = TfMetaApply<std::tuple, Params>;
600 
601  // If there are at least two parameters to Fn (first has to be
602  // DomainType) and the last parameter type is vector<FnArg>, then
603  // namesAndDefaults does not apply to it, and any remaining unbound args
604  // after binding are passed through that parameter.
605  static const bool TakesArbitraryArgs =
606  _TakesArbitraryArgs<ParamsTuple>(
607  std::integral_constant<bool, Traits::Arity >= 2> {});
608 
609  size_t minArgs = Traits::Arity-1 - namesAndDefaults.GetNumDefaults();
610  size_t maxArgs = TakesArbitraryArgs ? size_t(-1) : Traits::Arity-1;
611 
612  // Number of bindable args is arity-1 (for the domain arg) or -2 if the
613  // trailing parameter is the vector<FnArg> bag of extra arguments.
614  static const size_t NumBindableArgs =
615  Traits::Arity - (TakesArbitraryArgs ? 2 : 1);
616 
617  if (args.size() < minArgs) {
618  TF_RUNTIME_ERROR("Function requires at least %zu argument%s, "
619  "%zu given", minArgs, minArgs == 1 ? "" : "s",
620  args.size());
621  return {};
622  }
623  if (args.size() > maxArgs) {
624  TF_RUNTIME_ERROR("Function takes at most %zu argument%s, %zu given",
625  maxArgs, maxArgs == 1 ? "" : "s", args.size());
626  return {};
627  }
628 
629  ParamsTuple typedArgs;
630  std::vector<bool> boundArgs;
631  if (_TryBindArgs(typedArgs, args, namesAndDefaults,
632  std::make_index_sequence<NumBindableArgs> {},
633  boundArgs)) {
634  _FillArbitraryArgs(
635  std::integral_constant<bool, TakesArbitraryArgs> {},
636  args, boundArgs, typedArgs);
637  return [typedArgs, fn](DomainType const &obj) {
639  std::apply(fn,
640  std::tuple_cat(std::make_tuple(obj), typedArgs))
641  };
642  };
643  }
644  return {};
645  }
646 
647  struct _OverloadBinderBase
648  {
649  virtual ~_OverloadBinderBase() = default;
651  Bind(std::vector<SdfPredicateExpression::FnArg> const &args) const {
652  return _Bind(args);
653  }
654  virtual std::unique_ptr<_OverloadBinderBase> Clone() const = 0;
655  protected:
656  _OverloadBinderBase() = default;
657 
658  explicit _OverloadBinderBase(NamesAndDefaults const &namesAndDefaults)
659  : _namesAndDefaults(namesAndDefaults) {}
660 
661  virtual PredicateFunction
662  _Bind(std::vector<
663  SdfPredicateExpression::FnArg> const &args) const = 0;
664 
665  NamesAndDefaults _namesAndDefaults;
666  };
667 
668  template <class Fn>
669  struct _OverloadBinder : _OverloadBinderBase
670  {
671  ~_OverloadBinder() override = default;
672 
673  static std::unique_ptr<_OverloadBinder>
674  TryCreate(Fn &&fn, NamesAndDefaults const &nd) {
675  auto ret = std::unique_ptr<_OverloadBinder>(
676  new _OverloadBinder(std::move(fn), nd));
677  if (!_CheckNamesAndDefaultsWithSignature<Fn>(nd)) {
678  ret.reset();
679  }
680  return ret;
681  }
682 
683  std::unique_ptr<_OverloadBinderBase> Clone() const override {
684  return std::unique_ptr<
685  _OverloadBinder>(new _OverloadBinder(*this));
686  }
687 
688  private:
689  _OverloadBinder(_OverloadBinder const &) = default;
690 
691  explicit _OverloadBinder(Fn &&fn,
692  NamesAndDefaults const &namesAndDefaults)
693  : _OverloadBinderBase(namesAndDefaults)
694  , _fn(std::move(fn)) {}
695 
696  explicit _OverloadBinder(Fn const &fn,
697  NamesAndDefaults const &namesAndDefaults)
698  : _OverloadBinder(Fn(fn), namesAndDefaults) {}
699 
701  _Bind(std::vector<
702  SdfPredicateExpression::FnArg> const &args) const override {
703  // Try to bind 'args' to _fn's parameters, taking _namesAndDefaults
704  // into account.
705  return _TryToBindCall(_fn, args, this->_namesAndDefaults);
706  }
707 
708  Fn _fn;
709  };
710 
711  template <class Fn>
712  struct _CustomBinder : _OverloadBinderBase
713  {
714  ~_CustomBinder() override = default;
715 
716  static std::unique_ptr<_CustomBinder>
717  Create(Fn &&fn) {
718  return std::unique_ptr<_CustomBinder>(
719  new _CustomBinder(std::move(fn)));
720  }
721 
722  std::unique_ptr<_OverloadBinderBase> Clone() const override {
723  return std::unique_ptr<_CustomBinder>(new _CustomBinder(*this));
724  }
725 
726  private:
727  _CustomBinder(_CustomBinder const &) = default;
728  explicit _CustomBinder(Fn &&fn)
729  : _OverloadBinderBase()
730  , _fn(std::move(fn)) {}
731  explicit _CustomBinder(Fn const &fn) : _CustomBinder(Fn(fn)) {}
732 
734  _Bind(std::vector<
735  SdfPredicateExpression::FnArg> const &args) const override {
736  // Call _fn to try to bind 'args', producing a callable.
737  return _fn(args);
738  }
739 
740  Fn _fn;
741  };
742 
743  using _OverloadBinderBasePtr = std::unique_ptr<_OverloadBinderBase>;
744 
746  std::string, std::vector<_OverloadBinderBasePtr>
747  > _binders;
748 };
749 
751 
752 #endif // PXR_USD_SDF_PREDICATE_EXPRESSION_EVAL_H
std::vector< Param > GetParams() const &&
Move-return the parameters in a vector.
iterator end() noexcept
Definition: robin_map.h:222
friend bool operator==(SdfPredicateFunctionResult pfr, bool rhs)
Param(char const *name, Val &&defVal)
Construct from name and default value.
bool GetValue() const
Return the result value.
SdfPredicateProgram< DomainType > SdfLinkPredicateExpression(SdfPredicateExpression const &expr, SdfPredicateLibrary< DomainType > const &lib)
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
#define TF_CODING_ERROR
Param(char const *name)
Construct with or implicitly convert from name.
SdfPredicateLibrary & Define(char const *name, Fn &&fn)
bool IsConstant() const
Return true if this result's constancy is ConstantOverDescendants.
bool IsEmpty() const
Returns true iff this value is empty.
Definition: value.h:1285
GLenum const GLfloat * params
Definition: glcorearb.h:105
OutGridT const XformOp bool bool
friend bool operator==(bool lhs, SdfPredicateFunctionResult pfr)
std::decay_t< decltype(make_index_sequence_impl< N >())> make_index_sequence
Definition: Types.h:234
iterator find(const Key &key)
Definition: robin_map.h:501
SdfPredicateFunctionResult operator!() const
Return a result with the opposite value but the same constancy.
#define TF_RUNTIME_ERROR
SdfPredicateFunctionResult(bool value, Constancy constancy)
Construct with value and constancy.
void SetAndPropagateConstancy(SdfPredicateFunctionResult other)
SYS_FORCE_INLINE const X * cast(const InstancablePtr *o)
static SdfPredicateFunctionResult MakeConstant(bool value)
Create with value and 'ConstantOverDescendants'.
Constancy GetConstancy() const
Return the result constancy.
GLuint GLuint end
Definition: glcorearb.h:475
static SdfPredicateFunctionResult MakeVarying(bool value)
Create with value and 'MayVaryOverDescendants'.
T UncheckedRemove()
Definition: value.h:1024
friend bool operator!=(bool lhs, SdfPredicateFunctionResult pfr)
friend bool operator!=(SdfPredicateFunctionResult lhs, SdfPredicateFunctionResult rhs)
GLuint const GLchar * name
Definition: glcorearb.h:786
SdfPredicateLibrary & operator=(SdfPredicateLibrary const &other)
Copy-assignment from an other library.
friend bool operator==(SdfPredicateFunctionResult lhs, SdfPredicateFunctionResult rhs)
bool(SdfPredicateFunctionResult::*) UnspecifiedBoolType
std::function< SdfPredicateFunctionResult(DomainType const &)> PredicateFunction
The type of a bound function, the result of binding passed arguments.
SdfPredicateLibrary(SdfPredicateLibrary const &other)
Copy-construct from an other library.
SdfPredicateLibrary & DefineBinder(std::string const &name, Fn &&fn)
#define SDF_API
Definition: api.h:23
GLenum GLfloat param
Definition: glcorearb.h:104
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
SDF_API bool CheckValidity() const
GLuint index
Definition: glcorearb.h:786
#define TF_UNUSED(x)
Definition: tf.h:168
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
std::vector< Param > const & GetParams() const &
Return a reference to the parameters in a vector.
GA_API const UT_StringHolder N
**If you just want to fire and args
Definition: thread.h:618
OIIO_UTIL_API const char * c_str(string_view str)
SdfPredicateLibrary & operator=(SdfPredicateLibrary &&other)=default
Move-assignment from an other library.
SdfPredicateLibrary & Define(std::string const &name, Fn &&fn, NamesAndDefaults const &namesAndDefaults)
size_t GetNumDefaults() const
Return the number of params with default values.
SdfPredicateParamNamesAndDefaults()
Default constructor produces empty set of names & defaults.
typename Tf_GetFuncSig< Fn >::Type TfFunctionTraits
iterator begin() noexcept
Definition: robin_map.h:218
GA_API const UT_StringHolder rest
SdfPredicateFunctionResult(bool value)
Construct with value and MayVaryOverDescendants constancy.
Definition: value.h:146
SdfPredicateLibrary()=default
Default constructor produces an empty library.
friend bool operator!=(SdfPredicateFunctionResult pfr, bool rhs)
typename Tf_MetaApplyImpl< Cls, TypeList >::Type TfMetaApply
Definition: meta.h:36
SdfPredicateParamNamesAndDefaults(std::initializer_list< Param > const &params)
Construct or implicitly convert from initializer_list<Param>.
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:566