TypeManip.h

  1 ////////////////////////////////////////////////////////////////////////////////
  2 // The Loki Library
  3 // Copyright (c) 2001 by Andrei Alexandrescu
  4 // This code accompanies the book:
  5 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
  6 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
  7 // Permission to use, copy, modify, distribute and sell this software for any 
  8 //     purpose is hereby granted without fee, provided that the above copyright 
  9 //     notice appear in all copies and that both that copyright notice and this 
 10 //     permission notice appear in supporting documentation.
 11 // The author or Addison-Welsey Longman make no representations about the 
 12 //     suitability of this software for any purpose. It is provided "as is" 
 13 //     without express or implied warranty.
 14 ////////////////////////////////////////////////////////////////////////////////
 15 
 16 // Last update: June 20, 2001
 17 
 18 #ifndef TYPEMANIP_INC_
 19 #define TYPEMANIP_INC_
 20 
 21 namespace Loki
 22 {
 23 ////////////////////////////////////////////////////////////////////////////////
 24 // class template Int2Type
 25 // Converts each integral constant into a unique type
 26 // Invocation: Int2Type<v> where v is a compile-time constant integral
 27 // Defines 'value', an enum that evaluates to v
 28 ////////////////////////////////////////////////////////////////////////////////
 29 
 30     template <int v>
 31     struct Int2Type
 32     {
 33         enum { value = v };
 34     };
 35     
 36 ////////////////////////////////////////////////////////////////////////////////
 37 // class template Type2Type
 38 // Converts each type into a unique, insipid type
 39 // Invocation Type2Type<T> where T is a type
 40 // Defines the type OriginalType which maps back to T
 41 ////////////////////////////////////////////////////////////////////////////////
 42 
 43     template <typename T>
 44     struct Type2Type
 45     {
 46         typedef T OriginalType;
 47     };
 48     
 49 ////////////////////////////////////////////////////////////////////////////////
 50 // class template Select
 51 // Selects one of two types based upon a boolean constant
 52 // Invocation: Select<flag, T, U>::Result
 53 // where:
 54 // flag is a compile-time boolean constant
 55 // T and U are types
 56 // Result evaluates to T if flag is true, and to U otherwise.
 57 ////////////////////////////////////////////////////////////////////////////////
 58 
 59     template <bool flag, typename T, typename U>
 60     struct Select
 61     {
 62         typedef T Result;
 63     };
 64     template <typename T, typename U>
 65     struct Select<false, T, U>
 66     {
 67         typedef U Result;
 68     };
 69     
 70 ////////////////////////////////////////////////////////////////////////////////
 71 // Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
 72 ////////////////////////////////////////////////////////////////////////////////
 73 
 74     namespace Private
 75     {
 76         template <class T, class U>
 77         struct ConversionHelper
 78         {
 79             typedef char Small;
 80             struct Big { char dummy[2]; };
 81             static Big   Test(...);
 82             static Small Test(U);
 83             static T MakeT();
 84         };
 85     }
 86 
 87 ////////////////////////////////////////////////////////////////////////////////
 88 // class template Conversion
 89 // Figures out the conversion relationships between two types
 90 // Invocations (T and U are types):
 91 // a) Conversion<T, U>::exists
 92 // returns (at compile time) true if there is an implicit conversion from T
 93 // to U (example: Derived to Base)
 94 // b) Conversion<T, U>::exists2Way
 95 // returns (at compile time) true if there are both conversions from T
 96 // to U and from U to T (example: int to char and back)
 97 // c) Conversion<T, U>::sameType
 98 // returns (at compile time) true if T and U represent the same type
 99 //
100 // Caveat: might not work if T and U are in a private inheritance hierarchy.
101 ////////////////////////////////////////////////////////////////////////////////
102 
103     template <class T, class U>
104     struct Conversion
105     {
106         typedef Private::ConversionHelper<T, U> H;
107 #ifndef __MWERKS__
108         enum { exists = sizeof(typename H::Small) == sizeof(H::Test(H::MakeT())) };
109 #else
110         enum { exists = false };
111 #endif
112         enum { exists2Way = exists && Conversion<U, T>::exists };
113         enum { sameType = false };
114     };
115     
116     template <class T>
117     struct Conversion<T, T>    
118     {
119         enum { exists = 1, exists2Way = 1,sameType = 1 };
120     };
121     
122     template <class T>
123     struct Conversion<void, T>    
124     {
125         enum { exists = 1, exists2Way = 0,sameType = 0 };
126     };
127     
128     template <class T>
129     struct Conversion<T, void>    
130     {
131         enum { exists = 1, exists2Way = 0,sameType = 0 };
132     };
133     
134     template <>
135     class Conversion<void, void>    
136     {
137     public:
138         enum { exists = 1, exists2Way = 1,sameType = 1 };
139     };    
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 // macro SUPERSUBCLASS
144 // Invocation: SUPERSUBCLASS(B, D) where B and D are types. 
145 // Returns true if B is a public base of D, or if B and D are aliases of the 
146 // same type.
147 //
148 // Caveat: might not work if T and U are in a private inheritance hierarchy.
149 ////////////////////////////////////////////////////////////////////////////////
150 
151 #define SUPERSUBCLASS(T, U) \
152     (::Loki::Conversion<const U*, const T*>::exists && \
153     !::Loki::Conversion<const T*, const void*>::sameType)
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 // macro SUPERSUBCLASS
157 // Invocation: SUPERSUBCLASS(B, D) where B and D are types. 
158 // Returns true if B is a public base of D.
159 //
160 // Caveat: might not work if T and U are in a private inheritance hierarchy.
161 ////////////////////////////////////////////////////////////////////////////////
162 
163 #define SUPERSUBCLASS_STRICT(T, U) \
164     (SUPERSUBCLASS(T, U) && \
165     !::Loki::Conversion<const T, const U>::sameType)
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 // Change log:
169 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
170 ////////////////////////////////////////////////////////////////////////////////
171 
172 #endif // TYPEMANIP_INC_
posted @ 2012-10-31 15:27  crazylhf  阅读(100)  评论(0)    收藏  举报