Writing - finished to the printed version.
[fic.git] / FerrisLoki / TypeManip.h
blobd68bd2caf6fb0ff7c23422a1a24cfc43694d0116
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 #ifndef LOKI_TYPEMANIP_INC_
16 #define LOKI_TYPEMANIP_INC_
18 // $Id: TypeManip.h,v 1.1 2007/12/10 11:58:52 ben Exp $
21 namespace Loki
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 ////////////////////////////////////////////////////////////////////////////////
30 template <int v>
31 struct Int2Type
33 enum { value = v };
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 ////////////////////////////////////////////////////////////////////////////////
43 template <typename T>
44 struct Type2Type
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
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 ////////////////////////////////////////////////////////////////////////////////
59 template <bool flag, typename T, typename U>
60 struct Select
62 typedef T Result;
64 template <typename T, typename U>
65 struct Select<false, T, U>
67 typedef U Result;
70 ////////////////////////////////////////////////////////////////////////////////
71 // class template IsSameType
72 // Return true iff two given types are the same
73 // Invocation: SameType<T, U>::value
74 // where:
75 // T and U are types
76 // Result evaluates to true iff U == T (types equal)
77 ////////////////////////////////////////////////////////////////////////////////
79 template <typename T, typename U>
80 struct IsSameType
82 enum { value = false };
85 template <typename T>
86 struct IsSameType<T,T>
88 enum { value = true };
91 ////////////////////////////////////////////////////////////////////////////////
92 // Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
93 ////////////////////////////////////////////////////////////////////////////////
95 namespace Private
97 template <class T, class U>
98 struct ConversionHelper
100 typedef char Small;
101 struct Big { char dummy[2]; };
102 static Big Test(...);
103 static Small Test(U);
104 static T MakeT();
108 ////////////////////////////////////////////////////////////////////////////////
109 // class template Conversion
110 // Figures out the conversion relationships between two types
111 // Invocations (T and U are types):
112 // a) Conversion<T, U>::exists
113 // returns (at compile time) true if there is an implicit conversion from T
114 // to U (example: Derived to Base)
115 // b) Conversion<T, U>::exists2Way
116 // returns (at compile time) true if there are both conversions from T
117 // to U and from U to T (example: int to char and back)
118 // c) Conversion<T, U>::sameType
119 // returns (at compile time) true if T and U represent the same type
121 // Caveat: might not work if T and U are in a private inheritance hierarchy.
122 ////////////////////////////////////////////////////////////////////////////////
124 template <class T, class U>
125 struct Conversion
127 typedef Private::ConversionHelper<T, U> H;
128 #ifndef __MWERKS__
129 enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
130 #else
131 enum { exists = false };
132 #endif
133 enum { exists2Way = exists && Conversion<U, T>::exists };
134 enum { sameType = false };
137 template <class T>
138 struct Conversion<T, T>
140 enum { exists = 1, exists2Way = 1, sameType = 1 };
143 template <class T>
144 struct Conversion<void, T>
146 enum { exists = 0, exists2Way = 0, sameType = 0 };
149 template <class T>
150 struct Conversion<T, void>
152 enum { exists = 0, exists2Way = 0, sameType = 0 };
155 template <>
156 struct Conversion<void, void>
158 public:
159 enum { exists = 1, exists2Way = 1, sameType = 1 };
162 ////////////////////////////////////////////////////////////////////////////////
163 // class template SuperSubclass
164 // Invocation: SuperSubclass<B, D>::value where B and D are types.
165 // Returns true if B is a public base of D, or if B and D are aliases of the
166 // same type.
168 // Caveat: might not work if T and U are in a private inheritance hierarchy.
169 ////////////////////////////////////////////////////////////////////////////////
171 template <class T, class U>
172 struct SuperSubclass
174 enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
175 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
177 // Dummy enum to make sure that both classes are fully defined.
178 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
181 template <>
182 struct SuperSubclass<void, void>
184 enum { value = false };
187 template <class U>
188 struct SuperSubclass<void, U>
190 enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
191 !::Loki::Conversion<const volatile void*, const volatile void*>::sameType) };
193 // Dummy enum to make sure that both classes are fully defined.
194 enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
197 template <class T>
198 struct SuperSubclass<T, void>
200 enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
201 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
203 // Dummy enum to make sure that both classes are fully defined.
204 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
207 ////////////////////////////////////////////////////////////////////////////////
208 // class template SuperSubclassStrict
209 // Invocation: SuperSubclassStrict<B, D>::value where B and D are types.
210 // Returns true if B is a public base of D.
212 // Caveat: might not work if T and U are in a private inheritance hierarchy.
213 ////////////////////////////////////////////////////////////////////////////////
215 template<class T,class U>
216 struct SuperSubclassStrict
218 enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
219 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
220 !::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
222 // Dummy enum to make sure that both classes are fully defined.
223 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
226 template<>
227 struct SuperSubclassStrict<void, void>
229 enum { value = false };
232 template<class U>
233 struct SuperSubclassStrict<void, U>
235 enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
236 !::Loki::Conversion<const volatile void*, const volatile void*>::sameType &&
237 !::Loki::Conversion<const volatile void*, const volatile U*>::sameType) };
239 // Dummy enum to make sure that both classes are fully defined.
240 enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
243 template<class T>
244 struct SuperSubclassStrict<T, void>
246 enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
247 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
248 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
250 // Dummy enum to make sure that both classes are fully defined.
251 enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
255 } // namespace Loki
257 ////////////////////////////////////////////////////////////////////////////////
258 // macro SUPERSUBCLASS
259 // Invocation: SUPERSUBCLASS(B, D) where B and D are types.
260 // Returns true if B is a public base of D, or if B and D are aliases of the
261 // same type.
263 // Caveat: might not work if T and U are in a private inheritance hierarchy.
264 // Deprecated: Use SuperSubclass class template instead.
265 ////////////////////////////////////////////////////////////////////////////////
267 #define LOKI_SUPERSUBCLASS(T, U) \
268 ::Loki::SuperSubclass<T,U>::value
270 ////////////////////////////////////////////////////////////////////////////////
271 // macro SUPERSUBCLASS_STRICT
272 // Invocation: SUPERSUBCLASS(B, D) where B and D are types.
273 // Returns true if B is a public base of D.
275 // Caveat: might not work if T and U are in a private inheritance hierarchy.
276 // Deprecated: Use SuperSubclassStrict class template instead.
277 ////////////////////////////////////////////////////////////////////////////////
279 #define LOKI_SUPERSUBCLASS_STRICT(T, U) \
280 ::Loki::SuperSubclassStrict<T,U>::value
283 #endif // end file guardian