diff --git a/src/utils/visitor/visitable.hpp b/src/utils/visitor/visitable.hpp index 6c86b1ee3..bca5a40ee 100644 --- a/src/utils/visitor/visitable.hpp +++ b/src/utils/visitor/visitable.hpp @@ -1,33 +1,42 @@ +/// @file visitable.hpp + #pragma once namespace utils { -// Inherit from this class to allow visiting from TVisitor class. -// Example usage: -// class Expression : public Visitable { -// }; -// class Identifier : public ExpressionVisitor { -// public: -// DEFVISITABLE(ExpressionVisitor) // Use default Accept implementation -// .... -// }; -// class Literal : public Expression { -// public: -// void Accept(ExpressionVisitor &visitor) override { -// // Implement custom Accept. -// } -// }; +/// Inherit from this class to allow visiting from TVisitor class. +/// Example usage: +/// +/// class Expression : public Visitable { +/// }; +/// class Identifier : public ExpressionVisitor { +/// public: +/// DEFVISITABLE(ExpressionVisitor) // Use default Accept implementation +/// .... +/// }; +/// class Literal : public Expression { +/// public: +/// void Accept(ExpressionVisitor &visitor) override { +/// // Implement custom Accept. +/// } +/// }; +/// +/// @sa DEFVISITABLE +/// @sa Visitor template class Visitable { public: virtual ~Visitable() = default; - virtual void Accept(TVisitor&) = 0; - -#define DEFVISITABLE(TVisitor) \ - void Accept(TVisitor &visitor) override \ - { visitor.Visit(*this); visitor.PostVisit(*this); } - + virtual void Accept(TVisitor &) = 0; +/// Default implementation for @c Accept, which works for visitors of +/// @c TVisitor type. +/// @sa utils::Visitable +#define DEFVISITABLE(TVisitor) \ + void Accept(TVisitor &visitor) override { \ + visitor.Visit(*this); \ + visitor.PostVisit(*this); \ + } }; -} +} // namespace utils diff --git a/src/utils/visitor/visitor.hpp b/src/utils/visitor/visitor.hpp index e449ba262..f838f23bd 100644 --- a/src/utils/visitor/visitor.hpp +++ b/src/utils/visitor/visitor.hpp @@ -1,22 +1,26 @@ #pragma once -namespace { +namespace utils { + +// Don't use anonymous namespace, because each translation unit will then get a +// unique type. This may cause errors if one wants to check the type. +namespace detail { template class VisitorBase { public: virtual ~VisitorBase() = default; - virtual void Visit(T&) {} - virtual void PostVisit(T&) {} + virtual void Visit(T &) {} + virtual void PostVisit(T &) {} }; template class RecursiveVisitorBase; template -class RecursiveVisitorBase : public VisitorBase, - public RecursiveVisitorBase { +class RecursiveVisitorBase + : public VisitorBase, public RecursiveVisitorBase { public: using VisitorBase::Visit; using VisitorBase::PostVisit; @@ -32,28 +36,29 @@ class RecursiveVisitorBase : public VisitorBase { using VisitorBase::PostVisit; }; -} +} // namespace detail -namespace utils { - -// 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 ExpressionVisitorBase; -// class ExpressionVisitor : public ExpressionVisitorBase { -// public: -// using ExpressionVisitorBase::Visit; -// using ExpressionVisitorBase::PostVisit; -// -// void Visit(Identifier &identifier) override { -// // Custom implementation of visiting Identifier. -// } -// }; +/// 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 ExpressionVisitorBase; +/// class ExpressionVisitor : public ExpressionVisitorBase { +/// public: +/// using ExpressionVisitorBase::Visit; +/// using ExpressionVisitorBase::PostVisit; +/// +/// void Visit(Identifier &identifier) override { +/// // Custom implementation of visiting Identifier. +/// } +/// }; +/// +/// @sa Visitable template -class Visitor : public RecursiveVisitorBase { +class Visitor : public detail::RecursiveVisitorBase { public: - using RecursiveVisitorBase::Visit; - using RecursiveVisitorBase::PostVisit; + using detail::RecursiveVisitorBase::Visit; + using detail::RecursiveVisitorBase::PostVisit; }; -} +} // namespace utils