#ifndef MSVC6HELPERS__H #define MSVC6HELPERS__H #if !defined (_MSC_VER) || _MSC_VER >= 1300 #error "please use this header only with MSVC 6.0" #endif namespace Loki { namespace Private { // workaround for the "Error C2516. : is not a legal base class" // Use VC_Base_Workaround's LeftBase instead of the // alleged illegal base class. template struct VC_Base_Workaround : public T, public U { typedef T LeftBase; }; // MSVC 6.0 does not allow the return of // expressions of type "cv void" in a functions with a return // type of cv void (6.6.3). // Functor.h uses this Type as a workaround. struct VoidAsType {}; // workarounds for template template parameters //////////////////////////////////////////////////////////////////////////////// // class template AlwaysFalse // Invocation: AlwaysFalse::value // value will always by 0 (false) //////////////////////////////////////////////////////////////////////////////// template< typename T > struct AlwaysFalse { enum { value = false }; }; //////////////////////////////////////////////////////////////////////////////// // class template ApplyImpl1 // Invocation: ApplyImpl1::template Result // T must be a nontemplate type with a nested class template named In. // The class template is a helper for the Apply1-Template //////////////////////////////////////////////////////////////////////////////// template struct ApplyImpl1 { template struct VC_WORKAROUND : public TypeWithNestedTemplate {}; struct VC_WORKAROUND { template struct In; }; template< typename T1 > struct Result : public VC_WORKAROUND< AlwaysFalse::value >::template In { typedef VC_WORKAROUND< AlwaysFalse::value >::template In Base; }; }; //////////////////////////////////////////////////////////////////////////////// // class template ApplyImpl2 // Invocation: ApplyImpl2::template Result // T must be a nontemplate type with a nested class template named In. // The class template is a helper for the Apply2-Template //////////////////////////////////////////////////////////////////////////////// template struct ApplyImpl2 { template struct VC_WORKAROUND : public TypeWithNestedTemplate {}; struct VC_WORKAROUND {template struct In; }; template< typename T1, typename T2 > struct Result : public VC_WORKAROUND< AlwaysFalse::value >::template In { }; }; } // end of namespace Private //////////////////////////////////////////////////////////////////////////////// // class template Apply1 // Invocation: Apply1 // Applies the type U to the inner template In of type T // The class template Apply1 helps to emulate template template parameters // i first saw this technique in boost's mpl library. //////////////////////////////////////////////////////////////////////////////// template struct Apply1 : Private::ApplyImpl1::template Result { typedef typename Private::ApplyImpl1::template Result::Base Base; }; //////////////////////////////////////////////////////////////////////////////// // class template Apply2 // Invocation: Apply2 // Applies the types U and V to the inner template In of type T // The class template Apply2 helps to emulate template template parameters // i first saw this technique in boost's mpl library. //////////////////////////////////////////////////////////////////////////////// template struct Apply2 : Private::ApplyImpl2::template Result { }; //////////////////////////////////////////////////////////////////////////////// // class template ApplyInnerType // Invocation: ApplyInnerType::type // Applies the type U to the the inner template 'In' of type Wrapper and typedefs // the resulting type to 'type' // The class template ApplyInnerType helps to emulate template template parameters // i first saw this technique in boost's mpl library. //////////////////////////////////////////////////////////////////////////////// template struct ApplyInnerType { template struct Wrapper_VC : Wrapper {}; template<> struct Wrapper_VC { template struct In; }; typedef typename Wrapper_VC::value>::template In::type type; }; //////////////////////////////////////////////////////////////////////////////// // class template ApplyInnerType2 // Invocation: ApplyInnerType2::type // Applies the types U and V to the the inner template 'In' of type Wrapper and typedefs // the resulting type to 'type' // The class template ApplyInnerType helps to emulate template template parameters // i first saw this technique in boost's mpl library. //////////////////////////////////////////////////////////////////////////////// template struct ApplyInnerType2 { template struct Wrapper_VC : Wrapper {}; template<> struct Wrapper_VC { template struct In; }; typedef typename Wrapper_VC::value>::template In::type type; }; template struct ApplyInnerType4 { template struct Wrapper_VC : Wrapper {}; template<> struct Wrapper_VC { template struct In; }; typedef typename Wrapper_VC::value>::template In::type type; }; } #endif