24 #ifndef PXR_USD_SDF_PREDICATE_LIBRARY_H
25 #define PXR_USD_SDF_PREDICATE_LIBRARY_H
38 #include <initializer_list>
63 : name(name),
val(std::forward<Val>(defVal)) {}
71 std::initializer_list<Param>
const &
params) :
72 _params(params.
begin(), params.
end()) {}
88 return std::move(_params);
92 std::vector<Param> _params;
108 : _value(false), _constancy(
MayVary) {}
113 : _value(value), _constancy(constancy) {}
126 explicit operator bool()
const {
136 template <
class DomainType>
140 template <
class DomainType>
144 template <
class DomainType>
154 template <
class DomainType>
158 SdfLinkPredicateExpression<DomainType>(
172 for (
auto iter = other._binders.
begin(),
end = other._binders.
end();
173 iter !=
end; ++iter) {
174 auto &theseBinders = _binders[iter->first];
175 for (
auto const &otherBinder: iter->second) {
176 theseBinders.push_back(otherBinder->Clone());
186 if (
this != &other) {
188 *
this = std::move(copy);
198 return Define(name, std::forward<Fn>(fn), {});
214 if (
auto obinder = _OverloadBinder<std::decay_t<Fn>>
215 ::TryCreate(std::forward<Fn>(fn), namesAndDefaults)) {
216 _binders[
name].push_back(std::move(obinder));
223 std::function<SdfPredicateFunctionResult (DomainType)>
225 std::vector<SdfPredicateExpression::FnArg>
const &
args)
const {
226 std::function<SdfPredicateFunctionResult (DomainType)> ret;
227 auto iter = _binders.
find(name);
228 if (iter == _binders.
end()) {
234 for (
auto i = iter->second.rbegin(),
235 end = iter->second.rend(); i !=
end; ++i) {
236 ret = (*i)->Bind(args);
244 template <
class ParamType>
245 static void _CheckOneNameAndDefault(
246 bool &valid,
size_t index,
size_t numParams,
247 NamesAndDefaults
const &namesAndDefaults) {
251 std::vector<NamesAndDefaults::Param>
const &
252 params = namesAndDefaults.GetParams();
254 size_t nFromEnd = numParams - index - 1;
255 if (nFromEnd >= params.size()) {
260 size_t namesIndex = params.size() - nFromEnd - 1;
262 auto const &
param = params[namesIndex];
263 if (!
param.val.IsEmpty() && !
param.val.CanCast<ParamType>()) {
265 "type '%s' cannot convert to c++ argument of "
266 "type '%s' at index %zu",
268 param.val.GetTypeName().c_str(),
269 ArchGetDemangled<ParamType>().c_str(),
275 template <
class ParamsTuple,
size_t... I>
277 _CheckNamesAndDefaultsImpl(
278 NamesAndDefaults
const &namesAndDefaults,
279 std::index_sequence<I...>) {
288 (_CheckOneNameAndDefault<std::tuple_element_t<N-I-1, ParamsTuple>>(
289 valid, N-I-1,
N, namesAndDefaults), 0)...
297 _CheckNamesAndDefaultsWithSignature(
298 NamesAndDefaults
const &namesAndDefaults) {
300 if (!namesAndDefaults.CheckValidity()) {
307 static_assert(std::is_convertible<
308 typename Traits::ReturnType,
bool>::
value,
"");
312 using DomainArgType =
typename Traits::template NthArg<0>;
319 std::vector<NamesAndDefaults::Param>
const &
320 params = namesAndDefaults.GetParams();
321 if (params.size() > Traits::Arity-1) {
323 "C++ function arguments (%zu)",
324 params.size(), Traits::Arity-1);
331 if (!params.empty()) {
333 using FullParams =
typename Traits::ArgTypes;
338 return _CheckNamesAndDefaultsImpl<ParamsTuple>(
344 template <
class ParamType>
345 static void _TryBindOne(
346 size_t index,
size_t numParams,
348 bool &boundAllParams,
349 std::vector<SdfPredicateExpression::FnArg>
const &args,
350 std::vector<bool> &boundArgs,
351 NamesAndDefaults
const &namesAndDefaults) {
362 if (!boundAllParams) {
368 std::vector<NamesAndDefaults::Param>
const &
369 params = namesAndDefaults.GetParams();
370 size_t numUnnamed = params.size() - numParams;
372 if (index >= numUnnamed) {
373 paramNameAndDefault = ¶ms[index - numUnnamed];
380 (index < args.size() && args[
index].argName.empty()) ?
381 &args[index] :
nullptr;
383 auto tryBind = [&](
VtValue const &
val,
size_t argIndex) {
387 boundArgs[argIndex] =
true;
390 boundAllParams =
false;
394 if (!paramNameAndDefault) {
396 if (!posArg || !posArg->argName.empty()) {
397 boundAllParams =
false;
401 tryBind(posArg->value, index);
406 tryBind(posArg->value, index);
412 for (
size_t i = 0,
end = args.size(); i !=
end; ++i) {
417 if (args[i].argName == paramNameAndDefault->name) {
419 tryBind(args[i].
value, i);
425 VtValue cast = VtValue::Cast<ParamType>(paramNameAndDefault->val);
431 boundAllParams =
false;
435 template <
class ParamsTuple,
size_t... I>
437 _TryBindArgs(ParamsTuple ¶ms,
438 std::vector<SdfPredicateExpression::FnArg>
const &args,
439 NamesAndDefaults
const &namesAndDefaults,
440 std::index_sequence<I...>) {
446 std::vector<bool> boundArgs(N);
451 (_TryBindOne(I, N, std::get<I>(params), bound,
452 args, boundArgs, namesAndDefaults), 0)...
459 static std::function<SdfPredicateFunctionResult (DomainType)>
460 _TryToBindCall(Fn
const &fn,
461 std::vector<SdfPredicateExpression::FnArg>
const &args,
462 NamesAndDefaults
const &namesAndDefaults) {
469 using FullParams =
typename Traits::ArgTypes;
474 if (args.size() > Traits::Arity-1) {
476 Traits::Arity-1, Traits::Arity-1 == 1 ?
"" :
"s",
481 ParamsTuple typedArgs;
482 if (_TryBindArgs(typedArgs, args, namesAndDefaults,
483 std::make_index_sequence<Traits::Arity-1> {})) {
484 return [typedArgs, fn](DomainType obj) {
487 invoke_hpp::apply(fn, std::tuple_cat(
488 std::make_tuple(obj), typedArgs))
495 struct _OverloadBinderBase
497 virtual ~_OverloadBinderBase() =
default;
498 std::function<SdfPredicateFunctionResult (DomainType)>
499 Bind(std::vector<SdfPredicateExpression::FnArg>
const &args)
const {
502 virtual std::unique_ptr<_OverloadBinderBase> Clone()
const = 0;
504 explicit _OverloadBinderBase(NamesAndDefaults
const &namesAndDefaults)
505 : _namesAndDefaults(namesAndDefaults) {}
507 virtual std::function<SdfPredicateFunctionResult (DomainType)>
511 NamesAndDefaults _namesAndDefaults;
515 struct _OverloadBinder : _OverloadBinderBase
517 ~_OverloadBinder()
override =
default;
519 static std::unique_ptr<_OverloadBinder>
520 TryCreate(Fn &&fn, NamesAndDefaults
const &nd) {
521 auto ret = std::unique_ptr<_OverloadBinder>(
522 new _OverloadBinder(fn, nd));
523 if (!_CheckNamesAndDefaultsWithSignature<Fn>(nd)) {
529 std::unique_ptr<_OverloadBinderBase> Clone()
const override {
530 return std::unique_ptr<
531 _OverloadBinder>(
new _OverloadBinder(*
this));
535 _OverloadBinder(_OverloadBinder
const &) =
default;
537 explicit _OverloadBinder(Fn &&fn,
538 NamesAndDefaults
const &namesAndDefaults)
539 : _OverloadBinderBase(namesAndDefaults)
540 , _fn(std::move(fn)) {}
542 explicit _OverloadBinder(Fn
const &fn,
543 NamesAndDefaults
const &namesAndDefaults)
544 : _OverloadBinder(Fn(fn), namesAndDefaults) {}
546 std::function<SdfPredicateFunctionResult (DomainType)>
551 return _TryToBindCall(_fn, args, this->_namesAndDefaults);
557 using _OverloadBinderBasePtr = std::unique_ptr<_OverloadBinderBase>;
566 #endif // PXR_USD_SDF_PREDICATE_EXPRESSION_EVAL_H
std::vector< Param > GetParams() const &&
Move-return the parameters in a vector.
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 IsEmpty() const
Returns true iff this value is empty.
GLenum const GLfloat * params
std::decay_t< decltype(make_index_sequence_impl< N >())> make_index_sequence
SdfPredicateFunctionResult(bool value, Constancy constancy=MayVary)
Construct with value and constancy.
iterator find(const Key &key)
Constancy GetConstancy() const
Return the result constancy.
GLuint const GLchar * name
SdfPredicateLibrary & operator=(SdfPredicateLibrary const &other)
Copy-assignment from an other library.
SdfPredicateLibrary(SdfPredicateLibrary const &other)
Copy-construct from an other library.
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()
Default construction produces a 'false' result that 'MayVary'.
SdfPredicateLibrary & operator=(SdfPredicateLibrary &&other)=default
Move-assignment from an other library.
SdfPredicateLibrary & Define(std::string const &name, Fn &&fn, NamesAndDefaults const &namesAndDefaults)
typename Tf_GetFuncSig< Fn >::Type TfFunctionTraits
iterator begin() noexcept
SdfPredicateLibrary()=default
Default constructor produces an empty library.
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.