93 #include <type_traits> 
  100 struct ram_visitor_tag {};
 
  111 template <
typename R = void, 
typename... Params>
 
  118         return visit(node, args...);
 
  123         return visit(*node, args...);
 
  137     virtual R 
visit(
const Node& node, Params... args) {
 
  140 #define FORWARD(Kind) \ 
  141     if (const auto* n = dynamic_cast<const Kind*>(&node)) return visit##Kind(*n, args...); 
  213         fatal(
"unsupported type: %s", 
typeid(node).name());
 
  216     virtual R 
visit(
const Node* node, Params... args) {
 
  217         return visit(*node, args...);
 
  221 #define LINK(Node, Parent)                                 \ 
  222     virtual R visit##Node(const Node& n, Params... args) { \ 
  223         return visit##Parent(n, args...);                  \ 
  229     LINK(Clear, RelationStatement);
 
  230     LINK(LogSize, RelationStatement);
 
  232     LINK(RelationStatement, Statement);
 
  234     LINK(Swap, BinRelationStatement);
 
  235     LINK(Extend, BinRelationStatement);
 
  236     LINK(BinRelationStatement, Statement);
 
  238     LINK(Sequence, ListStatement);
 
  239     LINK(Loop, Statement);
 
  240     LINK(Parallel, ListStatement);
 
  241     LINK(ListStatement, Statement);
 
  242     LINK(Exit, Statement);
 
  243     LINK(LogTimer, Statement);
 
  244     LINK(LogRelationTimer, Statement);
 
  245     LINK(DebugInfo, Statement);
 
  246     LINK(Call, Statement);
 
  248     LINK(Statement, Node);
 
  251     LINK(Project, Operation);
 
  252     LINK(SubroutineReturn, Operation);
 
  253     LINK(UnpackRecord, TupleOperation);
 
  254     LINK(NestedIntrinsicOperator, TupleOperation)
 
  255     LINK(Scan, RelationOperation);
 
  256     LINK(ParallelScan, Scan);
 
  257     LINK(IndexScan, IndexOperation);
 
  258     LINK(ParallelIndexScan, IndexScan);
 
  259     LINK(Choice, RelationOperation);
 
  260     LINK(ParallelChoice, Choice);
 
  261     LINK(IndexChoice, IndexOperation);
 
  262     LINK(ParallelIndexChoice, IndexChoice);
 
  263     LINK(RelationOperation, TupleOperation);
 
  264     LINK(Aggregate, RelationOperation);
 
  265     LINK(ParallelAggregate, Aggregate);
 
  266     LINK(IndexAggregate, IndexOperation);
 
  267     LINK(ParallelIndexAggregate, IndexAggregate);
 
  268     LINK(IndexOperation, RelationOperation);
 
  269     LINK(TupleOperation, NestedOperation);
 
  270     LINK(Filter, AbstractConditional);
 
  271     LINK(Break, AbstractConditional);
 
  272     LINK(AbstractConditional, NestedOperation);
 
  273     LINK(NestedOperation, Operation);
 
  275     LINK(Operation, Node);
 
  278     LINK(True, Condition);
 
  279     LINK(False, Condition);
 
  280     LINK(Conjunction, Condition);
 
  281     LINK(Negation, Condition);
 
  282     LINK(Constraint, Condition);
 
  283     LINK(ProvenanceExistenceCheck, AbstractExistenceCheck);
 
  284     LINK(ExistenceCheck, AbstractExistenceCheck);
 
  285     LINK(EmptinessCheck, Condition);
 
  286     LINK(AbstractExistenceCheck, Condition);
 
  288     LINK(Condition, Node);
 
  291     LINK(SignedConstant, Constant);
 
  292     LINK(UnsignedConstant, Constant);
 
  293     LINK(FloatConstant, Constant);
 
  294     LINK(Constant, Expression);
 
  295     LINK(UndefValue, Expression);
 
  296     LINK(TupleElement, Expression);
 
  297     LINK(IntrinsicOperator, AbstractOperator);
 
  298     LINK(UserDefinedOperator, AbstractOperator);
 
  299     LINK(AbstractOperator, Expression);
 
  300     LINK(AutoIncrement, Expression);
 
  301     LINK(PackRecord, Expression);
 
  302     LINK(SubroutineArgument, Expression);
 
  303     LINK(RelationSize, Expression);
 
  305     LINK(Expression, Node);
 
  311     LINK(Relation, Node);
 
  316     virtual R 
visitNode(
const Node& , Params... ) {
 
  330 template <
typename R, 
typename... Ps, 
typename... Args>
 
  332     visitor(root, args...);
 
  334         if (cur != 
nullptr) {
 
  349 template <
typename R, 
typename... Ps, 
typename... Args>
 
  350 void visitDepthFirst(
const Node& root, Visitor<R, Ps...>& visitor, Args&... args) {
 
  360 template <
typename R, 
typename N>
 
  362     std::function<R(
const N&)> 
lambda;
 
  365         if (
const auto* 
n = 
dynamic_cast<const N*
>(&node)) {
 
  374 template <
typename R, 
typename N>
 
  382 template <
typename T>
 
  384     static constexpr 
size_t value = std::is_base_of<ram_visitor_tag, T>::value;
 
  387 template <
typename T>
 
  388 struct is_ram_visitor<const T> : 
public is_ram_visitor<T> {};
 
  390 template <
typename T>
 
  403 template <
typename R, 
typename N>
 
  406     visitDepthFirst<void>(root, visitor);
 
  418 template <typename Lambda, typename R = typename lambda_traits<Lambda>::result_type,
 
  421         const Node& root, 
const Lambda& fun) {