VisitableImpl Cyclic Implementation - GerdHirsch/Cpp-VisitorFrameworkCyclicAcyclic GitHub Wiki

The Repository generates the application specific visitable base with the parameters, the repository is created: using VisitableImpl = .

template<class LoggingPolicy, class BaseKind_, class ...Visitables>
struct Repository{
using VisitorBase = ...
...
//=================================================================
// Visitables
//=================================================================
using Visitable = Cyclic::Visitable<VisitorBase>;

template<class ConcreteVisitable>
using VisitableImpl =
		Cyclic::VisitableImpl<ConcreteVisitable, VisitorBase, LoggingPolicy>;
...
};

Cyclic::Visitable<VisitorBase> is the baseclass of all visitables of a familiy accepting VisitorBase.

The implementation Cyclic::VisitableImpl<..> is based on the template method pattern of the "Gang of Four". The "template method" is the method accept(VisitorBase& ). A "hook method" is the method getVisitable() which must be redefined by the specialization, if the types of VisitableImplementation (i.e. Adapter ) differ from class ConcreteVisitable.

template
<
	class ConcreteVisitable,
	class VisitorBase,
	class LoggingPolicy,
	class VisitableImplementation = ConcreteVisitable
>
struct VisitableImpl : Visitable<VisitorBase>, LoggingPolicy {
typedef Visitable<VisitorBase> base_type;

void accept(VisitorBase& visitor){
	this->logAccepted(*this, visitor);
	visitor.visit(*(This()->getVisitable()) );
}
protected:
// must be redefined if ConcreteVisitable and
// VisitableImplementation differ i.e. see Adapter
ConcreteVisitable* getVisitable() {
	return static_cast<ConcreteVisitable*>(this);
}
ConcreteVisitable const* getVisitable() const {
	return static_cast<ConcreteVisitable const*>(this);
}

VisitableImplementation* This(){
	return static_cast<VisitableImplementation*>(this);
}
VisitableImplementation const* This() const {
	return static_cast<VisitableImplementation const*>(this);
}
};

This() gives access to the specialization. A call This()->getVisitable() chooses the method from VisitableImplementation.