Add PreVisit method to utils::Visitor

Reviewers: florijan, mislav.bradac

Reviewed By: mislav.bradac

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D242
This commit is contained in:
Teon Banek 2017-04-06 16:17:17 +02:00
parent e8fd479bbc
commit 7d0958b1a4
4 changed files with 306 additions and 188 deletions

View File

@ -64,12 +64,14 @@ class OrOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
// TODO: Should we short-circuit?
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -80,11 +82,13 @@ class XorOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -95,12 +99,14 @@ class AndOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
// TODO: Should we short-circuit?
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -111,11 +117,13 @@ class AdditionOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -126,11 +134,13 @@ class SubtractionOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -141,11 +151,13 @@ class MultiplicationOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -156,11 +168,13 @@ class DivisionOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -171,11 +185,13 @@ class ModOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -186,11 +202,13 @@ class NotEqualOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -201,11 +219,13 @@ class EqualOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -216,11 +236,13 @@ class LessOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -231,11 +253,13 @@ class GreaterOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -246,11 +270,13 @@ class LessEqualOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -261,11 +287,13 @@ class GreaterEqualOperator : public BinaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression1_->Accept(visitor);
expression2_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using BinaryOperator::BinaryOperator;
@ -276,10 +304,12 @@ class NotOperator : public UnaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using UnaryOperator::UnaryOperator;
@ -290,10 +320,12 @@ class UnaryPlusOperator : public UnaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using UnaryOperator::UnaryOperator;
@ -304,10 +336,12 @@ class UnaryMinusOperator : public UnaryOperator {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
using UnaryOperator::UnaryOperator;
@ -342,10 +376,12 @@ class PropertyLookup : public Expression {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
Expression *expression_ = nullptr;
GraphDbTypes::Property property_ = nullptr;
@ -371,10 +407,12 @@ class Aggregation : public UnaryOperator {
Op op_;
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
protected:
Aggregation(int uid, Expression *expression, Op op)
@ -386,10 +424,12 @@ class NamedExpression : public Tree {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::string name_;
Expression *expression_ = nullptr;
@ -418,10 +458,12 @@ class NodeAtom : public PatternAtom {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
identifier_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::vector<GraphDbTypes::Label> labels_;
// TODO: change to unordered_map
@ -441,10 +483,12 @@ class EdgeAtom : public PatternAtom {
enum class Direction { LEFT, RIGHT, BOTH };
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
identifier_->Accept(visitor);
visitor.PostVisit(*this);
}
}
Direction direction_ = Direction::BOTH;
std::vector<GraphDbTypes::EdgeType> edge_types_;
@ -469,12 +513,14 @@ class Pattern : public Tree {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &part : atoms_) {
part->Accept(visitor);
}
visitor.PostVisit(*this);
}
}
Identifier *identifier_ = nullptr;
std::vector<PatternAtom *> atoms_;
@ -487,12 +533,14 @@ class Query : public Tree {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &clause : clauses_) {
clause->Accept(visitor);
}
visitor.PostVisit(*this);
}
}
std::vector<Clause *> clauses_;
protected:
@ -506,12 +554,14 @@ class Create : public Clause {
Create(int uid) : Clause(uid) {}
std::vector<Pattern *> patterns_;
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &pattern : patterns_) {
pattern->Accept(visitor);
}
visitor.PostVisit(*this);
}
}
};
class Where : public Tree {
@ -519,10 +569,12 @@ class Where : public Tree {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
Expression *expression_ = nullptr;
protected:
@ -535,6 +587,7 @@ class Match : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &pattern : patterns_) {
pattern->Accept(visitor);
@ -544,6 +597,7 @@ class Match : public Clause {
}
visitor.PostVisit(*this);
}
}
std::vector<Pattern *> patterns_;
Where *where_ = nullptr;
@ -556,12 +610,14 @@ class Return : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &expr : named_expressions_) {
expr->Accept(visitor);
}
visitor.PostVisit(*this);
}
}
std::vector<NamedExpression *> named_expressions_;
protected:
@ -573,6 +629,7 @@ class With : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &expr : named_expressions_) {
expr->Accept(visitor);
@ -580,6 +637,7 @@ class With : public Clause {
if (where_) where_->Accept(visitor);
visitor.PostVisit(*this);
}
}
bool distinct_ = false;
std::vector<NamedExpression *> named_expressions_;
@ -594,12 +652,14 @@ class Delete : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
for (auto &expr : expressions_) {
expr->Accept(visitor);
}
visitor.PostVisit(*this);
}
}
std::vector<Expression *> expressions_;
bool detach_ = false;
@ -612,11 +672,13 @@ class SetProperty : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
property_lookup_->Accept(visitor);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
PropertyLookup *property_lookup_ = nullptr;
Expression *expression_ = nullptr;
@ -633,11 +695,13 @@ class SetProperties : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
identifier_->Accept(visitor);
expression_->Accept(visitor);
visitor.PostVisit(*this);
}
}
Identifier *identifier_ = nullptr;
Expression *expression_ = nullptr;
bool update_ = false;
@ -657,10 +721,12 @@ class SetLabels : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
identifier_->Accept(visitor);
visitor.PostVisit(*this);
}
}
Identifier *identifier_ = nullptr;
std::vector<GraphDbTypes::Label> labels_;
@ -676,10 +742,12 @@ class RemoveProperty : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
property_lookup_->Accept(visitor);
visitor.PostVisit(*this);
}
}
PropertyLookup *property_lookup_ = nullptr;
protected:
@ -693,10 +761,12 @@ class RemoveLabels : public Clause {
public:
void Accept(TreeVisitorBase &visitor) override {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
identifier_->Accept(visitor);
visitor.PostVisit(*this);
}
}
Identifier *identifier_ = nullptr;
std::vector<GraphDbTypes::Label> labels_;

View File

@ -12,9 +12,11 @@ CreateNode::CreateNode(NodeAtom *node_atom,
: node_atom_(node_atom), input_(input) {}
void CreateNode::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
if (input_) input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> CreateNode::MakeCursor(GraphDbAccessor &db) {
@ -69,9 +71,11 @@ CreateExpand::CreateExpand(NodeAtom *node_atom, EdgeAtom *edge_atom,
node_existing_(node_existing) {}
void CreateExpand::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> CreateExpand::MakeCursor(GraphDbAccessor &db) {
@ -155,9 +159,11 @@ ScanAll::ScanAll(NodeAtom *node_atom, std::shared_ptr<LogicalOperator> input)
: node_atom_(node_atom), input_(input) {}
void ScanAll::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
if (input_) input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> ScanAll::MakeCursor(GraphDbAccessor &db) {
@ -202,9 +208,11 @@ Expand::Expand(NodeAtom *node_atom, EdgeAtom *edge_atom,
edge_cycle_(edge_cycle) {}
void Expand::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> Expand::MakeCursor(GraphDbAccessor &db) {
@ -323,9 +331,11 @@ NodeFilter::NodeFilter(std::shared_ptr<LogicalOperator> input,
: input_(input), input_symbol_(input_symbol), node_atom_(node_atom) {}
void NodeFilter::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> NodeFilter::MakeCursor(GraphDbAccessor &db) {
@ -373,9 +383,11 @@ EdgeFilter::EdgeFilter(std::shared_ptr<LogicalOperator> input,
: input_(input), input_symbol_(input_symbol), edge_atom_(edge_atom) {}
void EdgeFilter::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> EdgeFilter::MakeCursor(GraphDbAccessor &db) {
@ -426,9 +438,11 @@ Filter::Filter(const std::shared_ptr<LogicalOperator> &input_,
: input_(input_), expression_(expression_) {}
void Filter::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> Filter::MakeCursor(GraphDbAccessor &db) {
@ -458,9 +472,11 @@ Produce::Produce(std::shared_ptr<LogicalOperator> input,
: input_(input), named_expressions_(named_expressions) {}
void Produce::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
if (input_) input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> Produce::MakeCursor(GraphDbAccessor &db) {
@ -499,9 +515,11 @@ Delete::Delete(const std::shared_ptr<LogicalOperator> &input_,
: input_(input_), expressions_(expressions), detach_(detach_) {}
void Delete::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> Delete::MakeCursor(GraphDbAccessor &db) {
@ -550,9 +568,11 @@ SetProperty::SetProperty(const std::shared_ptr<LogicalOperator> input,
: input_(input), lhs_(lhs), rhs_(rhs) {}
void SetProperty::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> SetProperty::MakeCursor(GraphDbAccessor &db) {
@ -599,9 +619,11 @@ SetProperties::SetProperties(const std::shared_ptr<LogicalOperator> input,
: input_(input), input_symbol_(input_symbol), rhs_(rhs), op_(op) {}
void SetProperties::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> SetProperties::MakeCursor(GraphDbAccessor &db) {
@ -682,9 +704,11 @@ SetLabels::SetLabels(const std::shared_ptr<LogicalOperator> input,
: input_(input), input_symbol_(input_symbol), labels_(labels) {}
void SetLabels::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> SetLabels::MakeCursor(GraphDbAccessor &db) {
@ -711,9 +735,11 @@ RemoveProperty::RemoveProperty(const std::shared_ptr<LogicalOperator> input,
: input_(input), lhs_(lhs) {}
void RemoveProperty::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> RemoveProperty::MakeCursor(GraphDbAccessor &db) {
@ -756,9 +782,11 @@ RemoveLabels::RemoveLabels(const std::shared_ptr<LogicalOperator> input,
: input_(input), input_symbol_(input_symbol), labels_(labels) {}
void RemoveLabels::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> RemoveLabels::MakeCursor(GraphDbAccessor &db) {
@ -792,9 +820,11 @@ ExpandUniquenessFilter<TAccessor>::ExpandUniquenessFilter(
template <typename TAccessor>
void ExpandUniquenessFilter<TAccessor>::Accept(
LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
template <typename TAccessor>
@ -867,9 +897,11 @@ Accumulate::Accumulate(std::shared_ptr<LogicalOperator> input,
: input_(input), symbols_(symbols), advance_command_(advance_command) {}
void Accumulate::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> Accumulate::MakeCursor(GraphDbAccessor &db) {
return std::make_unique<Accumulate::AccumulateCursor>(*this, db);
@ -911,9 +943,11 @@ Aggregate::Aggregate(const std::shared_ptr<LogicalOperator> &input,
: input_(input), aggregations_(aggregations), group_by_(group_by) {}
void Aggregate::Accept(LogicalOperatorVisitor &visitor) {
if (visitor.PreVisit(*this)) {
visitor.Visit(*this);
input_->Accept(visitor);
visitor.PostVisit(*this);
}
}
std::unique_ptr<Cursor> Aggregate::MakeCursor(GraphDbAccessor &db) {

View File

@ -18,6 +18,11 @@ namespace utils {
/// public:
/// void Accept(ExpressionVisitor &visitor) override {
/// // Implement custom Accept.
/// if (visitor.PreVisit(*this)) {
/// visitor.Visit(*this);
/// ... // e.g. send visitor to children
/// visitor.PostVisit(*this);
/// }
/// }
/// };
///
@ -34,8 +39,10 @@ class Visitable {
/// @sa utils::Visitable
#define DEFVISITABLE(TVisitor) \
void Accept(TVisitor &visitor) override { \
if (visitor.PreVisit(*this)) { \
visitor.Visit(*this); \
visitor.PostVisit(*this); \
} \
}
};

View File

@ -11,6 +11,7 @@ class VisitorBase {
public:
virtual ~VisitorBase() = default;
virtual bool PreVisit(T &) { return true; }
virtual void Visit(T &) {}
virtual void PostVisit(T &) {}
};
@ -22,9 +23,11 @@ template <typename Head, typename... Tail>
class RecursiveVisitorBase<Head, Tail...>
: public VisitorBase<Head>, public RecursiveVisitorBase<Tail...> {
public:
using VisitorBase<Head>::PreVisit;
using VisitorBase<Head>::Visit;
using VisitorBase<Head>::PostVisit;
using RecursiveVisitorBase<Tail...>::PreVisit;
using RecursiveVisitorBase<Tail...>::Visit;
using RecursiveVisitorBase<Tail...>::PostVisit;
};
@ -32,19 +35,22 @@ class RecursiveVisitorBase<Head, Tail...>
template <typename T>
class RecursiveVisitorBase<T> : public VisitorBase<T> {
public:
using VisitorBase<T>::PreVisit;
using VisitorBase<T>::Visit;
using VisitorBase<T>::PostVisit;
};
} // namespace detail
/// Inherit from this class if you want to visit TVisitable types.
/// @brief Inherit from this class if you want to visit TVisitable types.
///
/// Example usage:
///
/// // Typedef for convenience or to establish a base class of visitors.
/// typedef Visitor<Identifier, Literal> ExpressionVisitorBase;
/// class ExpressionVisitor : public ExpressionVisitorBase {
/// public:
/// using ExpressionVisitorBase::PreVisit;
/// using ExpressionVisitorBase::Visit;
/// using ExpressionVisitorBase::PostVisit;
///
@ -57,6 +63,7 @@ class RecursiveVisitorBase<T> : public VisitorBase<T> {
template <typename... TVisitable>
class Visitor : public detail::RecursiveVisitorBase<TVisitable...> {
public:
using detail::RecursiveVisitorBase<TVisitable...>::PreVisit;
using detail::RecursiveVisitorBase<TVisitable...>::Visit;
using detail::RecursiveVisitorBase<TVisitable...>::PostVisit;
};