VisitorBase Cyclic Implementation - GerdHirsch/Cpp-VisitorFrameworkCyclicAcyclic GitHub Wiki
The Repository generates the application specific visitor base
with the parameters, the repository is created: using Visitor =
.
template<class LoggingPolicy, class BaseKind_, class ...Visitables>
struct Repository{
using Visitor =
typename Cyclic::SwitchBaseKind<LoggingPolicy, BaseKind_>::template
implementsVisitor<Visitables...>;
...
};
Cyclic::SwitchBaseKind
is the switch between abstract and default implementations
for visit(..)
which are generated via the inner template implementsVisitor<Visitables...>
.
The inner template delegates to a template in namespace Cyclic
InheritFrom...
.
namespace Cyclic{
template<class LoggingPolicy_, class = BaseKind::Abstract>
struct SwitchBaseKind{
template<class ...Visitables>
using implementsVisitor = Cyclic::InheritFromAbstract<Visitables...>;
};
template<class LoggingPolicy_>
struct SwitchBaseKind<LoggingPolicy_, BaseKind::Default>{
template<class ...Visitables>
using implementsVisitor = Cyclic::InheritFromDefault<LoggingPolicy_, Visitables...>;
};
InheritFromDefault
is similar implemented like InheritFromAbstract
. It is explicit specialized for one
Argument and the primary inherits from itself by reducing the list of Visitables by one type. The list is represented by
template<class ToVisit, class... Rest>
. The specialization ends the recursion. This creates a structure of linear inherited baseclasses each declaring the matching signature for virtual void visit(ToVisit&) = 0;
Because of name hiding, the using base_type::visit
statement is needed.
template<class ToVisit, class... Rest>
struct InheritFromAbstract
: public InheritFromAbstract<Rest...>{
public:
virtual void visit(ToVisit& v) = 0;
using base_type = InheritFromAbstract<Rest...>;
using base_type::visit;
};
template<class ToVisit>
struct InheritFromAbstract<ToVisit>
{
public:
virtual void visit(ToVisit& v) = 0;
virtual std::string toString() const = 0;
};
}