7#ifndef PXR_USD_SDF_PREDICATE_PROGRAM_H
8#define PXR_USD_SDF_PREDICATE_PROGRAM_H
11#include "pxr/usd/sdf/api.h"
14#include "pxr/base/tf/functionTraits.h"
15#include "pxr/base/vt/value.h"
17#include "pxr/usd/sdf/predicateExpression.h"
18#include "pxr/usd/sdf/predicateLibrary.h"
20#include <initializer_list>
25PXR_NAMESPACE_OPEN_SCOPE
28template <
class DomainType>
32template <
class DomainType>
49template <
class DomainType>
53 using PredicateFunction =
57 SdfLinkPredicateExpression<DomainType>(
62 explicit operator bool()
const {
72 auto funcIter = _funcs.cbegin();
73 auto opIter = _ops.cbegin(), opEnd = _ops.cend();
95 auto shortCircuit = [&]() {
96 const int origNest = nest;
97 for (; opIter != opEnd; ++opIter) {
99 case Call: ++funcIter;
break;
100 case Not:
case And:
case Or:
break;
101 case Open: ++nest;
break;
103 if (--nest == origNest) {
113 for (; opIter != opEnd; ++opIter) {
118 case Not: result = !result;
break;
120 const bool decidingValue = *opIter != And;
123 if (result == decidingValue) {
128 case Open: ++nest;
break;
129 case Close: --nest;
break;
136 enum _Op { Call, Not, Open, Close, And, Or };
137 std::vector<_Op> _ops;
138 std::vector<PredicateFunction> _funcs;
145template <
class DomainType>
158 auto exprToProgramOp = [](Expr::Op op) {
160 case Expr::Call:
return Program::Call;
161 case Expr::Not:
return Program::Not;
162 case Expr::ImpliedAnd:
case Expr::And:
return Program::And;
163 case Expr::Or:
return Program::Or;
165 return static_cast<typename Program::_Op
>(-1);
168 auto translateLogic = [&](Expr::Op op,
int argIndex) {
172 prog._ops.push_back(Program::Not);
175 case Expr::ImpliedAnd:
179 prog._ops.push_back(exprToProgramOp(op));
180 prog._ops.push_back(Program::Open);
182 else if (argIndex == 2) {
183 prog._ops.push_back(Program::Close);
191 auto translateCall = [&](Expr::FnCall
const &call) {
194 if (
auto fn = lib._BindCall(call.funcName, call.args)) {
195 prog._funcs.push_back(std::move(fn));
196 prog._ops.push_back(Program::Call);
202 errs +=
"Failed to bind call of " + call.funcName;
207 expr.
Walk(translateLogic, translateCall);
216PXR_NAMESPACE_CLOSE_SCOPE
Low-level utilities for informing users of various internal and external diagnostic conditions.
Represents a logical expression syntax tree consisting of predicate function calls joined by the logi...
SDF_API void Walk(TfFunctionRef< void(Op, int)> logic, TfFunctionRef< void(FnCall const &)> call) const
Walk this expression's syntax tree in depth-first order, calling call with the current function call ...
Represents the result of a predicate function: a pair of the boolean result and a Constancy token ind...
static SdfPredicateFunctionResult MakeConstant(bool value)
Create with value and 'ConstantOverDescendants'.
void SetAndPropagateConstancy(SdfPredicateFunctionResult other)
Set this result's value to other's value, and propagate constancy; if both this and other are Constan...
Represents a library of predicate functions for use with SdfPredicateExpression.
std::function< SdfPredicateFunctionResult(DomainType const &)> PredicateFunction
The type of a bound function, the result of binding passed arguments.
Represents a callable "program", the result of linking an SdfPredicateExpression with an SdfPredicate...
friend SdfPredicateProgram SdfLinkPredicateExpression(SdfPredicateExpression const &expr, SdfPredicateLibrary< DomainType > const &lib)
Link expr with lib and return a callable program that evaluates expr on given objects of the DomainTy...
SdfPredicateFunctionResult operator()(DomainType const &obj) const
Run the predicate program on obj, and return the result.
#define TF_RUNTIME_ERROR(fmt, args)
Issue a generic runtime error, but continue execution.