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) {}
140 #if !defined(doxygen)
146 return _value ? &SdfPredicateFunctionResult::_value :
nullptr;
151 return { !_value, _constancy };
159 _value = other._value;
169 return lhs._value == rhs._value &&
170 lhs._constancy == rhs._constancy;
174 return !(lhs == rhs);
178 return pfr._value == rhs;
181 return lhs == pfr._value;
184 return pfr._value != rhs;
187 return lhs != pfr._value;
195 template <
class DomainType>
199 template <
class DomainType>
203 template <
class DomainType>
213 template <
class DomainType>
217 SdfLinkPredicateExpression<DomainType>(
226 std::function<SdfPredicateFunctionResult (DomainType const &)>;
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());
250 if (
this != &other) {
252 *
this = std::move(copy);
262 return Define(name, std::forward<Fn>(fn), {});
278 if (
auto obinder = _OverloadBinder<std::decay_t<Fn>>
279 ::TryCreate(std::forward<Fn>(fn), namesAndDefaults)) {
280 _binders[
name].push_back(std::move(obinder));
294 auto binder = _CustomBinder<
295 std::decay_t<Fn>>::Create(std::forward<Fn>(fn));
296 _binders[
name].push_back(std::move(binder));
303 _BindCall(std::string
const &
name,
304 std::vector<SdfPredicateExpression::FnArg>
const &
args)
const {
306 auto iter = _binders.
find(name);
307 if (iter == _binders.
end()) {
313 for (
auto i = iter->second.rbegin(),
314 end = iter->second.rend(); i !=
end; ++i) {
315 ret = (*i)->Bind(args);
323 template <
class ParamType>
324 static void _CheckOneNameAndDefault(
325 bool &valid,
size_t index,
size_t numParams,
326 NamesAndDefaults
const &namesAndDefaults) {
330 std::vector<NamesAndDefaults::Param>
const &
331 params = namesAndDefaults.GetParams();
333 size_t nFromEnd = numParams - index - 1;
334 if (nFromEnd >= params.size()) {
339 size_t namesIndex = params.size() - nFromEnd - 1;
341 auto const &
param = params[namesIndex];
342 if (!
param.val.IsEmpty() && !
param.val.CanCast<ParamType>()) {
344 "type '%s' cannot convert to c++ argument of "
345 "type '%s' at index %zu",
347 param.val.GetTypeName().c_str(),
348 ArchGetDemangled<ParamType>().
c_str(),
354 template <
class ParamsTuple,
size_t... I>
356 _CheckNamesAndDefaultsImpl(
357 NamesAndDefaults
const &namesAndDefaults,
358 std::index_sequence<I...>) {
367 (_CheckOneNameAndDefault<std::tuple_element_t<N-I-1, ParamsTuple>>(
368 valid, N-I-1,
N, namesAndDefaults), 0)...
376 _CheckNamesAndDefaultsWithSignature(
377 NamesAndDefaults
const &namesAndDefaults) {
379 if (!namesAndDefaults.CheckValidity()) {
387 std::is_same<
typename Traits::ReturnType,
390 typename Traits::ReturnType,
bool>::
value,
"");
394 using DomainArgType =
typename Traits::template NthArg<0>;
401 std::vector<NamesAndDefaults::Param>
const &
402 params = namesAndDefaults.GetParams();
403 if (params.size() > Traits::Arity-1) {
405 "C++ function arguments (%zu)",
406 params.size(), Traits::Arity-1);
413 if (!params.empty()) {
415 using FullParams =
typename Traits::ArgTypes;
420 return _CheckNamesAndDefaultsImpl<ParamsTuple>(
426 template <
class ParamType>
427 static void _TryBindOne(
428 size_t index,
size_t numParams,
430 bool &boundAllParams,
431 std::vector<SdfPredicateExpression::FnArg>
const &args,
432 std::vector<bool> &boundArgs,
433 NamesAndDefaults
const &namesAndDefaults) {
444 if (!boundAllParams) {
450 std::vector<NamesAndDefaults::Param>
const &
451 params = namesAndDefaults.GetParams();
452 size_t numUnnamed = params.size() - numParams;
454 if (index >= numUnnamed) {
455 paramNameAndDefault = ¶ms[index - numUnnamed];
462 (index < args.size() && args[
index].argName.empty()) ?
463 &args[index] :
nullptr;
465 auto tryBind = [&](
VtValue const &
val,
size_t argIndex) {
469 boundArgs[argIndex] =
true;
472 boundAllParams =
false;
476 if (!paramNameAndDefault) {
478 if (!posArg || !posArg->argName.empty()) {
479 boundAllParams =
false;
483 tryBind(posArg->value, index);
488 tryBind(posArg->value, index);
494 for (
size_t i = 0,
end = args.size(); i !=
end; ++i) {
499 if (args[i].argName == paramNameAndDefault->name) {
501 tryBind(args[i].
value, i);
507 VtValue cast = VtValue::Cast<ParamType>(paramNameAndDefault->val);
513 boundAllParams =
false;
517 template <
class ParamsTuple,
size_t... I>
519 _TryBindArgs(ParamsTuple ¶ms,
520 std::vector<SdfPredicateExpression::FnArg>
const &args,
521 NamesAndDefaults
const &namesAndDefaults,
522 std::index_sequence<I...>,
523 std::vector<bool> &boundArgs) {
528 boundArgs.assign(args.size(),
false);
534 std::get<I>(params), bound,
535 args, boundArgs, namesAndDefaults), 0)...
541 template <
class Tuple>
543 _FillArbitraryArgs(std::true_type,
544 std::vector<SdfPredicateExpression::FnArg>
const &args,
545 std::vector<bool>
const &boundArgs,
547 std::vector<SdfPredicateExpression::FnArg> &
rest =
553 for (
size_t i = 0; i != args.size(); ++i) {
555 rest.push_back(args[i]);
562 _FillArbitraryArgs(std::false_type,
563 std::vector<SdfPredicateExpression::FnArg>
const &,
564 std::vector<bool>
const &,
569 template <
class ParamsTuple>
570 static constexpr
bool
571 _TakesArbitraryArgs(std::true_type) {
575 std::vector<SdfPredicateExpression::FnArg>
579 template <
class ParamsTuple>
580 static constexpr
bool
581 _TakesArbitraryArgs(std::false_type) {
587 _TryToBindCall(Fn
const &fn,
588 std::vector<SdfPredicateExpression::FnArg>
const &args,
589 NamesAndDefaults
const &namesAndDefaults) {
596 using FullParams =
typename Traits::ArgTypes;
605 static const bool TakesArbitraryArgs =
606 _TakesArbitraryArgs<ParamsTuple>(
607 std::integral_constant<bool, Traits::Arity >= 2> {});
609 size_t minArgs = Traits::Arity-1 - namesAndDefaults.GetNumDefaults();
610 size_t maxArgs = TakesArbitraryArgs ? size_t(-1) : Traits::Arity-1;
614 static const size_t NumBindableArgs =
615 Traits::Arity - (TakesArbitraryArgs ? 2 : 1);
617 if (args.size() < minArgs) {
619 "%zu given", minArgs, minArgs == 1 ?
"" :
"s",
623 if (args.size() > maxArgs) {
625 maxArgs, maxArgs == 1 ?
"" :
"s", args.size());
629 ParamsTuple typedArgs;
630 std::vector<bool> boundArgs;
631 if (_TryBindArgs(typedArgs, args, namesAndDefaults,
632 std::make_index_sequence<NumBindableArgs> {},
635 std::integral_constant<bool, TakesArbitraryArgs> {},
636 args, boundArgs, typedArgs);
637 return [typedArgs, fn](DomainType
const &obj) {
640 std::tuple_cat(std::make_tuple(obj), typedArgs))
647 struct _OverloadBinderBase
649 virtual ~_OverloadBinderBase() =
default;
651 Bind(std::vector<SdfPredicateExpression::FnArg>
const &args)
const {
654 virtual std::unique_ptr<_OverloadBinderBase> Clone()
const = 0;
656 _OverloadBinderBase() =
default;
658 explicit _OverloadBinderBase(NamesAndDefaults
const &namesAndDefaults)
659 : _namesAndDefaults(namesAndDefaults) {}
665 NamesAndDefaults _namesAndDefaults;
669 struct _OverloadBinder : _OverloadBinderBase
671 ~_OverloadBinder()
override =
default;
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)) {
683 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
684 return std::unique_ptr<
685 _OverloadBinder>(
new _OverloadBinder(*
this));
689 _OverloadBinder(_OverloadBinder
const &) =
default;
691 explicit _OverloadBinder(Fn &&fn,
692 NamesAndDefaults
const &namesAndDefaults)
693 : _OverloadBinderBase(namesAndDefaults)
694 , _fn(std::move(fn)) {}
696 explicit _OverloadBinder(Fn
const &fn,
697 NamesAndDefaults
const &namesAndDefaults)
698 : _OverloadBinder(Fn(fn), namesAndDefaults) {}
705 return _TryToBindCall(_fn, args, this->_namesAndDefaults);
712 struct _CustomBinder : _OverloadBinderBase
714 ~_CustomBinder()
override =
default;
716 static std::unique_ptr<_CustomBinder>
718 return std::unique_ptr<_CustomBinder>(
719 new _CustomBinder(std::move(fn)));
722 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
723 return std::unique_ptr<_CustomBinder>(
new _CustomBinder(*
this));
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)) {}
743 using _OverloadBinderBasePtr = std::unique_ptr<_OverloadBinderBase>;
746 std::string, std::vector<_OverloadBinderBasePtr>
752 #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 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()
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>.
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.