📄 visitor.h
字号:
virtual R Visit(typename TList::Head&)
{ return R(); }
protected:
~BaseVisitorImplBase() {}
};
template <class TList, class R>
struct BaseVisitorImplVoidBase : public Visitor<typename TList::Head, R>,
public Private::BaseVisitorImplWrap<TList, R>::Result
{
ASSERT_TYPELIST(TList);
virtual R Visit(typename TList::Head&)
{ }
protected:
~BaseVisitorImplVoidBase() {}
};
}
template <class TList, typename R>
class BaseVisitorImpl : public Select
<
Private::IsVoid<R>::value,
Private::BaseVisitorImplVoidBase<TList,R>,
Private::BaseVisitorImplBase<TList, R>
>::Result
{
ASSERT_TYPELIST(TList);
public:
// using BaseVisitorImpl<Tail, R>::Visit;
};
////////////////////////////////////////////////////////////////////////////////
// class template DefaultCatchAll
////////////////////////////////////////////////////////////////////////////////
template <typename R, typename Visited>
struct DefaultCatchAll
{
static R OnUnknownVisitor(Visited&, BaseVisitor&)
{ return R(); }
};
template <typename R, typename Visited>
struct DefaultCatchAllVoid
{
static R OnUnknownVisitor(Visited&, BaseVisitor&)
{ }
};
// template template parameter workaround.
// use Wrapper-Classes like this to instantiate BaseVisitable
struct DefaultCatchAllWrapper
{
template <class R, class Visited>
struct In
{
typedef typename Select<Private::IsVoid<R>::value,
DefaultCatchAllVoid<R, Visited>,
DefaultCatchAll<R, Visited>
>::Result type;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template NonStrictVisitor
// Implements non-strict visitation (you can implement only part of the Visit
// functions)
////////////////////////////////////////////////////////////////////////////////
template <class T, class Base>
struct NonStrictVisitorUnit : public Base
{
typedef typename Base::ReturnType ReturnType;
ReturnType Visit(T&)
{
return ReturnType();
}
};
template <class T, class Base>
struct NonStrictVisitorUnitVoid : public Base
{
typedef typename Base::ReturnType ReturnType;
ReturnType Visit(T&)
{}
};
struct NonStrictVisitorUnitWrapper
{
template <class T, class B>
struct In
{
typedef typename B::ReturnType R;
typedef typename Select<Private::IsVoid<R>::value,
NonStrictVisitorUnitVoid<T, B>,
NonStrictVisitorUnit<T, B>
>::Result type;
};
};
template <class TList, typename R = Loki::Private::VoidWrap::type>
class NonStrictVisitor
: public GenLinearHierarchy<
TList,
NonStrictVisitorUnitWrapper,
Visitor<TList, R> >
{
};
////////////////////////////////////////////////////////////////////////////////
// class template BaseVisitable
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <class R, class CatchAll>
class BaseVisitableBase
{
typedef R ReturnType;
protected:
template <class T>
static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
{
typedef ApplyInnerType2<CatchAll, R, T>::type CatchA;
// Apply the Acyclic Visitor
if (Visitor<T, R>* p = dynamic_cast<Visitor<T, R>*>(&guest))
{
return p->Visit(visited);
}
return CatchA::OnUnknownVisitor(visited, guest);
}
~BaseVisitableBase() {}
};
template <class R, class CatchAll>
class BaseVisitableVoidBase
{
typedef R ReturnType;
protected:
template <class T>
static ReturnType AcceptImpl(T& visited, BaseVisitor& guest)
{
typedef ApplyInnerType2<CatchAll, R, T>::type CatchA;
// Apply the Acyclic Visitor
if (Visitor<T>* p = dynamic_cast<Visitor<T>*>(&guest))
{
p->Visit(visited);
return;
}
CatchA::OnUnknownVisitor(visited, guest);
}
~BaseVisitableVoidBase() {}
};
}
template
<
typename R = Loki::Private::VoidWrap::type,
class CatchAll = DefaultCatchAllWrapper
>
class BaseVisitable : public Select<Private::IsVoid<R>::value,
Private::BaseVisitableVoidBase<R, CatchAll>,
Private::BaseVisitableBase<R, CatchAll>
>::Result
{
public:
typedef R ReturnType;
virtual ~BaseVisitable() {}
virtual ReturnType Accept(BaseVisitor&) = 0;
};
////////////////////////////////////////////////////////////////////////////////
// macro DEFINE_VISITABLE
// Put it in every class that you want to make visitable (in addition to
// deriving it from BaseVisitable<R>
////////////////////////////////////////////////////////////////////////////////
#define DEFINE_VISITABLE() \
virtual ReturnType Accept(Loki::BaseVisitor& guest) \
{ return AcceptImpl(*this, guest); }
#define DEFINE_VISITABLE_VOID() \
virtual ReturnType Accept(Loki::BaseVisitor& guest) \
{ AcceptImpl(*this, guest); }
////////////////////////////////////////////////////////////////////////////////
// class template CyclicVisitor
// Put it in every class that you want to make visitable (in addition to
// deriving it from BaseVisitable<R>
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
template <typename R, class TList>
class CyclicVisitorBase : public Visitor<TList, R>
{
public:
template <class Visited>
ReturnType GenericVisit(Visited& host)
{
Visitor<Visited, ReturnType>& subObj = *this;
return subObj.Visit(host);
}
protected:
~CyclicVisitorBase() {}
};
template <class TList>
class CyclicVisitorVoidBase : public Visitor<TList, void>
{
public:
template <class Visited>
ReturnType GenericVisit(Visited& host)
{
Visitor<Visited, ReturnType>& subObj = *this;
subObj.Visit(host);
}
protected:
~CyclicVisitorVoidBase() {}
};
}
template <typename R, class TList>
class CyclicVisitor : public Select<Private::IsVoid<R>::value,
Private::CyclicVisitorVoidBase<TList>,
Private::CyclicVisitorBase<R, TList>
>::Result
{
public:
typedef R ReturnType;
// using Visitor<TList, R>::Visit;
};
////////////////////////////////////////////////////////////////////////////////
// macro DEFINE_CYCLIC_VISITABLE
// Put it in every class that you want to make visitable by a cyclic visitor
////////////////////////////////////////////////////////////////////////////////
#define DEFINE_CYCLIC_VISITABLE(SomeVisitor) \
virtual SomeVisitor::ReturnType Accept(SomeVisitor& guest) \
{ return guest.GenericVisit(*this); }
#define DEFINE_CYCLIC_VISITABLE_VOID(SomeVisitor) \
virtual void Accept(SomeVisitor& guest) \
{ guest.GenericVisit(*this); }
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20: add default argument DefaultCatchAll to BaseVisitable
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// Oct 27, 2002: ported by Benjamin Kaufmann to MSVC 6.0
// Feb 23, 2003: Removed special visitor classes for return type void.
// Added Loki:: qualification to Accept's Paramter (in the macro) B.K.
// Mar 06, 2003: Changed default values for return types to void.
// Added protected destructors to private implementation classes B.K.
////////////////////////////////////////////////////////////////////////////////
#endif // VISITOR_INC_
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -