nlib
TypeTraits.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_TYPETRAITS_H_
17 #define INCLUDE_NN_NLIB_TYPETRAITS_H_
18 
19 #include "nn/nlib/Config.h"
20 
21 #ifndef NLIB_HAS_NATIVE_TYPETRAITS
22 
23 #ifdef __GLIBCXX__
24 #include <type_traits> // NOLINT
25 #endif
26 
27 NLIB_NAMESPACE_BEGIN
28 
29 // for std::integral_constant
30 template<class T, T v>
31 struct IntegralConstant {
32  static const T value = v;
33  typedef T value_type;
34  typedef IntegralConstant type;
35  operator value_type() const { return value; }
36 };
37 
38 // for std::true_type, std::false_type
39 typedef IntegralConstant<bool, true> TrueType;
40 typedef IntegralConstant<bool, false> FalseType;
41 
42 #define NLIB_DEF_TRUETYPE(name, tp) \
43  template<> struct name<tp> { typedef TrueType type; }
44 
45 namespace tt_detail {
46 
47 template<class T> struct my_or1 { typedef T type; };
48 
49 template<class T1, class T2> struct my_or2;
50 template<class T> struct my_or2<TrueType, T> { typedef TrueType type; };
51 template<class T> struct my_or2<FalseType, T> {
52  typedef typename my_or1<T>::type type;
53 };
54 
55 template<class T1, class T2, class T3> struct my_or3;
56 template<class T1, class T2> struct my_or3<TrueType, T1, T2> {
57  typedef TrueType type;
58 };
59 template<class T1, class T2> struct my_or3<FalseType, T1, T2> {
60  typedef typename my_or2<T1, T2>::type type;
61 };
62 
63 template<class T1, class T2, class T3, class T4> struct my_or4;
64 template<class T1, class T2, class T3> struct my_or4<TrueType, T1, T2, T3> {
65  typedef TrueType type;
66 };
67 template<class T1, class T2, class T3> struct my_or4<FalseType, T1, T2, T3> {
68  typedef typename my_or3<T1, T2, T3>::type type;
69 };
70 
71 template<class T1 = FalseType, class T2 = FalseType,
72  class T3 = FalseType, class T4 = FalseType>
73 struct my_or {
74  typedef typename my_or4<T1, T2, T3, T4>::type type;
75 };
76 
77 } // namespace tt_detail
78 
79 // for std::enable_if
80 template<bool B, class T = void> struct EnableIf {};
81 template<class T> struct EnableIf<true, T> { typedef T type; };
82 
83 // for std::conditional
84 template<bool B, class T, class F> struct Conditional { typedef T type; };
85 template<class T, class F> struct Conditional<false, T, F> { typedef F type; };
86 
87 // for std::remove_cv
88 template<class T> struct RemoveConst { typedef T type; };
89 template<class T> struct RemoveConst<const T> { typedef T type; };
90 
91 template<class T> struct RemoveVolatile { typedef T type; };
92 template<class T> struct RemoveVolatile<volatile T> { typedef T type; };
93 
94 template<class T>
95 struct RemoveCv {
96  typedef typename RemoveVolatile<typename RemoveConst<T>::type>::type type;
97 };
98 
99 // for std::remove_pointer
100 template<class T> struct RemovePtr { typedef T type; };
101 template<class T> struct RemovePtr<T*> { typedef T type; };
102 template<class T> struct RemovePtr<const T*> { typedef T type; };
103 template<class T> struct RemovePtr<volatile T*> { typedef T type; };
104 template<class T> struct RemovePtr<const volatile T*> { typedef T type; };
105 
106 // for std::remove_reference
107 template<class T> struct RemoveRef { typedef T type; };
108 template<class T> struct RemoveRef<T&> { typedef T type; };
109 
110 template<class T> struct AddRef { typedef T& type; };
111 template<> struct AddRef<void> { typedef void type; };
112 
113 // for std::is_same
114 template<class T1, class T2> struct IsSame : public FalseType {};
115 template<class T> struct IsSame<T, T> : public TrueType {};
116 
117 // for std::is_void
118 namespace tt_detail {
119 template<class T> struct is_void { typedef FalseType type; };
120 NLIB_DEF_TRUETYPE(is_void, void);
121 }
122 
123 template<class T>
124 struct IsVoid :
125  public tt_detail::is_void<typename RemoveCv<T>::type>::type {
126 };
127 
128 // for std::is_integral
129 namespace tt_detail {
130 
131 template<class T> struct is_integral_ex { typedef FalseType type; };
132 NLIB_DEF_TRUETYPE(is_integral_ex, signed char);
133 NLIB_DEF_TRUETYPE(is_integral_ex, signed short); // NOLINT
134 NLIB_DEF_TRUETYPE(is_integral_ex, signed int);
135 NLIB_DEF_TRUETYPE(is_integral_ex, signed long); // NOLINT
136 NLIB_DEF_TRUETYPE(is_integral_ex, signed long long); // NOLINT
137 
138 template<class T> struct is_integral { typedef FalseType type; };
139 NLIB_DEF_TRUETYPE(is_integral, bool);
140 NLIB_DEF_TRUETYPE(is_integral, char);
141 NLIB_DEF_TRUETYPE(is_integral, wchar_t);
142 NLIB_DEF_TRUETYPE(is_integral, short); // NOLINT
143 NLIB_DEF_TRUETYPE(is_integral, int);
144 NLIB_DEF_TRUETYPE(is_integral, long); // NOLINT
145 NLIB_DEF_TRUETYPE(is_integral, long long); // NOLINT
146 
147 NLIB_DEF_TRUETYPE(is_integral, unsigned char);
148 NLIB_DEF_TRUETYPE(is_integral, unsigned short); // NOLINT
149 NLIB_DEF_TRUETYPE(is_integral, unsigned int);
150 NLIB_DEF_TRUETYPE(is_integral, unsigned long long); // NOLINT
151 NLIB_DEF_TRUETYPE(is_integral, unsigned long); // NOLINT
152 } // namespace tt_detail
153 
154 template<class T>
155 struct IsIntegral
156  : public tt_detail::my_or<
157  typename tt_detail::is_integral<typename RemoveCv<T>::type>::type,
158  typename tt_detail::is_integral_ex<typename RemoveCv<T>::type>::type
159  >::type {
160 };
161 
162 // for std::is_signed
163 namespace tt_detail {
164 
165 template<class T> struct is_signed_ex { typedef FalseType type; };
166 NLIB_DEF_TRUETYPE(is_signed_ex, signed char);
167 NLIB_DEF_TRUETYPE(is_signed_ex, signed short); // NOLINT
168 NLIB_DEF_TRUETYPE(is_signed_ex, signed int);
169 NLIB_DEF_TRUETYPE(is_signed_ex, signed long); // NOLINT
170 NLIB_DEF_TRUETYPE(is_signed_ex, signed long long); // NOLINT
171 
172 template<class T> struct is_signed { typedef FalseType type; };
173 NLIB_DEF_TRUETYPE(is_signed, char);
174 NLIB_DEF_TRUETYPE(is_signed, short); // NOLINT
175 NLIB_DEF_TRUETYPE(is_signed, int);
176 NLIB_DEF_TRUETYPE(is_signed, long); // NOLINT
177 NLIB_DEF_TRUETYPE(is_signed, long long); // NOLINT
178 NLIB_DEF_TRUETYPE(is_signed, float);
179 NLIB_DEF_TRUETYPE(is_signed, double);
180 } // namespace tt_detail
181 
182 template<class T>
183 struct IsSigned
184  : public tt_detail::my_or<
185  typename tt_detail::is_signed<typename RemoveCv<T>::type>::type,
186  typename tt_detail::is_signed_ex<typename RemoveCv<T>::type>::type
187  >::type {
188 };
189 
190 template<class T> struct IsUnsigned { typedef FalseType type; };
191 template<> struct IsUnsigned<bool> { typedef TrueType type; };
192 template<> struct IsUnsigned<wchar_t> { typedef TrueType type; };
193 template<> struct IsUnsigned<unsigned char> { typedef TrueType type; };
194 template<> struct IsUnsigned<unsigned short> { typedef TrueType type; }; // NOLINT
195 template<> struct IsUnsigned<unsigned int> { typedef TrueType type; };
196 template<> struct IsUnsigned<unsigned long> { typedef TrueType type; }; // NOLINT
197 template<> struct IsUnsigned<unsigned long long> { typedef TrueType type; }; // NOLINT
198 
199 // for std::is_floating_point
200 namespace tt_detail {
201 
202 template<class T> struct is_floating_point { typedef FalseType type; };
203 NLIB_DEF_TRUETYPE(is_floating_point, float);
204 NLIB_DEF_TRUETYPE(is_floating_point, double);
205 NLIB_DEF_TRUETYPE(is_floating_point, long double);
206 
207 }
208 
209 template<class T>
210 struct IsFloatingPoint
211  : public tt_detail::is_floating_point<typename RemoveCv<T>::type>::type {
212 };
213 
214 // for std::is_arithmetic
215 template<class T>
216 struct IsArithmetic
217  : public IntegralConstant<
218  bool,
219  IsIntegral<T>::value || IsFloatingPoint<T>::value> {
220 };
221 
222 // for std::is_pointer
223 namespace tt_detail {
224 template<class T> struct IsPointerHelper : public FalseType {};
225 template<class T> struct IsPointerHelper<T*> : public TrueType {};
226 }
227 template<class T>
228 struct IsPointer :
229  public tt_detail::IsPointerHelper<typename RemoveCv<T>::type> {
230 };
231 
232 // for std::is_reference
233 template<class T> struct IsReference : public FalseType {};
234 template<class T> struct IsReference<T&> : public TrueType {};
235 
236 // for std::is_array
237 template<class T> struct IsArray : public FalseType {};
238 template<class T> struct IsArray<T[]> : public TrueType {};
239 template<class T, size_t N>
240 struct IsArray<T[N]> : public TrueType {};
241 
242 // for std::is_member_pointer
243 namespace tt_detail {
244 template<class T> struct is_member_pointer : public FalseType {};
245 template<class T, class U>
246 struct is_member_pointer<T U::*> : public TrueType {};
247 }
248 template<class T>
249 struct IsMemberPointer :
250  public tt_detail::is_member_pointer<typename RemoveCv<T>::type> {
251 };
252 
253 // for std::is_function
254 namespace tt_detail {
255 template<bool B> struct is_function_ { typedef FalseType type; };
256 template<> struct is_function_<true> { typedef TrueType type; };
257 template<class T>
258 struct is_function {
259  private:
260  typedef char One;
261  typedef struct { char a[2]; } Two;
262  template<class U> static One test(...);
263  template<class U> static Two test(U (*)[1]);
264 
265  public:
266 #ifdef CAFE
267 # pragma diag_suppress 1931
268 #endif
269  typedef typename is_function_<sizeof(test<T>(0)) == 1>::type type;
270 #ifdef CAFE
271 # pragma diag_warning 1931
272 #endif
273 };
274 template<class T> struct is_function<T&> { typedef FalseType type; };
275 template<> struct is_function<void> { typedef FalseType type; };
276 template<> struct is_function<const void> { typedef FalseType type; };
277 template<> struct is_function<volatile void> { typedef FalseType type; };
278 template<> struct is_function<const volatile void> { typedef FalseType type; };
279 } // namespace tt_detail
280 template<class T>
281 struct IsFunction : public tt_detail::is_function<T>::type {};
282 
283 #if !defined(NN_PLATFORM_CTR)
284 template<class T>
285 struct IsEnum :
286  public IntegralConstant<bool, __is_enum(T)> {
287 };
288 #else
289 // for std::is_enum
290 namespace tt_detail {
291 typedef char (&SizeOverOne)[2];
292 template<class T,
293  bool convert_possible =
294  !IsArithmetic<T>::value &&
295  !IsReference<T>::value &&
296  !IsPointer<T>::value &&
297  !IsMemberPointer<T>::value &&
298  !IsFunction<T>::value &&
299  !IsVoid<T>::value &&
300  !IsArray<T>::value>
301 struct ConsumeUDC {
302  operator T() const;
303 };
304 template<class T>
305 struct ConsumeUDC<T, false> {
306  operator SizeOverOne() const;
307 };
308 char enum_check(bool x);
309 char enum_check(char x);
310 char enum_check(signed char x);
311 char enum_check(unsigned char x);
312 char enum_check(wchar_t x);
313 char enum_check(signed short x); // NOLINT
314 char enum_check(unsigned short x); // NOLINT
315 char enum_check(signed int x);
316 char enum_check(unsigned int x);
317 char enum_check(signed long x); // NOLINT
318 char enum_check(unsigned long x); // NOLINT
319 char enum_check(signed long long x); // NOLINT
320 char enum_check(unsigned long long x); // NOLINT
321 char enum_check(float x);
322 char enum_check(double x);
323 char enum_check(long double x);
324 SizeOverOne enum_check(SizeOverOne x);
325 SizeOverOne enum_check(...);
326 template<class T>
327 struct is_enum {
328  enum {
329  value = sizeof(enum_check(ConsumeUDC<T>())) == 1
330  };
331 };
332 } // namespace tt_detail
333 
334 template<class T>
335 struct IsEnum
336  : public IntegralConstant<bool, tt_detail::is_enum<T>::value> {};
337 #endif
338 
339 #if !defined(NN_PLATFORM_CTR) && !defined(CAFE)
340 template<class T>
341 struct IsPod :
342  public IntegralConstant<bool,
343  __is_pod(T) || IsEnum<T>::value ||
344  IsArithmetic<T>::value || IsPointer<T>::value ||
345  IsMemberPointer<T>::value> {
346 };
347 
348 template<class T>
349 struct IsTriviallyDestructible :
350  public IntegralConstant<bool, __has_trivial_destructor(T)> {
351 };
352 #ifdef _MSC_VER
353 template<class T>
354 struct IsTriviallyDefaultConstructible :
355  public IntegralConstant<bool, __has_trivial_default_constructor(T)> {
356 };
357 #else
358 template<class T>
359 struct IsTriviallyDefaultConstructible :
360  public IntegralConstant<bool, std::has_trivial_default_constructor<T>::value > {
361 };
362 #endif
363 
364 #else
365 // for std::is_pod
366 namespace tt_detail {
367 
368 template<class T> struct is_pod
369  : public tt_detail::my_or<typename IsArithmetic<T>::type,
370  typename IsPointer<T>::type,
371  typename IsMemberPointer<T>::type,
372  typename IsEnum<T>::type>::type {
373 };
374 
375 template<class T>
376 struct is_pod<T[]> {
377  typedef typename is_pod<typename RemoveCv<T>::type>::type type;
378 };
379 template<class T, size_t N>
380 struct is_pod<T[N]> {
381  typedef typename is_pod<typename RemoveCv<T>::type>::type type;
382 };
383 
384 } // namespace tt_detail
385 
386 // NOTE: internal use only
387 // treats enum as non-POD.
388 // treats struct as non-POD.
389 //
390 // You have to define specialized IsPod when you have to use IsPos on struct.
391 // example:
392 // template<> struct IsPod<MyType> : public TrueType {};
393 template<class T>
394 struct IsTriviallyDestructible
395  : public tt_detail::is_pod<typename RemoveCv<T>::type>::type {
396 };
397 template<class T>
398 struct IsTriviallyDefaultConstructible
399  : public tt_detail::is_pod<typename RemoveCv<T>::type>::type {
400 };
401 
402 template<class T>
403 struct IsPod : public IsTriviallyDestructible<T> {};
404 #endif
405 
406 #if !defined(NN_PLATFORM_CTR)
407 template<class T>
408 struct IsEmpty :
409  public IntegralConstant<bool, __is_empty(T)> {
410 };
411 #else
412 // for std::is_empty
413 namespace tt_detail {
414 template<class T>
415 struct IsEmptyHelper1 : public T {
416  int data[256];
417 
418  private:
419  NLIB_DISALLOW_COPY_AND_ASSIGN(IsEmptyHelper1);
420 };
421 
422 struct IsEmptyHelper2 { int data[256]; };
423 } // namespace tt_detail
424 
425 template<class T>
426 struct IsEmpty :
427  public IntegralConstant<bool, sizeof(tt_detail::IsEmptyHelper1<T>) ==
428  sizeof(tt_detail::IsEmptyHelper2)> {
429 };
430 #endif
431 
432 #if !defined(NN_PLATFORM_CTR)
433 template<class T>
434 struct IsClass :
435  public IntegralConstant<bool, __is_class(T)> {
436 };
437 #else
438 // note that IsClass<union type>::value becomes true
439 template<class T>
440 class IsClass {
441  typedef char yes;
442  typedef struct { char a[2]; } no;
443 
444  template<class X>
445  static yes check(void (X::*)(void));
446  template<class X>
447  static no check(...);
448 
449  public:
450  static const bool value = sizeof(check<T>(NULL)) == sizeof(yes);
451 };
452 #endif
453 
454 // template<class T> struct AddLvalueReference { typedef T& type; };
455 // template<class T> struct AddLvalueReference<T&> { typedef T& type; };
456 
457 NLIB_NAMESPACE_END
458 
459 #undef NLIB_DEF_TRUETYPE
460 #else
461 
462 #include <type_traits> // NOLINT
463 NLIB_NAMESPACE_BEGIN
464 
465 #ifdef NLIB_HAS_TR1_TYPETRAITS
466 #define NLIB_DEF_REDIRECT(nlibstruct, stdstruct) \
467 template<class T> struct nlibstruct \
468  : public std::tr1::stdstruct<T> {}
469 template<class T, T v>
470 struct IntegralConstant
471  : public std::tr1::integral_constant<T, v> {
472 };
473 typedef std::tr1::true_type TrueType;
474 typedef std::tr1::false_type FalseType;
475 template<bool B, class T = void> struct EnableIf {};
476 template<class T> struct EnableIf<true, T> { typedef T type; };
477 template<bool B, class T, class F> struct Conditional { typedef T type; };
478 template<class T, class F> struct Conditional<false, T, F> { typedef F type; };
479 template<class T1, class T2>
480 struct IsSame : public std::tr1::is_same<T1, T2> {};
481 
482 NLIB_DEF_REDIRECT(IsTriviallyDestructible, has_trivial_destructor);
483 NLIB_DEF_REDIRECT(IsTriviallyDefaultConstructible, has_trivial_default_constructor);
484 
485 #else
486 #define NLIB_DEF_REDIRECT(nlibstruct, stdstruct) \
487 template<class T> struct nlibstruct \
488  : public std::stdstruct<T> {}
489 template<class T, T v>
490 struct IntegralConstant
491  : public std::integral_constant<T, v> {
492 };
493 typedef std::true_type TrueType;
494 typedef std::false_type FalseType;
495 template<bool B, class T> struct EnableIf : public std::enable_if<B, T> {};
496 template<bool B, class T, class F>
497 struct Conditional
498  : public std::conditional<B, T, F> {
499 };
500 template<class T1, class T2>
501 struct IsSame : public std::is_same<T1, T2> {};
502 
503 // still unimplemented
504 // #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20141011
505 #if defined(__GLIBCXX__)
506 template<class T>
507 struct IsTriviallyDestructible :
508  public IntegralConstant<bool, __has_trivial_destructor(T)> {
509 };
510 template<class T>
511 struct IsTriviallyDefaultConstructible :
512  public IntegralConstant<bool, __has_trivial_constructor(T)> {
513 };
514 #else
515 NLIB_DEF_REDIRECT(IsTriviallyDestructible, is_trivially_destructible);
516 NLIB_DEF_REDIRECT(IsTriviallyDefaultConstructible, is_trivially_constructible);
517 #endif
518 
519 #endif
520 
521 NLIB_DEF_REDIRECT(RemoveConst, remove_const);
522 NLIB_DEF_REDIRECT(RemoveVolatile, remove_volatile);
523 NLIB_DEF_REDIRECT(RemovePtr, remove_pointer);
524 NLIB_DEF_REDIRECT(RemoveRef, remove_reference);
525 NLIB_DEF_REDIRECT(AddRef, add_lvalue_reference);
526 NLIB_DEF_REDIRECT(RemoveCv, remove_cv);
527 NLIB_DEF_REDIRECT(IsVoid, is_void);
528 NLIB_DEF_REDIRECT(IsIntegral, is_integral);
529 NLIB_DEF_REDIRECT(IsSigned, is_signed);
530 NLIB_DEF_REDIRECT(IsUnsigned, is_unsigned);
531 NLIB_DEF_REDIRECT(IsFloatingPoint, is_floating_point);
532 NLIB_DEF_REDIRECT(IsArithmetic, is_arithmetic);
533 NLIB_DEF_REDIRECT(IsPointer, is_pointer);
534 NLIB_DEF_REDIRECT(IsReference, is_reference);
535 NLIB_DEF_REDIRECT(IsArray, is_array);
536 NLIB_DEF_REDIRECT(IsMemberPointer, is_member_pointer);
537 NLIB_DEF_REDIRECT(IsFunction, is_function);
538 NLIB_DEF_REDIRECT(IsEnum, is_enum);
539 
540 NLIB_DEF_REDIRECT(IsPod, is_pod);
541 NLIB_DEF_REDIRECT(IsEmpty, is_empty);
542 NLIB_DEF_REDIRECT(IsClass, is_class);
543 
544 NLIB_NAMESPACE_END
545 
546 #undef NLIB_DEF_REDIRECT
547 #endif
548 
549 NLIB_NAMESPACE_BEGIN
550 
551 namespace detail {
552 
553 template<class T>
554 class HasSwapMemFn {
555  typedef char yes;
556  typedef struct { char a[2]; } no;
557 
558  template<class X, void (X::*Func)(T&)>
559  struct helper {};
560  template<class X>
561  static yes check(helper<X, &X::swap>* p);
562  template<class X>
563  static no check(...);
564 
565  public:
566 #ifdef CAFE
567 # pragma diag_suppress 1931
568 #endif
569  static const bool value = sizeof(check<T>(NULL)) == sizeof(yes);
570 #ifdef CAFE
571 # pragma diag_warning 1931
572 #endif
573 };
574 
575 template<class T, bool isClass>
576 struct IsSwappable_ :
577  public IntegralConstant<bool, detail::HasSwapMemFn<T>::value> {
578 };
579 
580 template<class T>
581 struct IsSwappable_<T, false> :
582  public IntegralConstant<
583  bool,
584  IsArithmetic<T>::value ||
585  IsPointer<T>::value ||
586  IsFunction<T>::value ||
587  IsMemberPointer<T>::value ||
588  IsEnum<T>::value
589  > {
590 };
591 
592 } // namespace detail
593 
594 // true if T has swap(T&) member function
595 // or T is a simple value.
596 // T may be swappable if IsSwappable<T>::value is false.
597 template<class T>
598 struct IsSwappable : public detail::IsSwappable_<T, IsClass<T>::value> {};
599 
600 NLIB_NAMESPACE_END
601 
602 #endif // INCLUDE_NN_NLIB_TYPETRAITS_H_
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:163
A file that contains the configuration information for each development environment.