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
37namespace Pt {
38
39template <typename T, T V>
40struct 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
51template <bool V>
52using BoolConstant = IntegralConstant<bool, V>;
53
54typedef BoolConstant<false> FalseType;
55typedef BoolConstant<true> TrueType;
56
57
58template<class T, class U>
59struct IsSame : FalseType
60{};
61
62
63template<class T>
64struct IsSame<T, T> : TrueType
65{};
66
67
68template <bool Condition, typename TrueT, typename FalseT>
69struct IfElse
70{
71 typedef TrueT Type;
72};
73
74
75template <typename TrueT, typename FalseT>
76struct IfElse<false, TrueT, FalseT>
77{
78 typedef FalseT Type;
79};
80
81
82template <std::size_t Index, typename T, typename... Ts>
83struct NthType
84{
85 typedef typename NthType<Index - 1, Ts...>::type type;
86};
87
88
89template <typename T, typename... Ts>
90struct NthType<0, T, Ts...>
91{
92 typedef T type;
93};
94
95
96template <typename T>
97struct 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
109template <typename T>
110struct 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
120template <typename T>
121struct 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
129template <typename T>
130struct 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
138template <typename T>
139struct 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
148template <typename T>
149struct 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
158template <typename T>
159struct 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
168template <typename T>
169struct 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
178template <typename T>
179struct 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
188template <typename T>
189struct 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
198template <typename T>
199struct 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
208template <typename T>
209struct 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
218template <typename T>
219struct 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
228template <typename T, std::size_t N>
229struct 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
238template <typename T, std::size_t N>
239struct 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
248template <typename T, std::size_t N>
249struct 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
258template <typename T, std::size_t N>
259struct 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
268template <typename T>
269struct 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
278template <typename T>
279struct 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
288template <typename T>
289struct 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
298template <typename T>
299struct 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
308template <typename R, typename... Args>
309struct 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
318template <typename R, typename... Args>
319struct 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
328template <typename R, typename... Args>
329struct 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
338template <>
339struct 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
355template <typename Base, typename Derived>
356class 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
383template <typename Base, typename Derived>
384class IsCompatible
385: public BoolConstant< IsCompatibleImpl<Base, Derived>::value >
386{};
387
388
389template <typename T>
390struct IntTraits
391{};
392
393template <>
394struct IntTraits<signed char>
395{
396 typedef unsigned char Unsigned;
397 typedef signed char Signed;
398
399 static const unsigned int isSigned = 1;
400};
401
402template <>
403struct IntTraits<unsigned char>
404{
405 typedef unsigned char Unsigned;
406 typedef signed char Signed;
407
408 static const unsigned int isSigned = 0;
409};
410
411template <>
412struct IntTraits<short>
413{
414 typedef unsigned short Unsigned;
415 typedef signed short Signed;
416
417 static const unsigned int isSigned = 1;
418};
419
420template <>
421struct IntTraits<unsigned short>
422{
423 typedef unsigned short Unsigned;
424 typedef signed short Signed;
425
426 static const unsigned int isSigned = 0;
427};
428
429template <>
430struct IntTraits<int>
431{
432 typedef unsigned int Unsigned;
433 typedef signed int Signed;
434
435 static const unsigned int isSigned = 1;
436};
437
438template <>
439struct IntTraits<unsigned int>
440{
441 typedef unsigned int Unsigned;
442 typedef signed int Signed;
443
444 static const unsigned int isSigned = 0;
445};
446
447template <>
448struct IntTraits<long>
449{
450 typedef unsigned long Unsigned;
451 typedef signed long Signed;
452
453 static const unsigned int isSigned = 1;
454};
455
456template <>
457struct IntTraits<unsigned long>
458{
459 typedef unsigned long Unsigned;
460 typedef signed long Signed;
461
462 static const unsigned int isSigned = 0;
463};
464
465template <>
466struct 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
474template <>
475struct 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
Traits for type properties.
Definition Api-TypeTraits.h:38
static const unsigned int isReference
If the type is a reference 1, otherwise 0.
Definition Api-TypeTraits.h:67
IMPLEMENTATION_DEFINED Pointer
The derived pointer type.
Definition Api-TypeTraits.h:52
static const unsigned int isConst
If the type is const 1, otherwise 0.
Definition Api-TypeTraits.h:58
IMPLEMENTATION_DEFINED ConstReference
The derived const qualified reference type.
Definition Api-TypeTraits.h:49
IMPLEMENTATION_DEFINED ConstPointer
The derived const qualified reference type.
Definition Api-TypeTraits.h:55
static const unsigned int isPointer
If the type is a pointer 1, otherwise 0.
Definition Api-TypeTraits.h:64
IMPLEMENTATION_DEFINED Reference
The derived reference type.
Definition Api-TypeTraits.h:46
static const unsigned int isVolatile
If the type is volatile 1, otherwise 0.
Definition Api-TypeTraits.h:61
IMPLEMENTATION_DEFINED Value
The derived value type.
Definition Api-TypeTraits.h:40