24 #ifndef PXR_USD_SDF_PREDICATE_PROGRAM_H
25 #define PXR_USD_SDF_PREDICATE_PROGRAM_H
38 #include <initializer_list>
46 template <
class DomainType>
50 template <
class DomainType>
67 template <
class DomainType>
72 SdfLinkPredicateExpression<DomainType>(
77 explicit operator bool()
const {
86 auto funcIter = _funcs.cbegin();
87 auto opIter = _ops.cbegin(), opEnd = _ops.cend();
92 auto shortCircuit = [&]() {
93 const int origNest = nest;
94 for (; opIter != opEnd; ++opIter) {
96 case Call: ++funcIter;
break;
97 case Not:
case And:
case Or:
break;
98 case Open: ++nest;
break;
100 if (--nest == origNest) {
110 for (; opIter != opEnd; ++opIter) {
112 case Call: result =
static_cast<bool>((*funcIter++)(obj));
break;
113 case Not: result = !
result;
break;
115 const bool decidingValue = *opIter != And;
118 if (result == decidingValue) {
123 case Open: ++nest;
break;
124 case Close: --nest;
break;
131 enum _Op { Call, Not, Open, Close, And, Or };
132 std::vector<_Op> _ops;
133 std::vector<std::function<SdfPredicateFunctionResult (DomainType)>> _funcs;
140 template <
class DomainType>
153 auto exprToProgramOp = [](
Expr::Op op) {
155 case Expr::Call:
return Program::Call;
156 case Expr::Not:
return Program::Not;
157 case Expr::ImpliedAnd:
case Expr::And:
return Program::And;
158 case Expr::Or:
return Program::Or;
160 return static_cast<typename Program::_Op
>(-1);
163 auto translateLogic = [&](
Expr::Op op,
int argIndex) {
167 prog._ops.push_back(Program::Not);
170 case Expr::ImpliedAnd:
174 prog._ops.push_back(exprToProgramOp(op));
175 prog._ops.push_back(Program::Open);
177 else if (argIndex == 2) {
178 prog._ops.push_back(Program::Close);
186 auto translateCall = [&](Expr::FnCall
const &call) {
189 if (
auto fn = lib._BindCall(call.funcName, call.args)) {
190 prog._funcs.push_back(std::move(fn));
191 prog._ops.push_back(Program::Call);
197 errs +=
"Failed to bind call of " + call.funcName;
202 expr.
Walk(translateLogic, translateCall);
213 #endif // PXR_USD_SDF_PREDICATE_PROGRAM_H
SDF_API void Walk(TfFunctionRef< void(Op, int)> logic, TfFunctionRef< void(FnCall const &)> call) const
GLsizei const GLchar *const * string
bool operator()(DomainType obj) const
Run the predicate program on obj, and return the result.
**But if you need a result
SdfPredicateProgram< DomainType > SdfLinkPredicateExpression(SdfPredicateExpression const &expr, SdfPredicateLibrary< DomainType > const &lib)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
#define PXR_NAMESPACE_CLOSE_SCOPE