7 #ifndef PXR_USD_SDF_PREDICATE_LIBRARY_H
8 #define PXR_USD_SDF_PREDICATE_LIBRARY_H
20 #include <initializer_list>
46 : name(name),
val(std::forward<Val>(defVal)) {}
57 std::initializer_list<Param>
const &
params)
58 : _params(params.
begin(), params.
end())
59 , _numDefaults(_CountDefaults()) {}
75 return std::move(_params);
85 size_t _CountDefaults()
const;
87 std::vector<Param> _params;
113 : _value(value), _constancy(constancy) {}
135 return (lc && rc) || (!lv && lc) || (!rv && rc)
150 return (lc && rc) || (lv && lc) || (rv && rc)
170 #if !defined(doxygen)
176 return _value ? &SdfPredicateFunctionResult::_value :
nullptr;
181 return { !_value, _constancy };
189 _value = other._value;
199 return lhs._value == rhs._value &&
200 lhs._constancy == rhs._constancy;
204 return !(lhs == rhs);
208 return pfr._value == rhs;
211 return lhs == pfr._value;
214 return pfr._value != rhs;
217 return lhs != pfr._value;
225 template <
class DomainType>
229 template <
class DomainType>
233 template <
class DomainType>
243 template <
class DomainType>
247 SdfLinkPredicateExpression<DomainType>(
256 std::function<SdfPredicateFunctionResult (DomainType const &)>;
266 for (
auto iter = other._binders.
begin(),
end = other._binders.
end();
267 iter !=
end; ++iter) {
268 auto &theseBinders = _binders[iter->first];
269 for (
auto const &otherBinder: iter->second) {
270 theseBinders.push_back(otherBinder->Clone());
280 if (
this != &other) {
282 *
this = std::move(copy);
292 return Define(name, std::forward<Fn>(fn), {});
308 if (
auto obinder = _OverloadBinder<std::decay_t<Fn>>
309 ::TryCreate(std::forward<Fn>(fn), namesAndDefaults)) {
310 _binders[
name].push_back(std::move(obinder));
324 auto binder = _CustomBinder<
325 std::decay_t<Fn>>::Create(std::forward<Fn>(fn));
326 _binders[
name].push_back(std::move(binder));
333 _BindCall(std::string
const &
name,
334 std::vector<SdfPredicateExpression::FnArg>
const &
args)
const {
336 auto iter = _binders.
find(name);
337 if (iter == _binders.
end()) {
343 for (
auto i = iter->second.rbegin(),
344 end = iter->second.rend(); i !=
end; ++i) {
345 ret = (*i)->Bind(args);
353 template <
class ParamType>
354 static void _CheckOneNameAndDefault(
355 bool &valid,
size_t index,
size_t numParams,
356 NamesAndDefaults
const &namesAndDefaults) {
360 std::vector<NamesAndDefaults::Param>
const &
361 params = namesAndDefaults.GetParams();
363 size_t nFromEnd = numParams - index - 1;
364 if (nFromEnd >= params.size()) {
369 size_t namesIndex = params.size() - nFromEnd - 1;
371 auto const &
param = params[namesIndex];
372 if (!
param.val.IsEmpty() && !
param.val.CanCast<ParamType>()) {
374 "type '%s' cannot convert to c++ argument of "
375 "type '%s' at index %zu",
377 param.val.GetTypeName().c_str(),
378 ArchGetDemangled<ParamType>().
c_str(),
384 template <
class ParamsTuple,
size_t... I>
386 _CheckNamesAndDefaultsImpl(
387 NamesAndDefaults
const &namesAndDefaults,
388 std::index_sequence<I...>) {
397 (_CheckOneNameAndDefault<std::tuple_element_t<N-I-1, ParamsTuple>>(
398 valid, N-I-1,
N, namesAndDefaults), 0)...
406 _CheckNamesAndDefaultsWithSignature(
407 NamesAndDefaults
const &namesAndDefaults) {
409 if (!namesAndDefaults.CheckValidity()) {
417 std::is_same<
typename Traits::ReturnType,
420 typename Traits::ReturnType,
bool>::
value,
"");
424 using DomainArgType =
typename Traits::template NthArg<0>;
431 std::vector<NamesAndDefaults::Param>
const &
432 params = namesAndDefaults.GetParams();
433 if (params.size() > Traits::Arity-1) {
435 "C++ function arguments (%zu)",
436 params.size(), Traits::Arity-1);
443 if (!params.empty()) {
445 using FullParams =
typename Traits::ArgTypes;
450 return _CheckNamesAndDefaultsImpl<ParamsTuple>(
456 template <
class ParamType>
457 static void _TryBindOne(
458 size_t index,
size_t numParams,
460 bool &boundAllParams,
461 std::vector<SdfPredicateExpression::FnArg>
const &args,
462 std::vector<bool> &boundArgs,
463 NamesAndDefaults
const &namesAndDefaults) {
474 if (!boundAllParams) {
480 std::vector<NamesAndDefaults::Param>
const &
481 params = namesAndDefaults.GetParams();
482 size_t numUnnamed = params.size() - numParams;
484 if (index >= numUnnamed) {
485 paramNameAndDefault = ¶ms[index - numUnnamed];
492 (index < args.size() && args[
index].argName.empty()) ?
493 &args[index] :
nullptr;
495 auto tryBind = [&](
VtValue const &
val,
size_t argIndex) {
499 boundArgs[argIndex] =
true;
502 boundAllParams =
false;
506 if (!paramNameAndDefault) {
508 if (!posArg || !posArg->argName.empty()) {
509 boundAllParams =
false;
513 tryBind(posArg->value, index);
518 tryBind(posArg->value, index);
524 for (
size_t i = 0,
end = args.size(); i !=
end; ++i) {
529 if (args[i].argName == paramNameAndDefault->name) {
531 tryBind(args[i].
value, i);
537 VtValue cast = VtValue::Cast<ParamType>(paramNameAndDefault->val);
543 boundAllParams =
false;
547 template <
class ParamsTuple,
size_t... I>
549 _TryBindArgs(ParamsTuple ¶ms,
550 std::vector<SdfPredicateExpression::FnArg>
const &args,
551 NamesAndDefaults
const &namesAndDefaults,
552 std::index_sequence<I...>,
553 std::vector<bool> &boundArgs) {
558 boundArgs.assign(args.size(),
false);
564 std::get<I>(params), bound,
565 args, boundArgs, namesAndDefaults), 0)...
571 template <
class Tuple>
573 _FillArbitraryArgs(std::true_type,
574 std::vector<SdfPredicateExpression::FnArg>
const &args,
575 std::vector<bool>
const &boundArgs,
577 std::vector<SdfPredicateExpression::FnArg> &
rest =
583 for (
size_t i = 0; i != args.size(); ++i) {
585 rest.push_back(args[i]);
592 _FillArbitraryArgs(std::false_type,
593 std::vector<SdfPredicateExpression::FnArg>
const &,
594 std::vector<bool>
const &,
599 template <
class ParamsTuple>
600 static constexpr
bool
601 _TakesArbitraryArgs(std::true_type) {
605 std::vector<SdfPredicateExpression::FnArg>
609 template <
class ParamsTuple>
610 static constexpr
bool
611 _TakesArbitraryArgs(std::false_type) {
617 _TryToBindCall(Fn
const &fn,
618 std::vector<SdfPredicateExpression::FnArg>
const &args,
619 NamesAndDefaults
const &namesAndDefaults) {
626 using FullParams =
typename Traits::ArgTypes;
635 static const bool TakesArbitraryArgs =
636 _TakesArbitraryArgs<ParamsTuple>(
637 std::integral_constant<bool, Traits::Arity >= 2> {});
639 size_t minArgs = Traits::Arity-1 - namesAndDefaults.GetNumDefaults();
640 size_t maxArgs = TakesArbitraryArgs ? size_t(-1) : Traits::Arity-1;
644 static const size_t NumBindableArgs =
645 Traits::Arity - (TakesArbitraryArgs ? 2 : 1);
647 if (args.size() < minArgs) {
649 "%zu given", minArgs, minArgs == 1 ?
"" :
"s",
653 if (args.size() > maxArgs) {
655 maxArgs, maxArgs == 1 ?
"" :
"s", args.size());
659 ParamsTuple typedArgs;
660 std::vector<bool> boundArgs;
661 if (_TryBindArgs(typedArgs, args, namesAndDefaults,
662 std::make_index_sequence<NumBindableArgs> {},
665 std::integral_constant<bool, TakesArbitraryArgs> {},
666 args, boundArgs, typedArgs);
667 return [typedArgs, fn](DomainType
const &obj) {
670 std::tuple_cat(std::make_tuple(obj), typedArgs))
677 struct _OverloadBinderBase
679 virtual ~_OverloadBinderBase() =
default;
681 Bind(std::vector<SdfPredicateExpression::FnArg>
const &args)
const {
684 virtual std::unique_ptr<_OverloadBinderBase> Clone()
const = 0;
686 _OverloadBinderBase() =
default;
688 explicit _OverloadBinderBase(NamesAndDefaults
const &namesAndDefaults)
689 : _namesAndDefaults(namesAndDefaults) {}
695 NamesAndDefaults _namesAndDefaults;
699 struct _OverloadBinder : _OverloadBinderBase
701 ~_OverloadBinder()
override =
default;
703 static std::unique_ptr<_OverloadBinder>
704 TryCreate(Fn &&fn, NamesAndDefaults
const &nd) {
705 auto ret = std::unique_ptr<_OverloadBinder>(
706 new _OverloadBinder(std::move(fn), nd));
707 if (!_CheckNamesAndDefaultsWithSignature<Fn>(nd)) {
713 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
714 return std::unique_ptr<
715 _OverloadBinder>(
new _OverloadBinder(*
this));
719 _OverloadBinder(_OverloadBinder
const &) =
default;
721 explicit _OverloadBinder(Fn &&fn,
722 NamesAndDefaults
const &namesAndDefaults)
723 : _OverloadBinderBase(namesAndDefaults)
724 , _fn(std::move(fn)) {}
726 explicit _OverloadBinder(Fn
const &fn,
727 NamesAndDefaults
const &namesAndDefaults)
728 : _OverloadBinder(Fn(fn), namesAndDefaults) {}
735 return _TryToBindCall(_fn, args, this->_namesAndDefaults);
742 struct _CustomBinder : _OverloadBinderBase
744 ~_CustomBinder()
override =
default;
746 static std::unique_ptr<_CustomBinder>
748 return std::unique_ptr<_CustomBinder>(
749 new _CustomBinder(std::move(fn)));
752 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
753 return std::unique_ptr<_CustomBinder>(
new _CustomBinder(*
this));
757 _CustomBinder(_CustomBinder
const &) =
default;
758 explicit _CustomBinder(Fn &&fn)
759 : _OverloadBinderBase()
760 , _fn(std::move(fn)) {}
761 explicit _CustomBinder(Fn
const &fn) : _CustomBinder(Fn(fn)) {}
773 using _OverloadBinderBasePtr = std::unique_ptr<_OverloadBinderBase>;
776 std::string, std::vector<_OverloadBinderBasePtr>
782 #endif // PXR_USD_SDF_PREDICATE_EXPRESSION_EVAL_H
std::vector< Param > GetParams() const &&
Move-return the parameters in a vector.
friend bool operator==(SdfPredicateFunctionResult pfr, bool rhs)
Param(char const *name, Val &&defVal)
Construct from name and default value.
static SdfPredicateFunctionResult Or(SdfPredicateFunctionResult lhs, SdfPredicateFunctionResult rhs)
bool GetValue() const
Return the result value.
SdfPredicateProgram< DomainType > SdfLinkPredicateExpression(SdfPredicateExpression const &expr, SdfPredicateLibrary< DomainType > const &lib)
#define PXR_NAMESPACE_OPEN_SCOPE
GLsizei const GLfloat * value
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.
GLenum const GLfloat * params
friend bool operator==(bool lhs, SdfPredicateFunctionResult pfr)
std::decay_t< decltype(make_index_sequence_impl< N >())> make_index_sequence
iterator find(const Key &key)
SdfPredicateFunctionResult operator!() const
Return a result with the opposite value but the same constancy.
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 And(SdfPredicateFunctionResult lhs, SdfPredicateFunctionResult rhs)
static SdfPredicateFunctionResult MakeConstant(bool value)
Create with value and 'ConstantOverDescendants'.
Constancy GetConstancy() const
Return the result constancy.
static SdfPredicateFunctionResult MakeVarying(bool value)
Create with value and 'MayVaryOverDescendants'.
friend bool operator!=(bool lhs, SdfPredicateFunctionResult pfr)
friend bool operator!=(SdfPredicateFunctionResult lhs, SdfPredicateFunctionResult rhs)
GLuint const GLchar * name
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)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
SDF_API bool CheckValidity() const
#define PXR_NAMESPACE_CLOSE_SCOPE
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
constexpr SdfPredicateFunctionResult()
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
GA_API const UT_StringHolder rest
SdfPredicateFunctionResult(bool value)
Construct with value and MayVaryOverDescendants constancy.
SdfPredicateLibrary()=default
Default constructor produces an empty library.
friend bool operator!=(SdfPredicateFunctionResult pfr, bool rhs)
SdfPredicateParamNamesAndDefaults(std::initializer_list< Param > const ¶ms)
Construct or implicitly convert from initializer_list<Param>.