]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/TypeManip.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / 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 #ifndef LOKI_TYPEMANIP_INC_
16 #define LOKI_TYPEMANIP_INC_
17
18 // $Id: TypeManip.h 749 2006-10-17 19:49:26Z syntheticpp $
19
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 // 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 ////////////////////////////////////////////////////////////////////////////////
78
79 template <typename T, typename U>
80 struct IsSameType
81 {
82         enum { value = false };
83 };
84
85 template <typename T>
86 struct IsSameType<T,T>
87 {
88         enum { value = true };
89 };
90
91 ////////////////////////////////////////////////////////////////////////////////
92 // Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
93 ////////////////////////////////////////////////////////////////////////////////
94
95 namespace Private
96 {
97 template <class T, class U>
98 struct ConversionHelper
99 {
100         typedef char Small;
101         struct Big
102         {
103                 char dummy[2];
104         };
105         static Big   Test(...);
106         static Small Test(U);
107         static T MakeT();
108 };
109 }
110
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
123 //
124 // Caveat: might not work if T and U are in a private inheritance hierarchy.
125 ////////////////////////////////////////////////////////////////////////////////
126
127 template <class T, class U>
128 struct Conversion
129 {
130         typedef Private::ConversionHelper<T, U> H;
131 #ifndef __MWERKS__
132         enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
133 #else
134         enum { exists = false };
135 #endif
136         enum { exists2Way = exists && Conversion<U, T>::exists };
137         enum { sameType = false };
138 };
139
140 template <class T>
141 struct Conversion<T, T>
142 {
143         enum { exists = 1, exists2Way = 1, sameType = 1 };
144 };
145
146 template <class T>
147 struct Conversion<void, T>
148 {
149         enum { exists = 0, exists2Way = 0, sameType = 0 };
150 };
151
152 template <class T>
153 struct Conversion<T, void>
154 {
155         enum { exists = 0, exists2Way = 0, sameType = 0 };
156 };
157
158 template <>
159 struct Conversion<void, void>
160 {
161 public:
162         enum { exists = 1, exists2Way = 1, sameType = 1 };
163 };
164
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
169 // same type.
170 //
171 // Caveat: might not work if T and U are in a private inheritance hierarchy.
172 ////////////////////////////////////////////////////////////////////////////////
173
174 template <class T, class U>
175 struct SuperSubclass
176 {
177         enum { value = (::Loki::Conversion<const volatile U *, const volatile T *>::exists &&
178                         !::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
179              };
180
181         // Dummy enum to make sure that both classes are fully defined.
182         enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
183 };
184
185 template <>
186 struct SuperSubclass<void, void>
187 {
188         enum { value = false };
189 };
190
191 template <class U>
192 struct SuperSubclass<void, U>
193 {
194         enum { value = (::Loki::Conversion<const volatile U *, const volatile void *>::exists &&
195                         !::Loki::Conversion<const volatile void *, const volatile void *>::sameType)
196              };
197
198         // Dummy enum to make sure that both classes are fully defined.
199         enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
200 };
201
202 template <class T>
203 struct SuperSubclass<T, void>
204 {
205         enum { value = (::Loki::Conversion<const volatile void *, const volatile T *>::exists &&
206                         !::Loki::Conversion<const volatile T *, const volatile void *>::sameType)
207              };
208
209         // Dummy enum to make sure that both classes are fully defined.
210         enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
211 };
212
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.
217 //
218 // Caveat: might not work if T and U are in a private inheritance hierarchy.
219 ////////////////////////////////////////////////////////////////////////////////
220
221 template<class T,class U>
222 struct SuperSubclassStrict
223 {
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)
227              };
228
229         // Dummy enum to make sure that both classes are fully defined.
230         enum { dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
231 };
232
233 template<>
234 struct SuperSubclassStrict<void, void>
235 {
236         enum { value = false };
237 };
238
239 template<class U>
240 struct SuperSubclassStrict<void, U>
241 {
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)
245              };
246
247         // Dummy enum to make sure that both classes are fully defined.
248         enum { dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
249 };
250
251 template<class T>
252 struct SuperSubclassStrict<T, void>
253 {
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)
257              };
258
259         // Dummy enum to make sure that both classes are fully defined.
260         enum { dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
261 };
262
263
264 }   // namespace Loki
265
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
270 // same type.
271 //
272 // Caveat: might not work if T and U are in a private inheritance hierarchy.
273 // Deprecated: Use SuperSubclass class template instead.
274 ////////////////////////////////////////////////////////////////////////////////
275
276 #define LOKI_SUPERSUBCLASS(T, U) \
277     ::Loki::SuperSubclass<T,U>::value
278
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.
283 //
284 // Caveat: might not work if T and U are in a private inheritance hierarchy.
285 // Deprecated: Use SuperSubclassStrict class template instead.
286 ////////////////////////////////////////////////////////////////////////////////
287
288 #define LOKI_SUPERSUBCLASS_STRICT(T, U) \
289     ::Loki::SuperSubclassStrict<T,U>::value
290
291
292 #endif // end file guardian
293