//TyepTraits.h namespace Loki { template <typename T> struct IsCustomUnsignedInt //IsCustomSignedInt IsCustomFloat { enum {value=0}; }; namespace Private { typedef LOKI_TYPELIST_4(unsigned char, unsigned short int, unsigned int, unsigned long int) StdUnsignedInts; typedef LOKI_TYPELIST_4(char, short int, int, long int) StdSignedInts; typedef LOKI_TYPELIST_3(bool, char, wchar_t) StdOtherInts; typedef LOKI_TYPELIST_3(float, double, long double) StdFloats; //ignore const template param instantiation version template <typename U> struct AddPointer { typedef U* Result; }; template <typename U> struct AddPointer<U&> { typedef U* Result; }; template <typename U> struct AddReference { typedef U& Result; }; template <typename U> struct AddReference<U&> { typedef U& Result; }; template <typename U> struct AddReference<void> { typedef NullType Result; }; template <typename U> struct AddParamterType { typedef const U& Result; }; template <typename U> struct AddParamterType<U&> { typedef U& Result; }; template <typename U> struct AddParamterType<void> { typedef NullType Result; }; //Is func pointer template <typename T> IsFunctionPointerRaw { enum{relust=0}; }; template <typename T> IsFunctionPointerRaw<T(*)()> { enum{result=1}; }; template <typename T, typename p01> IsFunctionPointerRaw<T(*)(p01)> { enum{result=1}; }; template <typename T, typename p01, typename p02> IsFunctionPointerRaw<T(*)(p01, p02)> { enum{result=1}; }; //... typename p20 template <typename T> IsFunctionPointerRaw<T(*)(...)> { enum{result=1}; }; template <typename T, typename p01> IsFuncitonPointerRaw<T(*)(p01,...)> /... typename p20 { enum{result=1}; } template <typename T> struct IsMemberFunctionPointerRaw{enum{result=0};}; template <typename T, typename S> struct IsMemberFunctionPointerRaw<T(S::*)()>{enum{result=1};}; template <typename T, tyepname S> struct IsMemberFunctionPointerRaw<T(S::*)(...)>{enum{result=1};}; //const version template <typename T, typename S> struct IsMemberFunctionPointerRaw<T(S::*)() const> {enum{result=1};}; //const and variable parameter version //volatile version //volatile and variable parameter version //const volatile versions //const and variable parameter version }//namespace Private template <typename T> class TypeTraits { private: template <class U> struct ReferenceTraits { enum {result=false}; typedef U ReferredType; }; template <class U> struct ReferenceTraits<U&> { enum {result=true}; typedef U ReferredType; }; template <class U> struct PointerTraits { enum{result=false}; typedef NullType PointeeType; }; template <class U> struct PointerTraits<U*> { enum{result=true}; typedef U PointeeType; }; template <class U> struct PointerTraits<U* &) { enum{result=true}; typedef U PointeeType; }; template <class U> struct PToMTraits{enum{result=false};}; template <class U, class V> struct PToMTraits<U V::*>{enum{result=true};}; template <class U> struct FunctionPointerTraits{enum{result=Private::IsFunctionPointerRaw<U>::result};}; template <class U> struct PToMFunctionTraits{enum{result=Private::IsMemverFuncitonPointerRaw<U>::result}; tepmlate <class U> struct UnConst { enum{IsConst=0}; typedef U Result; }; template <class U> struct UnConst<const U> { enum{IsConst=1}; typedef U Result; }; template <class U> struct UnConst<const U&> { enum{IsConst=1}; typedef U Result; }; //UnVolatile version public: typedef typename UnConst<T>::Result NonConstType; typedef typename UnVolatile<T>::Result NonVolatileType; typedef typename UnConst<typename UnVolatile<T>::Result>::Result UnQualifiedType; typedef typename PointerTraits<UnQualifiedType>::PointeeType PointeeType; typedef typename ReferenceTraits<T>::ReferredType ReferredType; enum { isConst = UnConst<T>::isConst }; enum { isVolatile = UnVolatile<T>::isVolatile }; enum { isReference = ReferenceTraits<UnqualifiedType>::result }; enum { isFunction = FunctionPointerTraits<typename Private::AddPointer<T>::Result >::result }; enum { isFunctionPointer= FunctionPointerTraits< typename ReferenceTraits<UnqualifiedType>::ReferredType >::result }; enum { isMemberFunctionPointer= PToMFunctionTraits< typename ReferenceTraits<UnqualifiedType>::ReferredType >::result }; enum { isMemberPointer = PToMTraits< typename ReferenceTraits<UnqualifiedType>::ReferredType >::result || isMemberFunctionPointer }; enum { isPointer = PointerTraits< typename ReferenceTraits<UnqualifiedType>::ReferredType >::result || isFunctionPointer }; enum { isStdUnsignedInt = TL::IndexOf<Private::StdUnsignedInts, UnqualifiedType>::value >= 0 || TL::IndexOf<Private::StdUnsignedInts, typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; enum { isStdSignedInt = TL::IndexOf<Private::StdSignedInts, UnqualifiedType>::value >= 0 || TL::IndexOf<Private::StdSignedInts, typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt || TL::IndexOf<Private::StdOtherInts, UnqualifiedType>::value >= 0 || TL::IndexOf<Private::StdOtherInts, typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; enum { isStdFloat = TL::IndexOf<Private::StdFloats, UnqualifiedType>::value >= 0 || TL::IndexOf<Private::StdFloats, typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; enum { isStdArith = isStdIntegral || isStdFloat }; enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType }; enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<UnqualifiedType>::value }; enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<UnqualifiedType>::value }; enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt }; enum { isFloat = isStdFloat || IsCustomFloat<UnqualifiedType>::value }; enum { isArith = isIntegral || isFloat }; enum { isFundamental = isStdFundamental || isArith }; typedef typename Select<isStdArith || isPointer || isMemberPointer, T, typename Private::AddParameterType<T>::Result>::Result ParameterType; }; } //Visitor.h namespace Loki { class BaseVisitor { public: virtual ~BaseVisitor(){} }; template <class T, typename R=void, bool ConstVisit=false> class Visitor; template <class T, typename R> class Visitor<T,R,false> { public: typedef T ParamType; typedef R ReturnType; virtual ~Visitor(){} ReturnType visit(ParamType&)=0; }; template <class T, typename R> class Visitor<T,R,true> { public: typedef T ParamType; typedef const R ReturnType; virtual ~Visitor(){} ReturnType visit(ParamType&)=0; }; template <class Head, class Tail, typename R> class Visitor<TypeList<Head, Tail>,R,false> :public Visitor<Head,R,false>,Visitor<Tail,R,false> { public: typedef R ReturnType; }; template <class Head, typename R> class Visitor<typeList<Head,NullType>,R,false> :public Visitor<Head,R,false> { public: typedef R ReturnType; using Visitor<Head,R,false>::visit; }; //true version template <class TList, typename R=void> class BaseVisitorImp; template <class Head, class Tail, typename R> class BaseVisitorImp <TypeList<Head, Tail>,R> :Visitor<Head,R>,BaseVisitorImp<Tail,R> { public: virtual R visit(Head&){return R();} }; template <class Head, typename R> class BaseVisitorImpl<Typelist<Head, NullType>, R> : public Visitor<Head, R> { public: virtual R Visit(Head&) { return R(); } }; template <typename R, typename Visited> struct DefaultCatchAll { static R OnUnknownVisitor(Visited&, BaseVisitor&) { return R(); } }; template < typename R = void, template <typename, class> class CatchAll = DefaultCatchAll, bool ConstVisitable = false > class BaseVisitable; template<typename R,template <typename, class> class CatchAll> class BaseVisitable<R, CatchAll, false> { public: typedef R ReturnType; virtual ~BaseVisitable() {} virtual ReturnType Accept(BaseVisitor&) = 0; protected: // give access only to the hierarchy template <class T> static ReturnType AcceptImpl(T& visited, BaseVisitor& guest) { // Apply the Acyclic Visitor if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(&guest)) { return p->Visit(visited); } return CatchAll<R, T>::OnUnknownVisitor(visited, guest); } }; template<typename R,template <typename, class> class CatchAll> class BaseVisitable<R, CatchAll, true> { public: typedef R ReturnType; virtual ~BaseVisitable() {} virtual ReturnType Accept(BaseVisitor&) const = 0; protected: // give access only to the hierarchy template <class T> static ReturnType AcceptImpl(const T& visited, BaseVisitor& guest) { // Apply the Acyclic Visitor if (Visitor<T,R,true>* p = dynamic_cast<Visitor<T,R,true>*>(&guest)) { return p->Visit(visited); } return CatchAll<R, T>::OnUnknownVisitor(const_cast<T&>(visited), guest); } }; template <typename R, class TList> class CyclicVisitor : public Visitor<TList, R> { public: typedef R ReturnType; // using Visitor<TList, R>::Visit; template <class Visited> ReturnType GenericVisit(Visited& host) { Visitor<Visited, ReturnType>& subObj = *this; return subObj.Visit(host); } }; }