1 ////////////////////////////////////////////////////////////////////////////////
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 #ifndef LOKI_TYPEMANIP_INC_
16 #define LOKI_TYPEMANIP_INC_
18 // $Id: TypeManip.h 749 2006-10-17 19:49:26Z syntheticpp $
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 ////////////////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////////////////
46 typedef T OriginalType;
49 ////////////////////////////////////////////////////////////////////////////////
50 // class template Select
51 // Selects one of two types based upon a boolean constant
52 // Invocation: Select<flag, T, U>::Result
54 // flag is a compile-time boolean constant
56 // Result evaluates to T if flag is true, and to U otherwise.
57 ////////////////////////////////////////////////////////////////////////////////
59 template <bool flag, typename T, typename U>
64 template <typename T, typename U>
65 struct Select<false, T, U>
70 ////////////////////////////////////////////////////////////////////////////////
71 // class template IsSameType
72 // Return true iff two given types are the same
73 // Invocation: SameType<T, U>::value
76 // Result evaluates to true iff U == T (types equal)
77 ////////////////////////////////////////////////////////////////////////////////
79 template <typename T, typename U>
82 enum { value = false };
86 struct IsSameType<T,T>
88 enum { value = true };
91 ////////////////////////////////////////////////////////////////////////////////
92 // Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
93 ////////////////////////////////////////////////////////////////////////////////
97 template <class T, class U>
98 struct ConversionHelper
105 static Big Test(...);
106 static Small Test(U);
111 ////////////////////////////////////////////////////////////////////////////////
112 // class template Conversion
113 // Figures out the conversion relationships between two types
114 // Invocations (T and U are types):
115 // a) Conversion<T, U>::exists
116 // returns (at compile time) true if there is an implicit conversion from T
117 // to U (example: Derived to Base)
118 // b) Conversion<T, U>::exists2Way
119 // returns (at compile time) true if there are both conversions from T
120 // to U and from U to T (example: int to char and back)
121 // c) Conversion<T, U>::sameType
122 // returns (at compile time) true if T and U represent the same type
124 // Caveat: might not work if T and U are in a private inheritance hierarchy.
125 ////////////////////////////////////////////////////////////////////////////////
127 template <class T, class U>
130 typedef Private::ConversionHelper<T, U> H;
132 enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
134 enum { exists = false };
136 enum { exists2Way = exists && Conversion<U, T>::exists };
137 enum { sameType = false };
141 struct Conversion<T, T>
143 enum { exists = 1, exists2Way = 1, sameType = 1 };
147 struct Conversion<void, T>
149 enum { exists = 0, exists2Way = 0, sameType = 0 };
153 struct Conversion<T, void>
155 enum { exists = 0, exists2Way = 0, sameType = 0 };
159 struct Conversion<void, void>
162 enum { exists = 1, exists2Way = 1, sameType = 1 };
165 ////////////////////////////////////////////////////////////////////////////////
166 // class template SuperSubclass
167 // Invocation: SuperSubclass<B, D>::value where B and D are types.
168 // Returns true if B is a public base of D, or if B and D are aliases of the
171 // Caveat: might not work if T and U are in a private inheritance hierarchy.
172 ////////////////////////////////////////////////////////////////////////////////
174 template <class T, class U>
177 enum { value = (::Loki::Conversion<const volatile U *, const volatile T *>::exists &&
178 !::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
181 // Dummy enum to make sure that both classes are fully defined.
182 enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
186 struct SuperSubclass<void, void>
188 enum { value = false };
192 struct SuperSubclass<void, U>
194 enum { value = (::Loki::Conversion<const volatile U *, const volatile void *>::exists &&
195 !::Loki::Conversion<const volatile void *, const volatile void *>::sameType)
198 // Dummy enum to make sure that both classes are fully defined.
199 enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
203 struct SuperSubclass<T, void>
205 enum { value = (::Loki::Conversion<const volatile void *, const volatile T *>::exists &&
206 !::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
209 // Dummy enum to make sure that both classes are fully defined.
210 enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
213 ////////////////////////////////////////////////////////////////////////////////
214 // class template SuperSubclassStrict
215 // Invocation: SuperSubclassStrict<B, D>::value where B and D are types.
216 // Returns true if B is a public base of D.
218 // Caveat: might not work if T and U are in a private inheritance hierarchy.
219 ////////////////////////////////////////////////////////////////////////////////
221 template<class T,class U>
222 struct SuperSubclassStrict
224 enum { value = (::Loki::Conversion<const volatile U *, const volatile T *>::exists &&
225 !::Loki::Conversion<const volatile T *, const volatile void *>::sameType &&
226 !::Loki::Conversion<const volatile T *, const volatile U *>::sameType)
229 // Dummy enum to make sure that both classes are fully defined.
230 enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
234 struct SuperSubclassStrict<void, void>
236 enum { value = false };
240 struct SuperSubclassStrict<void, U>
242 enum { value = (::Loki::Conversion<const volatile U *, const volatile void *>::exists &&
243 !::Loki::Conversion<const volatile void *, const volatile void *>::sameType &&
244 !::Loki::Conversion<const volatile void *, const volatile U *>::sameType)
247 // Dummy enum to make sure that both classes are fully defined.
248 enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
252 struct SuperSubclassStrict<T, void>
254 enum { value = (::Loki::Conversion<const volatile void *, const volatile T *>::exists &&
255 !::Loki::Conversion<const volatile T *, const volatile void *>::sameType &&
256 !::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
259 // Dummy enum to make sure that both classes are fully defined.
260 enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
266 ////////////////////////////////////////////////////////////////////////////////
267 // macro SUPERSUBCLASS
268 // Invocation: SUPERSUBCLASS(B, D) where B and D are types.
269 // Returns true if B is a public base of D, or if B and D are aliases of the
272 // Caveat: might not work if T and U are in a private inheritance hierarchy.
273 // Deprecated: Use SuperSubclass class template instead.
274 ////////////////////////////////////////////////////////////////////////////////
276 #define LOKI_SUPERSUBCLASS(T, U) \
277 ::Loki::SuperSubclass<T,U>::value
279 ////////////////////////////////////////////////////////////////////////////////
280 // macro SUPERSUBCLASS_STRICT
281 // Invocation: SUPERSUBCLASS(B, D) where B and D are types.
282 // Returns true if B is a public base of D.
284 // Caveat: might not work if T and U are in a private inheritance hierarchy.
285 // Deprecated: Use SuperSubclassStrict class template instead.
286 ////////////////////////////////////////////////////////////////////////////////
288 #define LOKI_SUPERSUBCLASS_STRICT(T, U) \
289 ::Loki::SuperSubclassStrict<T,U>::value
292 #endif // end file guardian