www.pudn.com > Loki.rar > Typelist.h
//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// // Last update: May 19, 2002 #ifndef TYPELIST_INC_ #define TYPELIST_INC_ #include "static_check.h" #include "Nulltype.h" #include "TypeManip.h" //////////////////////////////////////////////////////////////////////////////// // macros TYPELIST_1, TYPELIST_2, ... TYPELIST_50 // Each takes a number of arguments equal to its numeric suffix // The arguments are type names. TYPELIST_NN generates a typelist containing // all types passed as arguments, in that order. // Example: TYPELIST_2(char, int) generates a type containing char and int. //////////////////////////////////////////////////////////////////////////////// #define TYPELIST_1(T1) ::Loki::Typelist#define TYPELIST_2(T1, T2) ::Loki::Typelist #define TYPELIST_3(T1, T2, T3) ::Loki::Typelist #define TYPELIST_4(T1, T2, T3, T4) \ ::Loki::Typelist #define TYPELIST_5(T1, T2, T3, T4, T5) \ ::Loki::Typelist #define TYPELIST_6(T1, T2, T3, T4, T5, T6) \ ::Loki::Typelist #define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ ::Loki::Typelist #define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ ::Loki::Typelist #define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ ::Loki::Typelist #define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ ::Loki::Typelist #define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ ::Loki::Typelist #define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ ::Loki::Typelist #define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \ ::Loki::Typelist #define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14) \ ::Loki::Typelist #define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15) \ ::Loki::Typelist #define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16) \ ::Loki::Typelist #define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17) \ ::Loki::Typelist #define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18) \ ::Loki::Typelist #define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19) \ ::Loki::Typelist #define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \ ::Loki::Typelist #define TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \ ::Loki::Typelist #define TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \ ::Loki::Typelist #define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \ ::Loki::Typelist #define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \ ::Loki::Typelist #define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \ ::Loki::Typelist #define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26) \ ::Loki::Typelist #define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27) \ ::Loki::Typelist #define TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28) \ ::Loki::Typelist #define TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29) \ ::Loki::Typelist #define TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \ ::Loki::Typelist #define TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \ ::Loki::Typelist #define TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \ ::Loki::Typelist #define TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \ ::Loki::Typelist #define TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \ ::Loki::Typelist #define TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35) \ ::Loki::Typelist #define TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36) \ ::Loki::Typelist #define TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37) \ ::Loki::Typelist #define TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38) \ ::Loki::Typelist #define TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39) \ ::Loki::Typelist #define TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \ ::Loki::Typelist #define TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \ ::Loki::Typelist #define TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \ ::Loki::Typelist #define TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \ ::Loki::Typelist #define TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \ ::Loki::Typelist #define TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45) \ ::Loki::Typelist #define TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46) \ ::Loki::Typelist #define TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47) \ ::Loki::Typelist #define TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47, T48) \ ::Loki::Typelist #define TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47, T48, T49) \ ::Loki::Typelist #define TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \ T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \ T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \ T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \ T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \ ::Loki::Typelist namespace Loki { //////////////////////////////////////////////////////////////////////////////// // class template Typelist // The building block of typelists of any length // Use it through the TYPELIST_NN macros // Defines nested types: // Head (first element, a non-typelist type by convention) // Tail (second element, can be another typelist) //////////////////////////////////////////////////////////////////////////////// template struct Typelist { typedef T Head; typedef U Tail; }; namespace TL { //////////////////////////////////////////////////////////////////////////////// // class template MakeTypelist // Takes a number of arguments equal to its numeric suffix // The arguments are type names. // MakeTypeList ::Result // returns a typelist that is of T1, T2, ... //////////////////////////////////////////////////////////////////////////////// template < typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, typename T4 = NullType, typename T5 = NullType, typename T6 = NullType, typename T7 = NullType, typename T8 = NullType, typename T9 = NullType, typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, typename T13 = NullType, typename T14 = NullType, typename T15 = NullType, typename T16 = NullType, typename T17 = NullType, typename T18 = NullType > struct MakeTypeList { private: typedef typename MakeTypeList < T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10, T11, T12, T13, T14, T15, T16, T17, T18 > ::Result TailResult; public: typedef Typelist Result; }; template<> struct MakeTypeList < NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType >{ typedef NullType Result; }; //////////////////////////////////////////////////////////////////////////////// // class template is_Typelist // detects if type is Typelist (including Nulltype) // Invocation : // is_Typelist ::value // returns a compile-time boolean constant containing true iff T is some Typelist // is_Typelist ::type_id // returns a compile-time unsigned constant containing // 1 iff T == Typelist , 2 iff T == NullType and 3 otherwise //////////////////////////////////////////////////////////////////////////////// struct Typelist_tag {}; struct NullType_tag {}; struct NoneList_tag {}; enum { Typelist_ID = 1, NullType_ID = 2, NoneList_ID = 3 }; template struct is_Typelist { private: typedef char (&ye1)[Typelist_ID]; typedef char (&ye2)[NullType_ID]; typedef char (&no) [NoneList_ID]; template static ye1 check(Type2Type< Typelist >); static ye2 check(Type2Type ); static no check(...); public: // VC7 fail NPS_HierarchyGenerators.h if this one is enum static const unsigned int type_id = sizeof(check( Type2Type () )); enum { value = type_id != sizeof(no) }; typedef typename Select < type_id == Typelist_ID, Typelist_tag, typename Select ::Result > ::Result type_tag; }; #ifndef TL_FAST_COMPILATION // this macro will cause compile time error if _type_ is not a Typelist or NullType #define ASSERT_TYPELIST(_type_) \ STATIC_CHECK( ::Loki::TL::is_Typelist<_type_>::value, TList_is_not_legal_Typelist ) #else // might improve the compilation time #define ASSERT_TYPELIST(_type_) \ typedef char _type_##_is_not_a_Typelist[true] #endif // ndef TL_FAST_COMPILATION //////////////////////////////////////////////////////////////////////////////// // class template Length // Computes the length of a typelist // Invocation (TList is a typelist): // Length ::value // returns a compile-time constant containing the length of TList, not counting // the end terminator (which by convention is NullType) //////////////////////////////////////////////////////////////////////////////// template struct Length; template <> struct Length { enum { value = 0 }; }; template struct Length { private: ASSERT_TYPELIST(TList); typedef typename TList::Head Head; typedef typename TList::Tail Tail; public: enum { value = 1 + Length ::value }; }; //////////////////////////////////////////////////////////////////////////////// // class template TypeAt // Finds the type at a given index in a typelist // Invocation (TList is a typelist and index is a compile-time integral // constant): // TypeAt ::Result // returns the type in position 'index' in TList // If you pass an out-of-bounds index, the result is a compile-time error //////////////////////////////////////////////////////////////////////////////// template struct TypeAt { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { typedef typename TypeAt ::Result Result; }; template<> struct In<0> { typedef Head Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template TypeAtNonStrict // Finds the type at a given index in a typelist // Invocations (TList is a typelist and index is a compile-time integral // constant): // a) TypeAt ::Result // returns the type in position 'index' in TList, or NullType if index is // out-of-bounds // b) TypeAt ::Result // returns the type in position 'index' in TList, or D if index is out-of-bounds //////////////////////////////////////////////////////////////////////////////// template struct TypeAtNonStrict { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { typedef typename TypeAtNonStrict < typename TList1::Tail, i - 1, DefaultType > ::Result Result; }; template<> struct In , 0> { typedef Head Result; }; template<> struct In { typedef DefaultType Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template IndexOf // Finds the index of a type in a typelist // Invocation (TList is a typelist and T is a type): // IndexOf ::value // returns the position of T in TList, or NullType if T is not found in TList //////////////////////////////////////////////////////////////////////////////// template struct IndexOf { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { private: typedef typename TList1::Tail Tail; enum { temp = (IndexOf ::value) }; public: enum { value = temp == -1 ? -1 : 1 + temp }; }; template<> struct In< Typelist > { enum { value = 0 }; }; template<> struct In { enum { value = -1 }; }; public: enum { value = In ::value }; }; //////////////////////////////////////////////////////////////////////////////// // class template Append // Appends a type or a typelist to another // Invocation (TList is a typelist and T is either a type or a typelist): // Append ::Result // returns a typelist that is TList followed by T and NullType-terminated //////////////////////////////////////////////////////////////////////////////// template struct Append { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { typedef typename TList1::Tail Tail; typedef Typelist < Head, typename Append ::Result > Result; }; template<> struct In { typedef typename Select < is_Typelist ::value, T, TYPELIST_1(T) > ::Result Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Erase // Erases the first occurence, if any, of a type in a typelist // Invocation (TList is a typelist and T is a type): // Erase ::Result // returns a typelist that is TList without the first occurence of T //////////////////////////////////////////////////////////////////////////////// template struct Erase { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { typedef typename TList1::Tail Tail; typedef Typelist < Head, typename Erase ::Result > Result; }; template<> struct In< Typelist > { typedef Tail Result; }; template<> struct In { typedef NullType Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template EraseAll // Erases all first occurences, if any, of a type in a typelist // Invocation (TList is a typelist and T is a type): // EraseAll ::Result // returns a typelist that is TList without any occurence of T //////////////////////////////////////////////////////////////////////////////// template struct EraseAll { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { private: typedef typename TList1::Tail Tail; typedef typename EraseAll ::Result TailResult; public: typedef typename Select < SameType::value, TailResult, Typelist > ::Result Result; }; template<> struct In { typedef NullType Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template NoDuplicates // Removes all duplicate types in a typelist // Invocation (TList is a typelist): // NoDuplicates ::Result //////////////////////////////////////////////////////////////////////////////// template struct NoDuplicates { private: typedef typename TList::Head Head; typedef typename TList::Tail Tail; ASSERT_TYPELIST(TList); typedef typename NoDuplicates ::Result L1; typedef typename Erase ::Result L2; public: typedef Typelist Result; }; template <> struct NoDuplicates { typedef NullType Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Replace // Replaces the first occurence of a type in a typelist, with another type // Invocation (TList is a typelist, T, U are types): // Replace ::Result // returns a typelist in which the first occurence of T is replaced with U //////////////////////////////////////////////////////////////////////////////// template struct Replace { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { typedef typename TList1::Tail Tail; typedef Typelist < Head, typename Replace ::Result > Result; }; template<> struct In< Typelist > { typedef Typelist Result; }; template<> struct In { typedef NullType Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template ReplaceAll // Replaces all occurences of a type in a typelist, with another type // Invocation (TList is a typelist, T, U are types): // Replace ::Result // returns a typelist in which all occurences of T is replaced with U //////////////////////////////////////////////////////////////////////////////// template struct ReplaceAll { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { private: typedef typename TList1::Tail Tail; typedef typename ReplaceAll ::Result TailResult; public: typedef typename Select < SameType::value, Typelist, Typelist > ::Result Result; }; template<> struct In { typedef NullType Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template Reverse // Reverses a typelist // Invocation (TList is a typelist): // Reverse ::Result // returns a typelist that is TList reversed //////////////////////////////////////////////////////////////////////////////// template struct Reverse; template <> struct Reverse { typedef NullType Result; }; template struct Reverse { private: typedef typename TList::Head Head; typedef typename TList::Tail Tail; ASSERT_TYPELIST(TList); public: typedef typename Append< typename Reverse ::Result, Head>::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template MostDerived // Finds the type in a typelist that is the most derived from a given type // Invocation (TList is a typelist, T is a type): // Replace ::Result // returns the type in TList that's the most derived from T //////////////////////////////////////////////////////////////////////////////// template struct MostDerived { typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: ASSERT_TYPELIST(TList); template struct In { private: typedef typename TList1::Tail Tail; typedef typename TList1::Head Head; typedef typename MostDerived ::Result Candidate; public: typedef typename Select < SUPERSUBCLASS(Candidate, Head), Head, Candidate > ::Result Result; }; template<> struct In { typedef T Result; }; public: typedef typename In ::Result Result; }; //////////////////////////////////////////////////////////////////////////////// // class template DerivedToFront // Arranges the types in a typelist so that the most derived types appear first // Invocation (TList is a typelist): // DerivedToFront ::Result // returns the reordered TList //////////////////////////////////////////////////////////////////////////////// template struct DerivedToFront; template <> struct DerivedToFront { typedef NullType Result; }; template struct DerivedToFront { private: ASSERT_TYPELIST(TList); typedef typename TList::Head Head; typedef typename TList::Tail Tail; typedef typename MostDerived ::Result TheMostDerived; typedef typename ReplaceAll ::Result Temp; typedef typename DerivedToFront ::Result L; public: typedef Typelist Result; }; //////////////////////////////////////////////////////////////////////////////// // class template DerivedToFrontAll // Arranges all the types in a typelist so that the most derived types appear first // Invocation (TList is a typelist): // DerivedToFront ::Result // returns the reordered TList //////////////////////////////////////////////////////////////////////////////// template struct DerivedToFrontAll; template <> struct DerivedToFrontAll { typedef NullType Result; }; template struct DerivedToFrontAll { private: ASSERT_TYPELIST(TList); typedef typename TList::Head Head; typedef typename TList::Tail Tail; typedef typename MostDerived ::Result TheMostDerived; typedef typename Replace ::Result L; typedef typename DerivedToFrontAll ::Result TailResult; public: typedef Typelist Result; }; } // namespace TL } // namespace Loki //////////////////////////////////////////////////////////////////////////////// // Change log: // June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27 // (credit due to Dave Taylor) // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! // May 10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466) //////////////////////////////////////////////////////////////////////////////// #endif // TYPELIST_INC_