24 #ifndef PXR_USD_SDF_PREDICATE_LIBRARY_H
25 #define PXR_USD_SDF_PREDICATE_LIBRARY_H
38 #include <initializer_list>
64 : name(name),
val(std::forward<Val>(defVal)) {}
75 std::initializer_list<Param>
const &
params)
76 : _params(params.
begin(), params.
end())
77 , _numDefaults(_CountDefaults()) {}
93 return std::move(_params);
103 size_t _CountDefaults()
const;
105 std::vector<Param> _params;
131 : _value(value), _constancy(constancy) {}
158 #if !defined(doxygen)
164 return _value ? &SdfPredicateFunctionResult::_value :
nullptr;
169 return { !_value, _constancy };
177 _value = other._value;
187 return lhs._value == rhs._value &&
188 lhs._constancy == rhs._constancy;
192 return !(lhs == rhs);
196 return pfr._value == rhs;
199 return lhs == pfr._value;
202 return pfr._value != rhs;
205 return lhs != pfr._value;
213 template <
class DomainType>
217 template <
class DomainType>
221 template <
class DomainType>
231 template <
class DomainType>
235 SdfLinkPredicateExpression<DomainType>(
244 std::function<SdfPredicateFunctionResult (DomainType const &)>;
254 for (
auto iter = other._binders.
begin(),
end = other._binders.
end();
255 iter !=
end; ++iter) {
256 auto &theseBinders = _binders[iter->first];
257 for (
auto const &otherBinder: iter->second) {
258 theseBinders.push_back(otherBinder->Clone());
268 if (
this != &other) {
270 *
this = std::move(copy);
280 return Define(name, std::forward<Fn>(fn), {});
296 if (
auto obinder = _OverloadBinder<std::decay_t<Fn>>
297 ::TryCreate(std::forward<Fn>(fn), namesAndDefaults)) {
298 _binders[
name].push_back(std::move(obinder));
312 auto binder = _CustomBinder<
313 std::decay_t<Fn>>::Create(std::forward<Fn>(fn));
314 _binders[
name].push_back(std::move(binder));
322 std::vector<SdfPredicateExpression::FnArg>
const &
args)
const {
324 auto iter = _binders.
find(name);
325 if (iter == _binders.
end()) {
331 for (
auto i = iter->second.rbegin(),
332 end = iter->second.rend(); i !=
end; ++i) {
333 ret = (*i)->Bind(args);
341 template <
class ParamType>
342 static void _CheckOneNameAndDefault(
343 bool &valid,
size_t index,
size_t numParams,
344 NamesAndDefaults
const &namesAndDefaults) {
348 std::vector<NamesAndDefaults::Param>
const &
349 params = namesAndDefaults.GetParams();
351 size_t nFromEnd = numParams - index - 1;
352 if (nFromEnd >= params.size()) {
357 size_t namesIndex = params.size() - nFromEnd - 1;
359 auto const &
param = params[namesIndex];
360 if (!
param.val.IsEmpty() && !
param.val.CanCast<ParamType>()) {
362 "type '%s' cannot convert to c++ argument of "
363 "type '%s' at index %zu",
365 param.val.GetTypeName().c_str(),
366 ArchGetDemangled<ParamType>().c_str(),
372 template <
class ParamsTuple,
size_t... I>
374 _CheckNamesAndDefaultsImpl(
375 NamesAndDefaults
const &namesAndDefaults,
376 std::index_sequence<I...>) {
385 (_CheckOneNameAndDefault<std::tuple_element_t<N-I-1, ParamsTuple>>(
386 valid, N-I-1,
N, namesAndDefaults), 0)...
394 _CheckNamesAndDefaultsWithSignature(
395 NamesAndDefaults
const &namesAndDefaults) {
397 if (!namesAndDefaults.CheckValidity()) {
405 std::is_same<
typename Traits::ReturnType,
408 typename Traits::ReturnType,
bool>::
value,
"");
412 using DomainArgType =
typename Traits::template NthArg<0>;
419 std::vector<NamesAndDefaults::Param>
const &
420 params = namesAndDefaults.GetParams();
421 if (params.size() > Traits::Arity-1) {
423 "C++ function arguments (%zu)",
424 params.size(), Traits::Arity-1);
431 if (!params.empty()) {
433 using FullParams =
typename Traits::ArgTypes;
438 return _CheckNamesAndDefaultsImpl<ParamsTuple>(
444 template <
class ParamType>
445 static void _TryBindOne(
446 size_t index,
size_t numParams,
448 bool &boundAllParams,
449 std::vector<SdfPredicateExpression::FnArg>
const &args,
450 std::vector<bool> &boundArgs,
451 NamesAndDefaults
const &namesAndDefaults) {
462 if (!boundAllParams) {
468 std::vector<NamesAndDefaults::Param>
const &
469 params = namesAndDefaults.GetParams();
470 size_t numUnnamed = params.size() - numParams;
472 if (index >= numUnnamed) {
473 paramNameAndDefault = ¶ms[index - numUnnamed];
480 (index < args.size() && args[
index].argName.empty()) ?
481 &args[index] :
nullptr;
483 auto tryBind = [&](
VtValue const &
val,
size_t argIndex) {
487 boundArgs[argIndex] =
true;
490 boundAllParams =
false;
494 if (!paramNameAndDefault) {
496 if (!posArg || !posArg->argName.empty()) {
497 boundAllParams =
false;
501 tryBind(posArg->value, index);
506 tryBind(posArg->value, index);
512 for (
size_t i = 0,
end = args.size(); i !=
end; ++i) {
517 if (args[i].argName == paramNameAndDefault->name) {
519 tryBind(args[i].
value, i);
525 VtValue cast = VtValue::Cast<ParamType>(paramNameAndDefault->val);
531 boundAllParams =
false;
535 template <
class ParamsTuple,
size_t... I>
537 _TryBindArgs(ParamsTuple ¶ms,
538 std::vector<SdfPredicateExpression::FnArg>
const &args,
539 NamesAndDefaults
const &namesAndDefaults,
540 std::index_sequence<I...>,
541 std::vector<bool> &boundArgs) {
546 boundArgs.assign(args.size(),
false);
552 std::get<I>(params), bound,
553 args, boundArgs, namesAndDefaults), 0)...
559 template <
class Tuple>
561 _FillArbitraryArgs(std::true_type,
562 std::vector<SdfPredicateExpression::FnArg>
const &args,
563 std::vector<bool>
const &boundArgs,
565 std::vector<SdfPredicateExpression::FnArg> &
rest =
571 for (
size_t i = 0; i != args.size(); ++i) {
573 rest.push_back(args[i]);
580 _FillArbitraryArgs(std::false_type,
581 std::vector<SdfPredicateExpression::FnArg>
const &,
582 std::vector<bool>
const &,
587 template <
class ParamsTuple>
588 static constexpr
bool
589 _TakesArbitraryArgs(std::true_type) {
593 std::vector<SdfPredicateExpression::FnArg>
597 template <
class ParamsTuple>
598 static constexpr
bool
599 _TakesArbitraryArgs(std::false_type) {
605 _TryToBindCall(Fn
const &fn,
606 std::vector<SdfPredicateExpression::FnArg>
const &args,
607 NamesAndDefaults
const &namesAndDefaults) {
614 using FullParams =
typename Traits::ArgTypes;
623 static const bool TakesArbitraryArgs =
624 _TakesArbitraryArgs<ParamsTuple>(
625 std::integral_constant<bool, Traits::Arity >= 2> {});
627 size_t minArgs = Traits::Arity-1 - namesAndDefaults.GetNumDefaults();
628 size_t maxArgs = TakesArbitraryArgs ? size_t(-1) : Traits::Arity-1;
632 static const size_t NumBindableArgs =
633 Traits::Arity - (TakesArbitraryArgs ? 2 : 1);
635 if (args.size() < minArgs) {
637 "%zu given", minArgs, minArgs == 1 ?
"" :
"s",
641 if (args.size() > maxArgs) {
643 maxArgs, maxArgs == 1 ?
"" :
"s", args.size());
647 ParamsTuple typedArgs;
648 std::vector<bool> boundArgs;
649 if (_TryBindArgs(typedArgs, args, namesAndDefaults,
650 std::make_index_sequence<NumBindableArgs> {},
653 std::integral_constant<bool, TakesArbitraryArgs> {},
654 args, boundArgs, typedArgs);
655 return [typedArgs, fn](DomainType
const &obj) {
658 invoke_hpp::apply(fn, std::tuple_cat(
659 std::make_tuple(obj), typedArgs))
666 struct _OverloadBinderBase
668 virtual ~_OverloadBinderBase() =
default;
670 Bind(std::vector<SdfPredicateExpression::FnArg>
const &args)
const {
673 virtual std::unique_ptr<_OverloadBinderBase> Clone()
const = 0;
675 _OverloadBinderBase() =
default;
677 explicit _OverloadBinderBase(NamesAndDefaults
const &namesAndDefaults)
678 : _namesAndDefaults(namesAndDefaults) {}
684 NamesAndDefaults _namesAndDefaults;
688 struct _OverloadBinder : _OverloadBinderBase
690 ~_OverloadBinder()
override =
default;
692 static std::unique_ptr<_OverloadBinder>
693 TryCreate(Fn &&fn, NamesAndDefaults
const &nd) {
694 auto ret = std::unique_ptr<_OverloadBinder>(
695 new _OverloadBinder(std::move(fn), nd));
696 if (!_CheckNamesAndDefaultsWithSignature<Fn>(nd)) {
702 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
703 return std::unique_ptr<
704 _OverloadBinder>(
new _OverloadBinder(*
this));
708 _OverloadBinder(_OverloadBinder
const &) =
default;
710 explicit _OverloadBinder(Fn &&fn,
711 NamesAndDefaults
const &namesAndDefaults)
712 : _OverloadBinderBase(namesAndDefaults)
713 , _fn(std::move(fn)) {}
715 explicit _OverloadBinder(Fn
const &fn,
716 NamesAndDefaults
const &namesAndDefaults)
717 : _OverloadBinder(Fn(fn), namesAndDefaults) {}
724 return _TryToBindCall(_fn, args, this->_namesAndDefaults);
731 struct _CustomBinder : _OverloadBinderBase
733 ~_CustomBinder()
override =
default;
735 static std::unique_ptr<_CustomBinder>
737 return std::unique_ptr<_CustomBinder>(
738 new _CustomBinder(std::move(fn)));
741 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
742 return std::unique_ptr<_CustomBinder>(
new _CustomBinder(*
this));
746 _CustomBinder(_CustomBinder
const &) =
default;
747 explicit _CustomBinder(Fn &&fn)
748 : _OverloadBinderBase()
749 , _fn(std::move(fn)) {}
750 explicit _CustomBinder(Fn
const &fn) : _CustomBinder(Fn(fn)) {}
762 using _OverloadBinderBasePtr = std::unique_ptr<_OverloadBinderBase>;
771 #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.
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 GLchar *const * string
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 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)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
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()
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>.
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.