TypeTraits.h
1 /*
2  Copyright (C) 2016 Marc Boris Duerner
3  Copyright (C) 2016 Aloysius Indrayanto
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  As a special exception, you may use this file as part of a free
11  software library without restriction. Specifically, if other files
12  instantiate templates or use macros or inline functions from this
13  file, or you compile this file and link it with other files to
14  produce an executable, this file does not by itself cause the
15  resulting executable to be covered by the GNU General Public
16  License. This exception does not however invalidate any other
17  reasons why the executable file might be covered by the GNU Library
18  General Public License.
19 
20  This library is distributed in the hope that it will be useful,
21  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23  Lesser General Public License for more details.
24 
25  You should have received a copy of the GNU Lesser General Public
26  License along with this library; if not, write to the:
27  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28  Boston, MA 02110-1301 USA
29 */
30 
31 #ifndef Pt_TypeTraits_h
32 #define Pt_TypeTraits_h
33 
34 #include <Pt/Api.h>
35 #include <cstddef>
36 
37 namespace Pt {
38 
39 template <typename T, T V>
40 struct IntegralConstant
41 {
42  static const T value = V;
43  typedef T ValueType;
44  typedef IntegralConstant<T, V> Type;
45 
46  operator ValueType() const
47  { return value; }
48 };
49 
50 
51 template <bool V>
52 using BoolConstant = IntegralConstant<bool, V>;
53 
54 typedef BoolConstant<false> FalseType;
55 typedef BoolConstant<true> TrueType;
56 
57 
58 template<class T, class U>
59 struct IsSame : FalseType
60 {};
61 
62 
63 template<class T>
64 struct IsSame<T, T> : TrueType
65 {};
66 
67 
68 template <bool Condition, typename TrueT, typename FalseT>
69 struct IfElse
70 {
71  typedef TrueT Type;
72 };
73 
74 
75 template <typename TrueT, typename FalseT>
76 struct IfElse<false, TrueT, FalseT>
77 {
78  typedef FalseT Type;
79 };
80 
81 
82 template <std::size_t Index, typename T, typename... Ts>
83 struct NthType
84 {
85  typedef typename NthType<Index - 1, Ts...>::type type;
86 };
87 
88 
89 template <typename T, typename... Ts>
90 struct NthType<0, T, Ts...>
91 {
92  typedef T type;
93 };
94 
95 
96 template <typename T>
97 struct TypeTraitsBase
98 {
99  typedef T Value;
100  typedef const T ConstValue;
101  typedef T& Reference;
102  typedef const T& ConstReference;
103  typedef T* Pointer;
104  typedef const T* ConstPointer;
105 };
106 
108 
109 template <typename T>
110 struct TypeTraits : public TypeTraitsBase<T>
111 {
112  static const unsigned int isConst = 0;
113  static const unsigned int isVolatile = 0;
114  static const unsigned int isPointer = 0;
115  static const unsigned int isReference = 0;
116 };
117 
119 
120 template <typename T>
121 struct TypeTraits<const T> : public TypeTraitsBase<T>
122 {
123  static const unsigned int isConst = 1;
124  static const unsigned int isVolatile = 0;
125  static const unsigned int isPointer = 0;
126  static const unsigned int isReference = 0;
127 };
128 
129 template <typename T>
130 struct TypeTraits<volatile T> : public TypeTraitsBase<T>
131 {
132  static const unsigned int isConst = 0;
133  static const unsigned int isVolatile = 1;
134  static const unsigned int isPointer = 0;
135  static const unsigned int isReference = 0;
136 };
137 
138 template <typename T>
139 struct TypeTraits<const volatile T> : public TypeTraitsBase<T>
140 {
141  static const unsigned int isConst = 1;
142  static const unsigned int isVolatile = 1;
143  static const unsigned int isPointer = 0;
144  static const unsigned int isReference = 0;
145 };
146 
147 
148 template <typename T>
149 struct TypeTraits<T&> : public TypeTraitsBase<T>
150 {
151  static const unsigned int isConst = 0;
152  static const unsigned int isVolatile = 0;
153  static const unsigned int isPointer = 0;
154  static const unsigned int isReference = 1;
155 };
156 
157 
158 template <typename T>
159 struct TypeTraits<const T&> : public TypeTraitsBase<T>
160 {
161  static const unsigned int isConst = 1;
162  static const unsigned int isVolatile = 0;
163  static const unsigned int isPointer = 0;
164  static const unsigned int isReference = 1;
165 };
166 
167 
168 template <typename T>
169 struct TypeTraits<volatile T&> : public TypeTraitsBase<T>
170 {
171  static const unsigned int isConst = 0;
172  static const unsigned int isVolatile = 1;
173  static const unsigned int isPointer = 0;
174  static const unsigned int isReference = 1;
175 };
176 
177 
178 template <typename T>
179 struct TypeTraits<const volatile T&> : public TypeTraitsBase<T>
180 {
181  static const unsigned int isConst = 1;
182  static const unsigned int isVolatile = 1;
183  static const unsigned int isPointer = 0;
184  static const unsigned int isReference = 1;
185 };
186 
187 
188 template <typename T>
189 struct TypeTraits<T*> : public TypeTraitsBase<T>
190 {
191  static const unsigned int isConst = 0;
192  static const unsigned int isVolatile = 0;
193  static const unsigned int isPointer = 1;
194  static const unsigned int isReference = 0;
195 };
196 
197 
198 template <typename T>
199 struct TypeTraits<const T*> : public TypeTraitsBase<T>
200 {
201  static const unsigned int isConst = 1;
202  static const unsigned int isVolatile = 0;
203  static const unsigned int isPointer = 1;
204  static const unsigned int isReference = 0;
205 };
206 
207 
208 template <typename T>
209 struct TypeTraits<volatile T*> : public TypeTraitsBase<T>
210 {
211  static const unsigned int isConst = 0;
212  static const unsigned int isVolatile = 1;
213  static const unsigned int isPointer = 1;
214  static const unsigned int isReference = 0;
215 };
216 
217 
218 template <typename T>
219 struct TypeTraits<const volatile T*> : public TypeTraitsBase<T>
220 {
221  static const unsigned int isConst = 1;
222  static const unsigned int isVolatile = 1;
223  static const unsigned int isPointer = 1;
224  static const unsigned int isReference = 0;
225 };
226 
227 
228 template <typename T, std::size_t N>
229 struct TypeTraits<T[N]> : public TypeTraitsBase<T*>
230 {
231  static const unsigned int isConst = 0;
232  static const unsigned int isVolatile = 0;
233  static const unsigned int isPointer = 1;
234  static const unsigned int isReference = 0;
235 };
236 
237 
238 template <typename T, std::size_t N>
239 struct TypeTraits<const T[N]> : public TypeTraitsBase<const T*>
240 {
241  static const unsigned int isConst = 1;
242  static const unsigned int isVolatile = 0;
243  static const unsigned int isPointer = 1;
244  static const unsigned int isReference = 0;
245 };
246 
247 
248 template <typename T, std::size_t N>
249 struct TypeTraits<volatile T[N]> : public TypeTraitsBase<volatile T*>
250 {
251  static const unsigned int isConst = 0;
252  static const unsigned int isVolatile = 1;
253  static const unsigned int isPointer = 1;
254  static const unsigned int isReference = 0;
255 };
256 
257 
258 template <typename T, std::size_t N>
259 struct TypeTraits<const volatile T[N]> : public TypeTraitsBase<const volatile T*>
260 {
261  static const unsigned int isConst = 1;
262  static const unsigned int isVolatile = 1;
263  static const unsigned int isPointer = 1;
264  static const unsigned int isReference = 0;
265 };
266 
267 
268 template <typename T>
269 struct TypeTraits<T[]> : public TypeTraitsBase<T*>
270 {
271  static const unsigned int isConst = 0;
272  static const unsigned int isVolatile = 0;
273  static const unsigned int isPointer = 1;
274  static const unsigned int isReference = 0;
275 };
276 
277 
278 template <typename T>
279 struct TypeTraits<const T[]> : public TypeTraitsBase<const T*>
280 {
281  static const unsigned int isConst = 1;
282  static const unsigned int isVolatile = 0;
283  static const unsigned int isPointer = 1;
284  static const unsigned int isReference = 0;
285 };
286 
287 
288 template <typename T>
289 struct TypeTraits<volatile T[]> : public TypeTraitsBase<volatile T*>
290 {
291  static const unsigned int isConst = 0;
292  static const unsigned int isVolatile = 1;
293  static const unsigned int isPointer = 1;
294  static const unsigned int isReference = 0;
295 };
296 
297 
298 template <typename T>
299 struct TypeTraits<const volatile T[]> : public TypeTraitsBase<const volatile T*>
300 {
301  static const unsigned int isConst = 1;
302  static const unsigned int isVolatile = 1;
303  static const unsigned int isPointer = 1;
304  static const unsigned int isReference = 0;
305 };
306 
307 
308 template <typename R, typename... Args>
309 struct TypeTraits<R(*)(Args...)> : public TypeTraitsBase<R(*)(Args...)>
310 {
311  static const unsigned int isConst = 0;
312  static const unsigned int isVolatile = 0;
313  static const unsigned int isPointer = 1;
314  static const unsigned int isReference = 0;
315 };
316 
317 
318 template <typename R, typename... Args>
319 struct TypeTraits<R(Args...)> : public TypeTraitsBase<R(*)(Args...)>
320 {
321  static const unsigned int isConst = 0;
322  static const unsigned int isVolatile = 0;
323  static const unsigned int isPointer = 0;
324  static const unsigned int isReference = 0;
325 };
326 
327 
328 template <typename R, typename... Args>
329 struct TypeTraits<R(&)(Args...)> : public TypeTraitsBase<R(*)(Args...)>
330 {
331  static const unsigned int isConst = 0;
332  static const unsigned int isVolatile = 0;
333  static const unsigned int isPointer = 0;
334  static const unsigned int isReference = 1;
335 };
336 
337 
338 template <>
339 struct TypeTraits<void>
340 {
341  typedef void Value;
342  typedef void ConstType;
343  typedef void Reference;
344  typedef void ConstReference;
345  typedef void* Pointer;
346  typedef void* ConstPointer;
347 
348  static const unsigned int isConst = 0;
349  static const unsigned int isVolatile = 0;
350  static const unsigned int isPointer = 0;
351  static const unsigned int isReference = 0;
352 };
353 
354 
355 template <typename Base, typename Derived>
356 class IsCompatibleImpl
357 {
358  private:
359  struct YesType
360  {
361  char value;
362  };
363 
364  struct NoType
365  {
366  char value[2];
367  };
368 
369  typedef typename TypeTraits<Base>::Value BaseType;
370  typedef typename TypeTraits<Derived>::Value DerivedType;
371 
372  static YesType test(BaseType*);
373  static NoType test(...);
374 
375  public:
376  enum
377  {
378  value = sizeof(test(static_cast<DerivedType*>(0))) == sizeof(YesType)
379  };
380 };
381 
382 
383 template <typename Base, typename Derived>
384 class IsCompatible
385 : public BoolConstant< IsCompatibleImpl<Base, Derived>::value >
386 {};
387 
388 
389 template <typename T>
390 struct IntTraits
391 {};
392 
393 template <>
394 struct IntTraits<signed char>
395 {
396  typedef unsigned char Unsigned;
397  typedef signed char Signed;
398 
399  static const unsigned int isSigned = 1;
400 };
401 
402 template <>
403 struct IntTraits<unsigned char>
404 {
405  typedef unsigned char Unsigned;
406  typedef signed char Signed;
407 
408  static const unsigned int isSigned = 0;
409 };
410 
411 template <>
412 struct IntTraits<short>
413 {
414  typedef unsigned short Unsigned;
415  typedef signed short Signed;
416 
417  static const unsigned int isSigned = 1;
418 };
419 
420 template <>
421 struct IntTraits<unsigned short>
422 {
423  typedef unsigned short Unsigned;
424  typedef signed short Signed;
425 
426  static const unsigned int isSigned = 0;
427 };
428 
429 template <>
430 struct IntTraits<int>
431 {
432  typedef unsigned int Unsigned;
433  typedef signed int Signed;
434 
435  static const unsigned int isSigned = 1;
436 };
437 
438 template <>
439 struct IntTraits<unsigned int>
440 {
441  typedef unsigned int Unsigned;
442  typedef signed int Signed;
443 
444  static const unsigned int isSigned = 0;
445 };
446 
447 template <>
448 struct IntTraits<long>
449 {
450  typedef unsigned long Unsigned;
451  typedef signed long Signed;
452 
453  static const unsigned int isSigned = 1;
454 };
455 
456 template <>
457 struct IntTraits<unsigned long>
458 {
459  typedef unsigned long Unsigned;
460  typedef signed long Signed;
461 
462  static const unsigned int isSigned = 0;
463 };
464 
465 template <>
466 struct IntTraits<long long>
467 {
468  typedef unsigned long long Unsigned;
469  typedef signed long long Signed;
470 
471  static const unsigned int isSigned = 1;
472 };
473 
474 template <>
475 struct IntTraits<unsigned long long>
476 {
477  typedef unsigned long long Unsigned;
478  typedef signed long long Signed;
479 
480  static const unsigned int isSigned = 0;
481 };
482 
483 } // namespace Pt
484 
485 #endif // Pt_TypeTraits_h
Core module.
Definition: Allocator.h:33
static const unsigned int isReference
If the type is a reference 1, otherwise 0.
Definition: Api-TypeTraits.h:49
IMPLEMENTATION_DEFINED ConstReference
The derived const qualified reference type.
Definition: Api-TypeTraits.h:31
static const unsigned int isPointer
If the type is a pointer 1, otherwise 0.
Definition: Api-TypeTraits.h:46
IMPLEMENTATION_DEFINED Pointer
The derived pointer type.
Definition: Api-TypeTraits.h:34
IMPLEMENTATION_DEFINED Reference
The derived reference type.
Definition: Api-TypeTraits.h:28
IMPLEMENTATION_DEFINED Value
The derived value type.
Definition: Api-TypeTraits.h:22
static const unsigned int isVolatile
If the type is volatile 1, otherwise 0.
Definition: Api-TypeTraits.h:43
IMPLEMENTATION_DEFINED ConstPointer
The derived const qualified reference type.
Definition: Api-TypeTraits.h:37
static const unsigned int isConst
If the type is const 1, otherwise 0.
Definition: Api-TypeTraits.h:40