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>
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<> \
44  struct name<tp> { \
45  typedef TrueType type; \
46  }
47 
48 namespace tt_detail {
49 
50 template<class T>
51 struct my_or1 {
52  typedef T type;
53 };
54 
55 template<class T1, class T2>
56 struct my_or2;
57 template<class T>
58 struct my_or2<TrueType, T> {
59  typedef TrueType type;
60 };
61 template<class T>
62 struct my_or2<FalseType, T> {
63  typedef typename my_or1<T>::type type;
64 };
65 
66 template<class T1, class T2, class T3>
67 struct my_or3;
68 template<class T1, class T2>
69 struct my_or3<TrueType, T1, T2> {
70  typedef TrueType type;
71 };
72 template<class T1, class T2>
73 struct my_or3<FalseType, T1, T2> {
74  typedef typename my_or2<T1, T2>::type type;
75 };
76 
77 template<class T1, class T2, class T3, class T4>
78 struct my_or4;
79 template<class T1, class T2, class T3>
80 struct my_or4<TrueType, T1, T2, T3> {
81  typedef TrueType type;
82 };
83 template<class T1, class T2, class T3>
84 struct my_or4<FalseType, T1, T2, T3> {
85  typedef typename my_or3<T1, T2, T3>::type type;
86 };
87 
88 template<class T1 = FalseType, class T2 = FalseType, class T3 = FalseType, class T4 = FalseType>
89 struct my_or {
90  typedef typename my_or4<T1, T2, T3, T4>::type type;
91 };
92 
93 } // namespace tt_detail
94 
95 // for std::enable_if
96 template<bool B, class T = void>
97 struct EnableIf {};
98 template<class T>
99 struct EnableIf<true, T> {
100  typedef T type;
101 };
102 
103 // for std::conditional
104 template<bool B, class T, class F>
105 struct Conditional {
106  typedef T type;
107 };
108 template<class T, class F>
109 struct Conditional<false, T, F> {
110  typedef F type;
111 };
112 
113 // for std::remove_cv
114 template<class T>
115 struct RemoveConst {
116  typedef T type;
117 };
118 template<class T>
119 struct RemoveConst<const T> {
120  typedef T type;
121 };
122 
123 template<class T>
124 struct RemoveVolatile {
125  typedef T type;
126 };
127 template<class T>
128 struct RemoveVolatile<volatile T> {
129  typedef T type;
130 };
131 
132 template<class T>
133 struct RemoveCv {
134  typedef typename RemoveVolatile<typename RemoveConst<T>::type>::type type;
135 };
136 
137 // for std::remove_pointer
138 template<class T>
139 struct RemovePtr {
140  typedef T type;
141 };
142 template<class T>
143 struct RemovePtr<T*> {
144  typedef T type;
145 };
146 template<class T>
147 struct RemovePtr<const T*> {
148  typedef T type;
149 };
150 template<class T>
151 struct RemovePtr<volatile T*> {
152  typedef T type;
153 };
154 template<class T>
155 struct RemovePtr<const volatile T*> {
156  typedef T type;
157 };
158 
159 // for std::remove_reference
160 template<class T>
161 struct RemoveRef {
162  typedef T type;
163 };
164 template<class T>
165 struct RemoveRef<T&> {
166  typedef T type;
167 };
168 
169 template<class T>
170 struct AddRef {
171  typedef T& type;
172 };
173 template<>
174 struct AddRef<void> {
175  typedef void type;
176 };
177 
178 // for std::is_same
179 template<class T1, class T2>
180 struct IsSame : public FalseType {};
181 template<class T>
182 struct IsSame<T, T> : public TrueType {};
183 
184 // for std::is_void
185 namespace tt_detail {
186 template<class T>
187 struct is_void {
188  typedef FalseType type;
189 };
190 NLIB_DEF_TRUETYPE(is_void, void);
191 } // namespace tt_detail
192 
193 template<class T>
194 struct IsVoid : public tt_detail::is_void<typename RemoveCv<T>::type>::type {};
195 
196 // for std::is_integral
197 namespace tt_detail {
198 
199 template<class T>
200 struct is_integral_ex {
201  typedef FalseType type;
202 };
203 NLIB_DEF_TRUETYPE(is_integral_ex, signed char);
204 NLIB_DEF_TRUETYPE(is_integral_ex, signed short);
205 NLIB_DEF_TRUETYPE(is_integral_ex, signed int);
206 NLIB_DEF_TRUETYPE(is_integral_ex, signed long);
207 NLIB_DEF_TRUETYPE(is_integral_ex, signed long long);
208 
209 template<class T>
210 struct is_integral {
211  typedef FalseType type;
212 };
213 NLIB_DEF_TRUETYPE(is_integral, bool);
214 NLIB_DEF_TRUETYPE(is_integral, char);
215 NLIB_DEF_TRUETYPE(is_integral, wchar_t);
216 NLIB_DEF_TRUETYPE(is_integral, short);
217 NLIB_DEF_TRUETYPE(is_integral, int);
218 NLIB_DEF_TRUETYPE(is_integral, long);
219 NLIB_DEF_TRUETYPE(is_integral, long long);
220 
221 NLIB_DEF_TRUETYPE(is_integral, unsigned char);
222 NLIB_DEF_TRUETYPE(is_integral, unsigned short);
223 NLIB_DEF_TRUETYPE(is_integral, unsigned int);
224 NLIB_DEF_TRUETYPE(is_integral, unsigned long long);
225 NLIB_DEF_TRUETYPE(is_integral, unsigned long);
226 } // namespace tt_detail
227 
228 template<class T>
229 struct IsIntegral
230  : public tt_detail::my_or<
231  typename tt_detail::is_integral<typename RemoveCv<T>::type>::type,
232  typename tt_detail::is_integral_ex<typename RemoveCv<T>::type>::type>::type {};
233 
234 // for std::is_signed
235 namespace tt_detail {
236 
237 template<class T>
238 struct is_signed_ex {
239  typedef FalseType type;
240 };
241 NLIB_DEF_TRUETYPE(is_signed_ex, signed char);
242 NLIB_DEF_TRUETYPE(is_signed_ex, signed short);
243 NLIB_DEF_TRUETYPE(is_signed_ex, signed int);
244 NLIB_DEF_TRUETYPE(is_signed_ex, signed long);
245 NLIB_DEF_TRUETYPE(is_signed_ex, signed long long);
246 
247 template<class T>
248 struct is_signed {
249  typedef FalseType type;
250 };
251 NLIB_DEF_TRUETYPE(is_signed, char);
252 NLIB_DEF_TRUETYPE(is_signed, short);
253 NLIB_DEF_TRUETYPE(is_signed, int);
254 NLIB_DEF_TRUETYPE(is_signed, long);
255 NLIB_DEF_TRUETYPE(is_signed, long long);
256 NLIB_DEF_TRUETYPE(is_signed, float);
257 NLIB_DEF_TRUETYPE(is_signed, double);
258 } // namespace tt_detail
259 
260 template<class T>
261 struct IsSigned : public tt_detail::my_or<
262  typename tt_detail::is_signed<typename RemoveCv<T>::type>::type,
263  typename tt_detail::is_signed_ex<typename RemoveCv<T>::type>::type>::type {};
264 
265 template<class T>
266 struct IsUnsigned {
267  typedef FalseType type;
268 };
269 template<>
270 struct IsUnsigned<bool> {
271  typedef TrueType type;
272 };
273 template<>
274 struct IsUnsigned<wchar_t> {
275  typedef TrueType type;
276 };
277 template<>
278 struct IsUnsigned<unsigned char> {
279  typedef TrueType type;
280 };
281 template<>
282 struct IsUnsigned<unsigned short> {
283  typedef TrueType type;
284 };
285 template<>
286 struct IsUnsigned<unsigned int> {
287  typedef TrueType type;
288 };
289 template<>
290 struct IsUnsigned<unsigned long> {
291  typedef TrueType type;
292 };
293 template<>
294 struct IsUnsigned<unsigned long long> {
295  typedef TrueType type;
296 };
297 
298 // for std::is_floating_point
299 namespace tt_detail {
300 
301 template<class T>
302 struct is_floating_point {
303  typedef FalseType type;
304 };
305 NLIB_DEF_TRUETYPE(is_floating_point, float);
306 NLIB_DEF_TRUETYPE(is_floating_point, double);
307 NLIB_DEF_TRUETYPE(is_floating_point, long double);
308 
309 } // namespace tt_detail
310 
311 template<class T>
312 struct IsFloatingPoint : public tt_detail::is_floating_point<typename RemoveCv<T>::type>::type {};
313 
314 // for std::is_arithmetic
315 template<class T>
316 struct IsArithmetic
317  : public IntegralConstant<bool, IsIntegral<T>::value || IsFloatingPoint<T>::value> {};
318 
319 // for std::is_pointer
320 namespace tt_detail {
321 template<class T>
322 struct IsPointerHelper : public FalseType {};
323 template<class T>
324 struct IsPointerHelper<T*> : public TrueType {};
325 } // namespace tt_detail
326 template<class T>
327 struct IsPointer : public tt_detail::IsPointerHelper<typename RemoveCv<T>::type> {};
328 
329 // for std::is_reference
330 template<class T>
331 struct IsReference : public FalseType {};
332 template<class T>
333 struct IsReference<T&> : public TrueType {};
334 
335 // for std::is_array
336 template<class T>
337 struct IsArray : public FalseType {};
338 template<class T>
339 struct IsArray<T[]> : public TrueType {};
340 template<class T, size_t N>
341 struct IsArray<T[N]> : public TrueType {};
342 
343 // for std::is_member_pointer
344 namespace tt_detail {
345 template<class T>
346 struct is_member_pointer : public FalseType {};
347 template<class T, class U>
348 struct is_member_pointer<T U::*> : public TrueType {};
349 } // namespace tt_detail
350 template<class T>
351 struct IsMemberPointer : public tt_detail::is_member_pointer<typename RemoveCv<T>::type> {};
352 
353 // for std::is_function
354 namespace tt_detail {
355 template<bool B>
356 struct is_function_ {
357  typedef FalseType type;
358 };
359 template<>
360 struct is_function_<true> {
361  typedef TrueType type;
362 };
363 template<class T>
364 struct is_function {
365  private:
366  typedef char One;
367  typedef struct {
368  char a[2];
369  } Two;
370  template<class U>
371  static One test(...);
372  template<class U>
373  static Two test(U (*)[1]);
374 
375  public:
376 #ifdef CAFE
377 #pragma diag_suppress 1931
378 #endif
379  typedef typename is_function_<sizeof(test<T>(0)) == 1>::type type;
380 #ifdef CAFE
381 #pragma diag_warning 1931
382 #endif
383 };
384 template<class T>
385 struct is_function<T&> {
386  typedef FalseType type;
387 };
388 template<>
389 struct is_function<void> {
390  typedef FalseType type;
391 };
392 template<>
393 struct is_function<const void> {
394  typedef FalseType type;
395 };
396 template<>
397 struct is_function<volatile void> {
398  typedef FalseType type;
399 };
400 template<>
401 struct is_function<const volatile void> {
402  typedef FalseType type;
403 };
404 } // namespace tt_detail
405 template<class T>
406 struct IsFunction : public tt_detail::is_function<T>::type {};
407 
408 #if !defined(NN_PLATFORM_CTR)
409 template<class T>
410 struct IsEnum : public IntegralConstant<bool, __is_enum(T)> {};
411 #else
412 // for std::is_enum
413 namespace tt_detail {
414 typedef char (&SizeOverOne)[2];
415 template<class T, bool convert_possible = !IsArithmetic<T>::value && !IsReference<T>::value &&
416  !IsPointer<T>::value && !IsMemberPointer<T>::value &&
417  !IsFunction<T>::value && !IsVoid<T>::value &&
418  !IsArray<T>::value>
419 struct ConsumeUDC {
420  operator T() const;
421 };
422 template<class T>
423 struct ConsumeUDC<T, false> {
424  operator SizeOverOne() const;
425 };
426 char enum_check(bool x);
427 char enum_check(char x);
428 char enum_check(signed char x);
429 char enum_check(unsigned char x);
430 char enum_check(wchar_t x);
431 char enum_check(signed short x);
432 char enum_check(unsigned short x);
433 char enum_check(signed int x);
434 char enum_check(unsigned int x);
435 char enum_check(signed long x);
436 char enum_check(unsigned long x);
437 char enum_check(signed long long x);
438 char enum_check(unsigned long long x);
439 char enum_check(float x);
440 char enum_check(double x);
441 char enum_check(long double x);
442 SizeOverOne enum_check(SizeOverOne x);
443 SizeOverOne enum_check(...);
444 template<class T>
445 struct is_enum {
446  enum { value = sizeof(enum_check(ConsumeUDC<T>())) == 1 };
447 };
448 } // namespace tt_detail
449 
450 template<class T>
451 struct IsEnum : public IntegralConstant<bool, tt_detail::is_enum<T>::value> {};
452 #endif
453 
454 #if !defined(NN_PLATFORM_CTR) && !defined(CAFE)
455 template<class T>
456 struct IsPod
457  : public IntegralConstant<bool, __is_pod(T) || IsEnum<T>::value || IsArithmetic<T>::value ||
458  IsPointer<T>::value || IsMemberPointer<T>::value> {};
459 
460 template<class T>
461 struct IsTriviallyDestructible : public IntegralConstant<bool, __has_trivial_destructor(T)> {};
462 #ifdef _MSC_VER
463 template<class T>
464 struct IsTriviallyDefaultConstructible
465  : public IntegralConstant<bool, __has_trivial_default_constructor(T)> {};
466 #else
467 template<class T>
468 struct IsTriviallyDefaultConstructible
469  : public IntegralConstant<bool, std::has_trivial_default_constructor<T>::value> {};
470 #endif
471 
472 #else
473 // for std::is_pod
474 namespace tt_detail {
475 
476 template<class T>
477 struct is_pod
478  : public tt_detail::my_or<typename IsArithmetic<T>::type, typename IsPointer<T>::type,
479  typename IsMemberPointer<T>::type, typename IsEnum<T>::type>::type {};
480 
481 template<class T>
482 struct is_pod<T[]> {
483  typedef typename is_pod<typename RemoveCv<T>::type>::type type;
484 };
485 template<class T, size_t N>
486 struct is_pod<T[N]> {
487  typedef typename is_pod<typename RemoveCv<T>::type>::type type;
488 };
489 
490 } // namespace tt_detail
491 
492 // NOTE: internal use only
493 // treats enum as non-POD.
494 // treats struct as non-POD.
495 //
496 // You have to define specialized IsPod when you have to use IsPos on struct.
497 // example:
498 // template<> struct IsPod<MyType> : public TrueType {};
499 template<class T>
500 struct IsTriviallyDestructible : public tt_detail::is_pod<typename RemoveCv<T>::type>::type {};
501 template<class T>
502 struct IsTriviallyDefaultConstructible
503  : public tt_detail::is_pod<typename RemoveCv<T>::type>::type {};
504 
505 template<class T>
506 struct IsPod : public IsTriviallyDestructible<T> {};
507 #endif
508 
509 #if !defined(NN_PLATFORM_CTR)
510 template<class T>
511 struct IsEmpty : public IntegralConstant<bool, __is_empty(T)> {};
512 #else
513 // for std::is_empty
514 namespace tt_detail {
515 template<class T>
516 struct IsEmptyHelper1 : public T {
517  int data[256];
518 
519  private:
520  NLIB_DISALLOW_COPY_AND_ASSIGN(IsEmptyHelper1);
521 };
522 
523 struct IsEmptyHelper2 {
524  int data[256];
525 };
526 } // namespace tt_detail
527 
528 template<class T>
529 struct IsEmpty : public IntegralConstant<bool, sizeof(tt_detail::IsEmptyHelper1<T>) ==
530  sizeof(tt_detail::IsEmptyHelper2)> {};
531 #endif
532 
533 #if !defined(NN_PLATFORM_CTR)
534 template<class T>
535 struct IsClass : public IntegralConstant<bool, __is_class(T)> {};
536 #else
537 // note that IsClass<union type>::value becomes true
538 template<class T>
539 class IsClass {
540  typedef char yes;
541  typedef struct {
542  char a[2];
543  } no;
544 
545  template<class X>
546  static yes check(void (X::*)(void));
547  template<class X>
548  static no check(...);
549 
550  public:
551  static const bool value = sizeof(check<T>(NULL)) == sizeof(yes);
552 };
553 #endif
554 
555 // template<class T> struct AddLvalueReference { typedef T& type; };
556 // template<class T> struct AddLvalueReference<T&> { typedef T& type; };
557 
558 NLIB_NAMESPACE_END
559 
560 #undef NLIB_DEF_TRUETYPE
561 #else
562 
563 #include <type_traits>
564 #include <utility>
565 NLIB_NAMESPACE_BEGIN
566 
567 #ifdef NLIB_HAS_TR1_TYPETRAITS
568 #define NLIB_DEF_REDIRECT(nlibstruct, stdstruct) \
569  \
570  template<class T> \
571  struct nlibstruct : public std::tr1::stdstruct<T> {}
572 template<class T, T v>
573 struct IntegralConstant : public std::tr1::integral_constant<T, v> {};
574 typedef std::tr1::true_type TrueType;
575 typedef std::tr1::false_type FalseType;
576 template<bool B, class T = void>
577 struct EnableIf {};
578 template<class T>
579 struct EnableIf<true, T> {
580  typedef T type;
581 };
582 template<bool B, class T, class F>
583 struct Conditional {
584  typedef T type;
585 };
586 template<class T, class F>
587 struct Conditional<false, T, F> {
588  typedef F type;
589 };
590 template<class T1, class T2>
591 struct IsSame : public std::tr1::is_same<T1, T2> {};
592 
593 NLIB_DEF_REDIRECT(IsTriviallyDestructible, has_trivial_destructor);
594 NLIB_DEF_REDIRECT(IsTriviallyDefaultConstructible, has_trivial_default_constructor);
595 
596 #else
597 #define NLIB_DEF_REDIRECT(nlibstruct, stdstruct) \
598  \
599  template<class T> \
600  struct nlibstruct : public std::stdstruct<T> {}
601 template<class T, T v>
602 struct IntegralConstant : public std::integral_constant<T, v> {};
603 typedef std::true_type TrueType;
604 typedef std::false_type FalseType;
605 template<bool B, class T>
606 struct EnableIf : public std::enable_if<B, T> {};
607 template<bool B, class T, class F>
608 struct Conditional : public std::conditional<B, T, F> {};
609 template<class T1, class T2>
610 struct IsSame : public std::is_same<T1, T2> {};
611 
612 // still unimplemented
613 // #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20141011
614 #if defined(__GLIBCXX__)
615 template<class T>
616 struct IsTriviallyDestructible : public IntegralConstant<bool, __has_trivial_destructor(T)> {};
617 template<class T>
618 struct IsTriviallyDefaultConstructible
619  : public IntegralConstant<bool, __has_trivial_constructor(T)> {};
620 #else
621 NLIB_DEF_REDIRECT(IsTriviallyDestructible, is_trivially_destructible);
622 NLIB_DEF_REDIRECT(IsTriviallyDefaultConstructible, is_trivially_constructible);
623 #endif
624 
625 #endif
626 
627 NLIB_DEF_REDIRECT(RemoveConst, remove_const);
628 NLIB_DEF_REDIRECT(RemoveVolatile, remove_volatile);
629 NLIB_DEF_REDIRECT(RemovePtr, remove_pointer);
630 NLIB_DEF_REDIRECT(RemoveRef, remove_reference);
631 NLIB_DEF_REDIRECT(AddRef, add_lvalue_reference);
632 NLIB_DEF_REDIRECT(RemoveCv, remove_cv);
633 NLIB_DEF_REDIRECT(IsVoid, is_void);
634 NLIB_DEF_REDIRECT(IsIntegral, is_integral);
635 NLIB_DEF_REDIRECT(IsSigned, is_signed);
636 NLIB_DEF_REDIRECT(IsUnsigned, is_unsigned);
637 NLIB_DEF_REDIRECT(IsFloatingPoint, is_floating_point);
638 NLIB_DEF_REDIRECT(IsArithmetic, is_arithmetic);
639 NLIB_DEF_REDIRECT(IsPointer, is_pointer);
640 NLIB_DEF_REDIRECT(IsReference, is_reference);
641 NLIB_DEF_REDIRECT(IsArray, is_array);
642 NLIB_DEF_REDIRECT(IsMemberPointer, is_member_pointer);
643 NLIB_DEF_REDIRECT(IsFunction, is_function);
644 NLIB_DEF_REDIRECT(IsEnum, is_enum);
645 
646 NLIB_DEF_REDIRECT(IsPod, is_pod);
647 NLIB_DEF_REDIRECT(IsEmpty, is_empty);
648 NLIB_DEF_REDIRECT(IsClass, is_class);
649 
650 NLIB_NAMESPACE_END
651 
652 #undef NLIB_DEF_REDIRECT
653 #endif
654 
655 NLIB_NAMESPACE_BEGIN
656 
657 #if (defined(_MSVC_LANG) && _MSVC_LANG > 201402L) || __cplusplus >= 201703L
658 template<typename T>
659 using IsSwappable = std::is_swappable<T>;
660 #elif defined(NLIB_HAS_NATIVE_TYPETRAITS) && defined(_MSC_VER)
661 // https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
662 namespace detail {
663 using std::swap;
664 template<typename T>
665 struct can_call_swap_impl {
666  template<typename U>
667  static auto check(int)
668  -> decltype(swap(std::declval<T&>(), std::declval<T&>()), std::true_type());
669  template<typename>
670  static std::false_type check(...);
671  using type = decltype(check<T>(0));
672 };
673 template<typename T>
674 struct can_call_swap : can_call_swap_impl<T>::type {};
675 } // namespace detail
676 namespace detail2 {
677 struct tag {};
678 template<class T>
679 tag swap(T&, T&);
680 template<typename T>
681 struct would_call_std_swap_impl {
682  template<typename U>
683  static auto check(int) -> std::integral_constant<
684  bool, std::is_same<decltype(swap(std::declval<U&>(), std::declval<U&>())), tag>::value>;
685  template<typename>
686  static std::false_type check(...);
687  using type = decltype(check<T>(0));
688 };
689 template<typename T>
690 struct would_call_std_swap : would_call_std_swap_impl<T>::type {};
691 } // namespace detail2
692 template<typename T>
693 struct IsSwappable : std::integral_constant<bool, detail::can_call_swap<T>::value &&
694  (!detail2::would_call_std_swap<T>::value ||
695  (std::is_move_assignable<T>::value &&
696  std::is_move_constructible<T>::value))> {};
697 template<typename T, size_t N>
698 struct IsSwappable<T[N]> : IsSwappable<T> {};
699 #else
700 namespace detail {
701 
702 template<class T>
703 class HasSwapMemFn {
704  typedef char yes;
705  typedef struct {
706  char a[2];
707  } no;
708 
709  template<class X, T& (X::*Func)(T&, move_tag)>
710  struct helper {};
711  template<class X>
712  static yes check(helper<X, &X::assign>* p);
713  template<class X>
714  static no check(...);
715 
716  public:
717 #ifdef CAFE
718 #pragma diag_suppress 1931
719 #endif
720  static const bool value = sizeof(check<T>(NULL)) == sizeof(yes);
721 #ifdef CAFE
722 #pragma diag_warning 1931
723 #endif
724 };
725 
726 template<class T, bool isClass>
727 struct IsSwappable_ : public IntegralConstant<bool, detail::HasSwapMemFn<T>::value> {};
728 
729 template<class T>
730 struct IsSwappable_<T, false>
731  : public IntegralConstant<bool, IsArithmetic<T>::value || IsPointer<T>::value ||
732  IsFunction<T>::value || IsMemberPointer<T>::value ||
733  IsEnum<T>::value> {};
734 
735 } // namespace detail
736 
737 // true if T has swap(T&) member function
738 // or T is a simple value.
739 // T may be swappable if IsSwappable<T>::value is false.
740 template<class T>
741 struct IsSwappable : public detail::IsSwappable_<T, IsClass<T>::value> {};
742 
743 #endif
744 NLIB_NAMESPACE_END
745 
746 #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:183
A file that contains the configuration information for each development environment.