diff --git a/MSVC/1200/Typelist.h b/MSVC/1200/Typelist.h index 5d949d7..1b5c1bc 100644 --- a/MSVC/1200/Typelist.h +++ b/MSVC/1200/Typelist.h @@ -2,25 +2,27 @@ // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// 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 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" +// 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: Sept 29, 2002 // -// Rani Sharoni's VC 7 port is heavily based on explicit template specialization +// Last update: Feb 22, 2003 +// +// renamed MakeTypeList to MakeTypelist. +// +// Rani Sharoni's VC 7 port is heavily based on explicit template specialization // inside class templates. // This approach has two problems: // First: It does not seem to work correctly with VC 6 // Second: The C++ Standard allows explicit specialization only in namespace-scope. -// +// // In general my solutions need more template-classes. But I hope that they // are all conforming to the C++ Standard. @@ -39,7 +41,7 @@ typedef ::Loki::Private::static_assert_test struct TList_is_not_legal_Typelist; template <> struct TList_is_not_legal_Typelist{}; - + struct Typelist_tag {}; struct NullType_tag {}; struct NoneList_tag {}; - - enum + + enum { NoneList_ID = 0, Typelist_ID = 1, AtomList_ID = 2, NullType_ID = 4 - + }; //////////////////////////////////////////////////////////////////////////////// // class template IsTypelist @@ -414,7 +416,7 @@ namespace Loki typedef TypeTag<2>::X AtomList; typedef TypeTag<3>::X NullList; typedef TypeTag<4>::X NoList; - + // VC 6.0 does not allow overloads // for check(Type2Type< Typelist >) // and check(Type2Type); @@ -426,31 +428,31 @@ namespace Loki template static TypeTag<2>::X check2(Type2Type< Typelist >); static TypeTag<4>::X check2(...); - + static TypeTag<3>::X check3(Type2Type); static TypeTag<4>::X check3(...); - - + + public: - enum - { + enum + { temp1 = sizeof(check(Type2Type())) == sizeof(TypeTag<1>::X) ? Typelist_ID : NoneList_ID, temp2 = sizeof(check2(Type2Type())) == sizeof(TypeTag<2>::X) ? AtomList_ID : NoneList_ID, temp4 = temp2 ? Typelist_ID :NoneList_ID, temp3 = sizeof(check3(Type2Type())) == sizeof(TypeTag<3>::X) ? NullType_ID : NoneList_ID, value = temp1 || temp2 || temp3, - type_id = (temp1 ^ temp4) | temp2 | temp3 + type_id = (temp1 ^ temp4) | temp2 | temp3 }; typedef typename Select < - type_id == Typelist_ID || type_id == AtomList_ID, + type_id == Typelist_ID || type_id == AtomList_ID, Typelist_tag, typename Select::Result - > + > ::Result type_tag; - - + + }; } // end of namespace Private @@ -462,24 +464,24 @@ namespace Loki // returns a typelist that is of T1, T2, ... //////////////////////////////////////////////////////////////////////////////// // MakeTypeList-Template from Rani Sharoni's VC 7 port. - template + 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 + > + struct MakeTypelist { private: - typedef typename MakeTypeList + typedef typename MakeTypelist < - T2 , T3 , T4 , - T5 , T6 , T7 , - T8 , T9 , T10, + T2 , T3 , T4 , + T5 , T6 , T7 , + T8 , T9 , T10, T11, T12, T13, - T14, T15, T16, + T14, T15, T16, T17, T18 > ::Result TailResult; @@ -489,11 +491,11 @@ namespace Loki }; template<> - struct MakeTypeList + struct MakeTypelist < - NullType, NullType, NullType, - NullType, NullType, NullType, - NullType, NullType, NullType, + NullType, NullType, NullType, + NullType, NullType, NullType, + NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType, NullType @@ -501,7 +503,7 @@ namespace Loki { typedef NullType Result; }; - + //////////////////////////////////////////////////////////////////////////////// // class template Length // Computes the length of a typelist @@ -518,7 +520,7 @@ namespace Loki typedef typename TList::Head Head; typedef typename TList::Tail Tail; public: - + enum {value = 1 + Length::value}; }; @@ -530,11 +532,11 @@ namespace Loki enum {value = 0}; }; - + //////////////////////////////////////////////////////////////////////////////// // 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 +// Invocation (TList is a typelist and index is a compile-time integral // constant): // TypeAt::Result // returns the type in position 'index' in TList @@ -554,7 +556,7 @@ namespace Private typedef typename TList::Tail Tail; typedef typename TypeAtImpl::template In::Result Result; }; - + }; // the border case is represented by an explicit specialization // The type at Index 0 is the type of the head. @@ -570,7 +572,7 @@ namespace Private }; }; } // end of namespace Private - + template struct TypeAt { @@ -580,10 +582,10 @@ namespace Private //////////////////////////////////////////////////////////////////////////////// // 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 +// 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 +// 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 @@ -591,7 +593,7 @@ namespace Private template struct TypeAtNonStrict; namespace Private -{ +{ // if TList is not NullType, check if Index is 0. // if Index is 0, the result is TList::Head // if Index is > 0, the result is the result of appliying TypeAtNonStrict @@ -622,15 +624,15 @@ namespace Private typedef DefType Result; }; }; - + } // end of namespace Private template struct TypeAtNonStrict { - typedef typename + typedef typename Private::TypeAtNonStrictImpl::template In::Result Result; - }; - + }; + //////////////////////////////////////////////////////////////////////////////// // class template IndexOf // Finds the index of a type in a typelist @@ -638,7 +640,7 @@ namespace Private // IndexOf::value // returns the position of T in TList, or -1 if T is not found in TList //////////////////////////////////////////////////////////////////////////////// - template + template struct IndexOf; namespace Private { @@ -657,9 +659,9 @@ namespace Private typedef typename TList::Head Head; typedef typename TList::Tail Tail; private: - enum {temp = IsEqualType::value != 0 ? 0 + enum {temp = IsEqualType::value != 0 ? 0 : IndexOf::temp}; - + public: enum {value = temp == -1 ? -1 : 1 + temp}; }; @@ -678,10 +680,10 @@ namespace Private }; } // end of namespace Private - + // The primary IndexOfImpl-Template is always one step ahead. // Therefore if T is in list, we need to subtract one from the result. - template + template struct IndexOf { enum {temp = Private::IndexOfImpl::template In::value}; @@ -708,10 +710,10 @@ namespace Private template struct In { - typedef Typelist::Result> Result; }; - + }; template <> @@ -732,7 +734,7 @@ namespace Private { typedef typename Select < - IsEqualType::value, // is T == Nulltype? + IsEqualType::value, // is T == Nulltype? NullType, // yes typename Select // no. check if T is a Typelist < @@ -765,7 +767,7 @@ namespace Private { template struct EraseImpl - { // TList is not NullType. + { // TList is not NullType. // Check if TList::Head is equal to T // if T is the same as TList::Head, then the Result is TList::Tail // @@ -801,7 +803,7 @@ namespace Private }; }; } // end of namespace Private - + template struct Erase { @@ -821,7 +823,7 @@ namespace Private { template struct EraseAllImpl - { // TList is not NullType. + { // TList is not NullType. // Check if TList::Head is equal to T // If T is equal to TLIst::Head the result is the result of EraseAll // applied to TList::Tail @@ -856,7 +858,7 @@ namespace Private }; }; } // end of namespace Private - + template struct EraseAll { @@ -870,13 +872,13 @@ namespace Private // NoDuplicates::Result //////////////////////////////////////////////////////////////////////////////// // NoDuplicates taken from Rani Sharoni's Loki VC7-Port. - template + template struct NoDuplicates { private: typedef typename TList::Head Head; typedef typename TList::Tail Tail; - + ASSERT_TYPELIST(TList); typedef typename NoDuplicates::Result L1; @@ -885,8 +887,8 @@ namespace Private public: typedef Typelist Result; }; - - template <> + + template <> struct NoDuplicates { typedef NullType Result; @@ -925,7 +927,7 @@ namespace Private >::Result Result; }; }; - + // If TList is NullType the result is NullType template <> struct ReplaceImpl @@ -937,14 +939,14 @@ namespace Private }; }; } // end of namespace Private - + template struct Replace { - typedef typename + typedef typename Private::ReplaceImpl::template In::Result Result; }; - + //////////////////////////////////////////////////////////////////////////////// // class template ReplaceAll // Replaces all occurences of a type in a typelist, with another type @@ -971,11 +973,11 @@ namespace Private < IsEqualType::value, // Is T == Head? Typelist::Result>, // yes - Typelist::Result> + Typelist::Result> >::Result Result; }; }; - + // If TList is NullType the result is NullType template <> struct ReplaceAllImpl @@ -990,7 +992,7 @@ namespace Private template struct ReplaceAll { - typedef typename + typedef typename Private::ReplaceAllImpl::template In::Result Result; }; @@ -1003,20 +1005,20 @@ namespace Private //////////////////////////////////////////////////////////////////////////////// // Reverse taken from Rani Sharoni's Loki VC7-Port. template struct Reverse; - + template <> struct Reverse { typedef NullType Result; }; - - template + + template struct Reverse { private: typedef typename TList::Head Head; typedef typename TList::Tail Tail; - + ASSERT_TYPELIST(TList); public: @@ -1068,15 +1070,13 @@ namespace Private typedef typename Private::MostDerivedImpl::template 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 +// returns the reordered TList //////////////////////////////////////////////////////////////////////////////// -// DerivedToFront taken from Rani Sharoni's Loki VC7-Port. template struct DerivedToFront { @@ -1085,15 +1085,15 @@ namespace Private typedef typename TList::Head Head; typedef typename TList::Tail Tail; - + typedef typename MostDerived::Result TheMostDerived; - typedef typename ReplaceAll::Result Temp; + typedef typename Replace::Result Temp; typedef typename DerivedToFront::Result L; public: typedef Typelist Result; }; - + template <> struct DerivedToFront { @@ -1105,7 +1105,7 @@ namespace Private // 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 +// returns the reordered TList //////////////////////////////////////////////////////////////////////////////// // DerivedToFrontAll taken from Rani Sharoni's Loki VC7-Port. template @@ -1116,23 +1116,23 @@ namespace Private 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; }; - + template <> struct DerivedToFrontAll { typedef NullType Result; }; - - + + } // end of namespace TL } // end of namespace Loki //////////////////////////////////////////////////////////////////////////////// @@ -1142,5 +1142,7 @@ namespace Private // 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) // Sept 29, 2002: ported by Benjamin Kaufmann to MSVC 6.0 +// Feb 24, 2003: renamed MakeTypeList to MakeTypelist. Fixed a bug in +// DerivedToFront. //////////////////////////////////////////////////////////////////////////////// #endif // TYPELIST_INC_ \ No newline at end of file