vSMC
vSMC: Scalable Monte Carlo
type_traits.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/cxx11/type_traits.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_CXX11_TYPE_TRAITS_HPP
33 #define VSMC_CXX11_TYPE_TRAITS_HPP
34 
35 #include <vsmc/internal/config.hpp>
36 #include <vsmc/internal/assert.hpp>
38 
39 #define VSMC_STATIC_ASSERT_CXX11_TYPE_TRATIS_FORWARD_RVALUE \
40  VSMC_STATIC_ASSERT((!is_lvalue_reference<T>::value), \
41  ATTEMPT_TO_FORWARD_AN_RVALUE_AS_AN_LVALUE)
42 
43 namespace vsmc {
44 
45 namespace cxx11 {
46 
102 
104 // Forward declarations
106 
107 // Helper classes
108 template <typename T, T> struct integral_constant;
109 
110 // Primary type categories
111 template <typename> struct is_void;
112 template <typename> struct is_null_pointer;
113 template <typename> struct is_integral;
114 template <typename> struct is_floating_point;
115 template <typename> struct is_array;
116 template <typename> struct is_enum;
117 template <typename> struct is_union;
118 template <typename> struct is_class;
119 template <typename> struct is_function;
120 template <typename> struct is_pointer;
121 template <typename> struct is_lvalue_reference;
122 template <typename> struct is_rvalue_reference;
123 template <typename> struct is_member_object_pointer;
124 template <typename> struct is_member_function_pointer;
125 
126 // Composite type categories
127 template <typename> struct is_fundamental;
128 template <typename> struct is_arithmetic;
129 template <typename> struct is_scalar;
130 template <typename> struct is_object;
131 template <typename> struct is_compound;
132 template <typename> struct is_reference;
133 template <typename> struct is_member_pointer;
134 
135 // Type properties
136 template <typename> struct is_const;
137 template <typename> struct is_volatile;
138 template <typename> struct is_trivial;
139 template <typename> struct is_trivially_copyable;
140 template <typename> struct is_standard_layout;
141 template <typename> struct is_pod;
142 template <typename> struct is_literal_type;
143 template <typename> struct is_empty;
144 template <typename> struct is_polymorphic;
145 template <typename> struct is_abstract;
146 template <typename> struct is_signed;
147 template <typename> struct is_unsigned;
148 
149 // Supported operations
150 template <typename> struct is_constructible;
151 template <typename> struct is_trivially_constructible;
152 template <typename> struct is_nothrow_constructible;
153 template <typename> struct is_default_constructible;
154 template <typename> struct is_trivially_default_constructible;
155 template <typename> struct is_nothrow_default_constructible;
156 template <typename> struct is_copy_constructible;
157 template <typename> struct is_trivially_copy_constructible;
158 template <typename> struct is_nothrow_copy_constructible;
159 template <typename> struct is_move_constructible;
160 template <typename> struct is_trivially_move_constructible;
161 template <typename> struct is_nothrow_move_constructible;
162 template <typename> struct is_assignable;
163 template <typename> struct is_trivially_assignable;
164 template <typename> struct is_nothrow_assignable;
165 template <typename> struct is_copy_assignable;
166 template <typename> struct is_trivially_copy_assignable;
167 template <typename> struct is_nothrow_copy_assignable;
168 template <typename> struct is_move_assignable;
169 template <typename> struct is_trivially_move_assignable;
170 template <typename> struct is_nothrow_move_assignable;
171 template <typename> struct is_destructible;
172 template <typename> struct is_trivially_destructible;
173 template <typename> struct is_nothrow_destructible;
174 template <typename> struct has_virtual_destructor;
175 
176 // Property queries
177 template <typename> struct alignment_of;
178 template <typename> struct rank;
179 template <typename, unsigned> struct extent;
180 
181 // Type relations
182 template <typename, typename> struct is_same;
183 template <typename, typename> struct is_base_of;
184 template <typename, typename> struct is_convertible;
185 
186 // Const-volatility specifiers
187 template <typename> struct remove_cv;
188 template <typename> struct remove_const;
189 template <typename> struct remove_volatile;
190 template <typename> struct add_cv;
191 template <typename> struct add_const;
192 template <typename> struct add_volatile;
193 
194 // References
195 template <typename> struct remove_reference;
196 template <typename> struct add_lvalue_reference;
197 template <typename> struct add_rvalue_reference;
198 
199 // Pointers
200 template <typename> struct remove_pointer;
201 template <typename> struct add_pointer;
202 
203 // Sign modifiers
204 template <typename> struct make_signed;
205 template <typename> struct make_unsigned;
206 
207 // Arrays
208 template <typename> struct remove_extent;
209 template <typename> struct remove_all_extents;
210 
211 // Miscellaneous transformations
212 template <typename> struct aligned_storage;
213 template <typename> struct aligned_union;
214 template <typename> struct decay;
215 template <bool, typename> struct enable_if;
216 template <bool, typename, typename> struct conditional;
217 template <typename> struct common_type;
218 template <typename> struct underlying_type;
219 template <typename> struct result_of;
220 
221 // Utilities
222 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
223 template <typename T>
225 #else
226 template <typename T>
228 #endif
229 
234 
235 // integral_constant
236 template <typename T, T v>
237 struct integral_constant
238 {
239  typedef T value_type;
241  static VSMC_CONSTEXPR const T value = v;
242  VSMC_CONSTEXPR operator value_type () const VSMC_NOEXCEPT {return value;}
243  VSMC_CONSTEXPR value_type operator() () const VSMC_NOEXCEPT {return value;}
244 }; // struct integral_constant
247 
248 namespace internal {
249 typedef char tp_test_true;
250 struct tp_test_false {char a[2];};
251 } // namespace vsmc::cxx11::internal
252 
254 
259 
260 // is_void
261 namespace internal {
262 template <typename> struct is_void_impl : public false_type {};
263 template <> struct is_void_impl<void> : public true_type {};
264 } // namespace vsmc::cxx11::internal
265 template <typename T> struct is_void :
266  public internal::is_void_impl<typename remove_cv<T>::type> {};
267 
268 // is_null_pointer
269 namespace internal {
270 template <typename T> struct is_null_pointer_impl : public false_type {};
271 #if VSMC_HAS_CXX11_NULLPTR
272 template <> struct is_null_pointer_impl<std::nullptr_t> : public true_type {};
273 #endif
274 } // namespace vsmc::cxx11::internal
275 template <typename T> struct is_null_pointer :
276  public internal::is_null_pointer_impl<typename remove_cv<T>::type> {};
277 
278 // is_integral
279 namespace internal {
280 template <typename> struct is_integral_impl : public false_type {};
281 template <> struct is_integral_impl<char > : public true_type {};
282 template <> struct is_integral_impl<signed char > : public true_type {};
283 template <> struct is_integral_impl<unsigned char > : public true_type {};
284 template <> struct is_integral_impl<wchar_t > : public true_type {};
285 template <> struct is_integral_impl<short > : public true_type {};
286 template <> struct is_integral_impl<unsigned short> : public true_type {};
287 template <> struct is_integral_impl<int > : public true_type {};
288 template <> struct is_integral_impl<unsigned > : public true_type {};
289 template <> struct is_integral_impl<long > : public true_type {};
290 template <> struct is_integral_impl<unsigned long > : public true_type {};
291 #if VSMC_HAS_CXX11_LONG_LONG
292 template <> struct is_integral_impl<long long > : public true_type {};
293 template <> struct is_integral_impl<unsigned long long> : public true_type {};
294 #endif
295 #if VSMC_HAS_CXX11_UNICODE_LITERALS
296 template <> struct is_integral_impl<char16_t> : public true_type {};
297 template <> struct is_integral_impl<char32_t> : public true_type {};
298 #endif
299 } // namespace vsmc::cxx11::internal
300 template <typename T> struct is_integral :
301  public internal::is_integral_impl<typename remove_cv<T>::type> {};
302 
303 // is_floating_point
304 namespace internal {
305 template <typename> struct is_floating_point_impl : public false_type {};
306 template <> struct is_floating_point_impl<float > : public true_type {};
307 template <> struct is_floating_point_impl<double > : public true_type {};
308 template <> struct is_floating_point_impl<long double> : public true_type {};
309 } // namespace vsmc::cxx11::internal
310 template <typename T> struct is_floating_point :
311  public internal::is_floating_point_impl<typename remove_cv<T>::type> {};
312 
313 // is_array
314 template <typename> struct is_array : public false_type {};
315 template <typename T> struct is_array<T []> : public true_type {};
316 template <typename T, std::size_t N> struct is_array<T [N]> :
317  public true_type {};
318 
319 // is_enum
320 template <typename T> struct is_enum :
321  public integral_constant<bool,
322  !is_void<T>::value && !is_integral<T>::value &&
323  !is_floating_point<T>::value && !is_pointer<T>::value &&
324  !is_reference<T>::value && !is_member_pointer<T>::value &&
325  !is_union<T>::value && !is_class<T>::value &&
326  !is_function<T>::value> {};
327 
328 // is_union
329 namespace internal {
330 template <typename> struct is_union_impl : public false_type {};
331 } // namespace vsmc::cxx11::internal
332 template <typename T> struct is_union :
333  public internal::is_union_impl<typename remove_cv<T>::type> {};
334 
335 // is_class
336 namespace internal {
337 template <typename T> tp_test_true is_class_test (int T::*);
338 template <typename> tp_test_false is_class_test (...);
339 } // namespace vsmc::cxx11::internal
340 template <typename T> struct is_class :
341  public integral_constant<bool,
342  sizeof(internal::is_class_test<T>(0)) == sizeof(internal::tp_test_true) &&
343  !is_union<T>::value> {};
344 
345 // is_function
346 namespace internal {
347 template <typename T> tp_test_true is_function_test (T *);
348 template <typename> tp_test_false is_function_test (...);
349 template <typename T> T &is_function_test_src ();
350 template <typename T, bool =
351  is_class<T>::value || is_union<T>::value || is_void<T>::value ||
352  is_reference<T>::value || is_null_pointer<T>::value>
354  public integral_constant<bool,
355  sizeof(is_function_test<T>(is_function_test_src<T>())) ==
356  sizeof(tp_test_true)> {};
357 template <typename T> struct is_function_impl<T, true> : public false_type {};
358 } // namespace vsmc::cxx11::internal
359 template <typename T> struct is_function :
360  public internal::is_function_impl<T> {};
361 
362 // is_pointer
363 namespace internal {
364 template <typename> struct is_pointer_impl : public false_type {};
365 template <typename T> struct is_pointer_impl<T *> : public true_type {};
366 } // namespace vsmc::cxx11::internal
367 template <typename T> struct is_pointer :
368  public internal::is_pointer_impl<typename remove_cv<T>::type> {};
369 
370 // is_lvalue_reference
371 template <typename> struct is_lvalue_reference : public false_type {};
372 template <typename T> struct is_lvalue_reference<T &> : public true_type {};
373 
374 // is_rvalue_reference
375 template <typename> struct is_rvalue_reference : public false_type {};
376 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
377 template <typename T> struct is_rvalue_reference<T &&> : public true_type {};
378 #endif
379 
380 // is_member_object_pointer
381 template <typename T> struct is_member_object_pointer :
382  public integral_constant<bool,
383  is_member_pointer<T>::value && !is_member_function_pointer<T>::value> {};
384 
385 // is_member_function_pointer
386 namespace internal {
387 template <typename>
388 struct is_member_function_pointer_impl : public false_type {};
389 template <typename T, typename U>
390 struct is_member_function_pointer_impl<T U::*> : public is_function<T> {};
391 } // namespace vsmc::cxx11::internal
392 template <typename T> struct is_member_function_pointer :
394  typename remove_cv<T>::type> {};
395 
397 
402 
403 // is_fundamental
404 template <typename T> struct is_fundamental :
405  public integral_constant<bool,
406  is_void<T>::value || is_null_pointer<T>::value ||
407  is_arithmetic<T>::value> {};
408 
409 // is_arithmetic
410 template <typename T> struct is_arithmetic :
411  public integral_constant<bool,
412  is_integral<T>::value || is_floating_point<T>::value> {};
413 
414 // is_scalar
415 template <typename T> struct is_scalar :
416  public integral_constant<bool,
417  is_arithmetic<T>::value || is_member_pointer<T>::value ||
418  is_pointer<T>::value || is_null_pointer<T>::value ||
419  is_enum<T>::value> {};
420 
421 // is_object
422 template <typename T> struct is_object :
423  public integral_constant<bool,
424  is_scalar<T>::value || is_array<T>::value ||
425  is_union<T>::value || is_class<T>::value> {};
426 
427 // is_compound
428 template <typename T> struct is_compound :
429  public integral_constant<bool, !is_fundamental<T>::value> {};
430 
431 // is_reference
432 template <typename T> struct is_reference : public false_type {};
433 template <typename T> struct is_reference<T &> : public true_type {};
434 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
435 template <typename T> struct is_reference<T &&> : public true_type {};
436 #endif
437 
438 // is_member_pointer
439 namespace internal {
440 template <typename>
441 struct is_member_pointer_impl : public false_type {};
442 template <typename T, typename U>
443 struct is_member_pointer_impl<T U::*> : public true_type {};
444 } // namespace vsmc::cxx11::internal
445 template <typename T> struct is_member_pointer :
446  public internal::is_member_pointer_impl<typename remove_cv<T>::type> {};
447 
449 
454 
455 // is_const
456 template <typename> struct is_const : public false_type {};
457 template <typename T> struct is_const<const T> : public true_type {};
458 
459 // is_volatile
460 template <typename> struct is_volatile : public false_type {};
461 template <typename T> struct is_volatile<volatile T> : public true_type {};
462 
463 // is_trivial
464 // is_trivially_copyable
465 // is_standard_layout
466 // is_pod
467 
468 // is_literal_type
469 template <typename T> struct is_literal_type :
470  public integral_constant<bool,
471  is_scalar<typename remove_all_extents<T>::type>::value ||
472  is_reference<typename remove_all_extents<T>::type>::value> {};
473 
474 // is_empty
475 namespace internal {
476 template <typename is_empty_base>
477 struct is_empty_derived : public is_empty_base {double x;};
478 template <typename>
479 struct is_empty_standalone {double x;};
480 } // namespace vsmc::cxx11::internal
481 template <typename T> struct is_empty :
482  public integral_constant<bool,
483  sizeof(internal::is_empty_derived<T>) ==
484  sizeof(internal::is_empty_standalone<T>)> {};
485 
486 // is_polymorphic
487 #ifdef VSMC_MSVC
488 template <typename T> struct is_polymorphic :
489  public integral_constant<bool, __is_polymorphic(T)> {};
490 #else // VSMC_MSVC
491 namespace internal {
492 template <typename T> tp_test_true is_polymorphic_test (
493  typename enable_if<sizeof(static_cast<T *>(const_cast<void *>(
494  dynamic_cast<const volatile void *>(declval<T *>())
495  ))) != 0, int>::type);
496 template <typename> tp_test_false is_polymorphic_test (...);
497 } // namespace vsmc::cxx11::internal
498 template <typename T> struct is_polymorphic :
499  public integral_constant<bool,
500  sizeof(internal::is_polymorphic_test<T>(0)) ==
501  sizeof(internal::tp_test_true)> {};
502 #endif // VSMC_MSVC
503 
504 // is_abstract
505 namespace internal {
506 template <typename T> tp_test_false is_abstract_test (T (*) [1]);
507 template <typename> tp_test_true is_abstract_test (...);
508 template <typename T, bool = is_class<T>::value> struct is_abstract_impl :
509  public integral_constant<bool,
510  sizeof(is_abstract_test<T>(0)) == sizeof(tp_test_true)> {};
511 template <typename T> struct is_abstract_impl<T, false> : public false_type {};
512 } // namespace vsmc::cxx11::internal
513 template <typename T> struct is_abstract :
514  public internal::is_abstract_impl<T> {};
515 
516 // is_signed
517 namespace internal {
518 template <typename T, bool = is_integral<T>::value>
519 struct is_signed_num_impl :
520  public integral_constant<bool, static_cast<T>(-1) < static_cast<T>(0)> {};
521 template <typename T>
522 struct is_signed_num_impl<T, false> : public true_type {};
523 template <typename T, bool = is_arithmetic<T>::value> struct is_signed_impl :
524  public is_signed_num_impl<T> {};
525 template <typename T> struct is_signed_impl<T, false> : public false_type {};
526 } // namespace vsmc::cxx11::internal
527 template <typename T> struct is_signed :
528  public internal::is_signed_impl<T> {};
529 
530 // is_unsigned
531 namespace internal {
532 template <typename T, bool = is_integral<T>::value>
533 struct is_unsigned_num_impl :
534  public integral_constant<bool, static_cast<T>(0) < static_cast<T>(-1)> {};
535 template <typename T>
536 struct is_unsigned_num_impl<T, false> : public false_type {};
537 template <typename T, bool = is_arithmetic<T>::value> struct is_unsigned_impl :
538  public is_unsigned_num_impl<T> {};
539 template <typename T> struct is_unsigned_impl<T, false> : public false_type {};
540 } // namespace vsmc::cxx11::internal
541 template <typename T> struct is_unsigned :
542  public internal::is_unsigned_impl<T> {};
543 
545 
550 
551 // is_constructible
552 // is_trivially_constructible
553 // is_nothrow_constructible
554 // is_default_constructible
555 // is_trivially_default_constructible
556 // is_nothrow_default_constructible
557 // is_copy_constructible
558 // is_trivially_copy_constructible
559 // is_nothrow_copy_constructible
560 // is_move_constructible
561 // is_trivially_move_constructible
562 // is_nothrow_move_constructible
563 // is_assignable
564 // is_trivially_assignable
565 // is_nothrow_assignable
566 // is_copy_assignable
567 // is_trivially_copy_assignable
568 // is_nothrow_copy_assignable
569 // is_move_assignable
570 // is_trivially_move_assignable
571 // is_nothrow_move_assignable
572 // is_destructible
573 // is_trivially_destructible
574 // is_nothrow_destructible
575 // has_virtual_destructor
576 
578 
583 
584 // alignment_of
585 
586 // rank
587 template <typename> struct rank :
588  public integral_constant<std::size_t, 0> {};
589 template <typename T> struct rank<T []> :
590  public integral_constant<std::size_t, rank<T>::value + 1> {};
591 template <typename T, std::size_t N> struct rank<T [N]> :
592  public integral_constant<std::size_t, rank<T>::value + 1> {};
593 
594 // extent
595 template <typename, unsigned = 0> struct extent :
596  public integral_constant<std::size_t, 0> {};
597 template <typename T> struct extent<T [], 0> :
598  public integral_constant<std::size_t, 0> {};
599 template <typename T, unsigned I> struct extent<T [], I> :
600  public integral_constant<std::size_t, extent<T, I - 1>::value> {};
601 template <typename T, std::size_t N> struct extent<T [N], 0> :
602  public integral_constant<std::size_t, N> {};
603 template <typename T, std::size_t N, unsigned I> struct extent<T [N], I> :
604  public integral_constant<std::size_t, extent<T, I - 1>::value> {};
605 
607 
612 
613 // is_same
614 template <typename, typename> struct is_same : public false_type {};
615 template <typename T> struct is_same<T, T> : public true_type {};
616 
617 // is_base_of
618 namespace internal {
619 template <typename T>
620 struct is_base_of_dest {is_base_of_dest (const volatile T &);};
621 template <typename T>
622 struct is_base_of_src
623 {
624  operator const volatile T &();
625  template <typename U> operator const is_base_of_dest<U> &();
626 }; // struct is_base_of_src
627 
628 template <std::size_t> struct is_base_of_fail {typedef tp_test_false type;};
629 template <typename B, typename D>
630 typename is_base_of_fail<sizeof(
631  is_base_of_dest<B>(declval<is_base_of_src<D> >())
632  )>::type is_base_of_test (int);
633 template <typename B, typename D> tp_test_true is_base_of_test (...);
634 } // namespace vsmc::cxx11::internal
635 template <typename B, typename D> struct is_base_of :
636  public integral_constant<bool, is_class<B>::value &&
637  sizeof(internal::is_base_of_test<B, D>(0)) ==
638  sizeof(internal::tp_test_true)> {};
639 
640 // is_convertible
641 namespace internal {
642 template <typename T> tp_test_true is_convertible_test (T);
643 template <typename> tp_test_false is_convertible_test (...);
644 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
645 template <typename T> T && is_convertible_test_src ();
646 #else
647 template <typename T>
648 typename remove_reference<T>::type &is_convertible_test_src ();
649 #endif
650 
651 template <typename T,
652  bool IsArray = is_array<T>::value,
653  bool IsFunction = is_function<T>::value,
654  bool IsVoid = is_void<T>::value>
655 struct is_convertible_afv {enum {value = 0};};
656 template <typename T>
657 struct is_convertible_afv<T, true, false, false> {enum {value = 1};};
658 template <typename T>
659 struct is_convertible_afv<T, false, true, false> {enum {value = 2};};
660 template <typename T>
661 struct is_convertible_afv<T, false, false, true> {enum {value = 3};};
662 
663 template <typename T1, typename T2,
664  unsigned T1_afv = is_convertible_afv<T1>::value,
665  unsigned T2_afv = is_convertible_afv<T2>::value>
666 struct is_convertible_impl :
667  public integral_constant<bool,
668 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
669  sizeof(is_convertible_test<T2>(is_convertible_test_src<T1>())) ==
670  sizeof(tp_test_true)
671 #else
672  sizeof(is_convertible_test<T2>(is_convertible_test_src<T1>())) ==
673  sizeof(tp_test_true) && !(!is_function<T1>::value &&
674  !is_reference<T1>::value && is_reference<T2>::value &&
675  (!is_const<typename remove_reference<T2>::type>::value ||
676  is_volatile<typename remove_reference<T2>::type>::value) &&
677  (is_same<typename remove_cv<T1>::type, typename remove_cv<
678  typename remove_reference<T2>::type>::type>::value ||
679  is_base_of<typename remove_reference<T2>::type, T1>::value))
680 #endif
681  > {};
682 template <typename T1, typename T2>
683 struct is_convertible_impl<T1, T2, 1, 0> : public false_type {};
684 template <typename T1>
685 struct is_convertible_impl<T1, const T1 &, 1, 0> : public true_type {};
686 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
687 template <typename T1>
688 struct is_convertible_impl<T1, T1 &&, 1, 0> : public true_type {};
689 template <typename T1>
690 struct is_convertible_impl<T1, const T1 &&, 1, 0> : public true_type {};
691 template <typename T1>
692 struct is_convertible_impl<T1, volatile T1 &&, 1, 0> : public true_type {};
693 template <typename T1>
694 struct is_convertible_impl<T1, const volatile T1 &&, 1, 0> :
695  public true_type {};
696 #endif
697 
698 template <typename T1, typename T2>
699 struct is_convertible_impl<T1, T2 *, 1, 0> :
700  public integral_constant<bool, is_convertible_impl<
701  typename remove_all_extents<T1>::type *, T2 *>::value> {};
702 template <typename T1, typename T2>
703 struct is_convertible_impl<T1, T2 *const, 1, 0> :
704  public integral_constant<bool, is_convertible_impl<
705  typename remove_all_extents<T1>::type *, T2 *const>::value> {};
706 template <typename T1, typename T2>
707 struct is_convertible_impl<T1, T2 *volatile, 1, 0> :
708  public integral_constant<bool, is_convertible_impl<
709  typename remove_all_extents<T1>::type *, T2 *volatile>::value> {};
710 template <typename T1, typename T2>
711 struct is_convertible_impl<T1, T2 *const volatile, 1, 0> :
712  public integral_constant<bool, is_convertible_impl<
713  typename remove_all_extents<T1>::type *, T2 *const volatile>::value> {};
714 
715 template <typename T1, typename T2>
716 struct is_convertible_impl<T1, T2, 2, 0> : public false_type {};
717 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
718 template <typename T1>
719 struct is_convertible_impl<T1, T1 &&, 2, 0> : public true_type {};
720 #endif
721 template <typename T1>
722 struct is_convertible_impl<T1, T1 &, 2, 0> : public true_type {};
723 template <typename T1>
724 struct is_convertible_impl<T1, T1 *, 2, 0> : public true_type {};
725 template <typename T1>
726 struct is_convertible_impl<T1, T1 *const, 2, 0> : public true_type {};
727 template <typename T1>
728 struct is_convertible_impl<T1, T1 *volatile, 2, 0> : public true_type {};
729 template <typename T1>
730 struct is_convertible_impl<T1, T1 *const volatile, 2, 0> : public true_type {};
731 
732 template <typename T1, typename T2>
733 struct is_convertible_impl<T1, T2, 3, 0> : public false_type {};
734 template <typename T1, typename T2>
735 struct is_convertible_impl<T1, T2, 0, 1> : public false_type {};
736 template <typename T1, typename T2>
737 struct is_convertible_impl<T1, T2, 1, 1> : public false_type {};
738 template <typename T1, typename T2>
739 struct is_convertible_impl<T1, T2, 2, 1> : public false_type {};
740 template <typename T1, typename T2>
741 struct is_convertible_impl<T1, T2, 3, 1> : public false_type {};
742 template <typename T1, typename T2>
743 struct is_convertible_impl<T1, T2, 0, 2> : public false_type {};
744 template <typename T1, typename T2>
745 struct is_convertible_impl<T1, T2, 1, 2> : public false_type {};
746 template <typename T1, typename T2>
747 struct is_convertible_impl<T1, T2, 2, 2> : public false_type {};
748 template <typename T1, typename T2>
749 struct is_convertible_impl<T1, T2, 3, 2> : public false_type {};
750 template <typename T1, typename T2>
751 struct is_convertible_impl<T1, T2, 0, 3> : public false_type {};
752 template <typename T1, typename T2>
753 struct is_convertible_impl<T1, T2, 1, 3> : public false_type {};
754 template <typename T1, typename T2>
755 struct is_convertible_impl<T1, T2, 3, 3> : public true_type {};
756 } // namespace vsmc::cxx11::internal
757 template <typename T1, typename T2> struct is_convertible :
758  public internal::is_convertible_impl<T1, T2> {};
759 
761 
766 
767 // remove_const
768 template <typename T> struct remove_const {typedef T type;};
769 template <typename T> struct remove_const<const T> {typedef T type;};
770 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
771 template <typename T> using remove_const_t = typename remove_const<T>::type;
772 #endif
773 
774 // remove_volatile
775 template <typename T> struct remove_volatile {typedef T type;};
776 template <typename T> struct remove_volatile<volatile T> {typedef T type;};
777 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
778 template <typename T> using remove_volatile_t =
779  typename remove_volatile<T>::type;
780 #endif
781 
782 // remove_cv
783 template <typename T> struct remove_cv
784 {typedef typename remove_volatile<typename remove_const<T>::type>::type type;};
785 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
786 template <typename T> using remove_cv_t = typename remove_cv<T>::type;
787 #endif
788 
789 // add_const
790 namespace internal {
791 template <typename T, bool =
792  is_reference<T>::value || is_function<T>::value || is_const<T>::value>
793 struct add_const_impl {typedef T type;};
794 template <typename T>
795 struct add_const_impl<T, false> {typedef const T type;};
796 } // namespace vsmc::cxx11::internal
797 template <typename T> struct add_const
798 {typedef typename internal::add_const_impl<T>::type type;};
799 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
800 template <typename T> using add_const_t = typename add_const<T>::type;
801 #endif
802 
803 // add_volatile
804 namespace internal {
805 template <typename T, bool =
806  is_reference<T>::value || is_function<T>::value || is_volatile<T>::value>
807 struct add_volatile_impl {typedef T type;};
808 template <typename T>
809 struct add_volatile_impl<T, false> {typedef volatile T type;};
810 } // namespace vsmc::cxx11::internal
811 template <typename T> struct add_volatile
812 {typedef typename internal::add_volatile_impl<T>::type type;};
813 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
814 template <typename T> using add_volatile_t = typename add_volatile<T>::type;
815 #endif
816 
817 // add_cv
818 template <typename T> struct add_cv
819 {typedef typename add_volatile<typename add_const<T>::type>::type type;};
820 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
821 template <typename T> using add_cv_t = typename add_cv<T>::type;
822 #endif
823 
825 
830 
831 // remove_reference
832 template <typename T> struct remove_reference {typedef T type;};
833 template <typename T> struct remove_reference<T &> {typedef T type;};
834 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
835 template <typename T> struct remove_reference<T &&> {typedef T type;};
836 #endif
837 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
838 template <typename T> using remove_reference_t =
839  typename remove_reference<T>::type;
840 #endif
841 
842 // add_lvalue_reference
843 template <typename T> struct add_lvalue_reference {typedef T & type;};
844 template <typename T> struct add_lvalue_reference<T &> {typedef T & type;};
845 template <> struct add_lvalue_reference<void>
846 {typedef void type;};
847 template <> struct add_lvalue_reference<const void>
848 {typedef const void type;};
849 template <> struct add_lvalue_reference<volatile void>
850 {typedef volatile void type;};
851 template <> struct add_lvalue_reference<const volatile void>
852 {typedef const volatile void type;};
853 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
854 template <typename T> using add_lvalue_reference_t =
855  typename add_lvalue_reference<T>::type;
856 #endif
857 
858 // add_rvalue_reference
859 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
860 template <typename T> struct add_rvalue_reference {typedef T && type;};
861 template <> struct add_rvalue_reference<void>
862 {typedef void type;};
863 template <> struct add_rvalue_reference<const void>
864 {typedef const void type;};
865 template <> struct add_rvalue_reference<volatile void>
866 {typedef volatile void type;};
867 template <> struct add_rvalue_reference<const volatile void>
868 {typedef const volatile void type;};
869 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
870 template <typename T> using add_rvalue_reference_t =
871  typename add_rvalue_reference<T>::type;
872 #endif
873 #endif
874 
876 
881 
882 // remove_pointer
883 template <typename T> struct remove_pointer {typedef T type;};
884 template <typename T> struct remove_pointer<T *> {typedef T type;};
885 template <typename T> struct remove_pointer<T *const> {typedef T type;};
886 template <typename T> struct remove_pointer<T *volatile> {typedef T type;};
887 template <typename T> struct remove_pointer<T *const volatile>
888 {typedef T type;};
889 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
890 template <typename T> using remove_pointer_t =
891  typename remove_pointer<T>::type;
892 #endif
893 
894 // add_pointer
895 template <typename T> struct add_pointer
896 {typedef typename remove_reference<T>::type * type;};
897 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
898 template <typename T> using add_pointer_t = typename add_pointer<T>::type;
899 #endif
900 
902 
907 
908 namespace internal {
909 template <typename T, typename U,
910  bool = is_const<typename remove_reference<T>::type>::value,
911  bool = is_volatile<typename remove_reference<T>::type>::value>
912 struct apply_cv;
913 template <typename T, typename U> struct apply_cv<T, U, true, true>
914 {typedef const volatile U type;};
915 template <typename T, typename U> struct apply_cv<T, U, true, false>
916 {typedef const U type;};
917 template <typename T, typename U> struct apply_cv<T, U, false, true>
918 {typedef volatile U type;};
919 template <typename T, typename U> struct apply_cv<T, U, false, false>
920 {typedef U type;};
921 template <typename T, typename U> struct apply_cv<T &, U, true, true>
922 {typedef const volatile U & type;};
923 template <typename T, typename U> struct apply_cv<T &, U, true, false>
924 {typedef const U & type;};
925 template <typename T, typename U> struct apply_cv<T &, U, false, true>
926 {typedef volatile U & type;};
927 template <typename T, typename U> struct apply_cv<T &, U, false, false>
928 {typedef U & type;};
929 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
930 template <typename T, typename U> struct apply_cv<T &&, U, true, true>
931 {typedef const volatile U && type;};
932 template <typename T, typename U> struct apply_cv<T &&, U, true, false>
933 {typedef const U && type;};
934 template <typename T, typename U> struct apply_cv<T &&, U, false, true>
935 {typedef volatile U && type;};
936 template <typename T, typename U> struct apply_cv<T &&, U, false, false>
937 {typedef U && type;};
938 #endif
939 } // namespace vsmc::cxx11::internal
940 
941 // make_signed
942 namespace internal {
943 template <typename T, bool = is_integral<T>::value || is_enum<T>::value>
944 struct make_signed_impl {};
945 template <> struct make_signed_impl<signed short, true>
946 {typedef signed short type;};
947 template <> struct make_signed_impl<signed int, true>
948 {typedef signed int type;};
949 template <> struct make_signed_impl<signed long, true>
950 {typedef signed long type;};
951 #if VSMC_HAS_CXX11_LONG_LONG
952 template <> struct make_signed_impl<signed long long, true>
953 {typedef signed long long type;};
954 #endif
955 template <> struct make_signed_impl<unsigned short, true>
956 {typedef signed short type;};
957 template <> struct make_signed_impl<unsigned int, true>
958 {typedef signed int type;};
959 template <> struct make_signed_impl<unsigned long, true>
960 {typedef signed long type;};
961 #if VSMC_HAS_CXX11_LONG_LONG
962 template <> struct make_signed_impl<unsigned long long, true>
963 {typedef signed long long type;};
964 #endif
965 } // namespace vsmc::cxx11::internal
966 template <typename T>
967 struct make_signed
968 {
969  typedef typename internal::apply_cv<T,
970  typename internal::make_signed_impl<typename remove_cv<
971  typename remove_reference<T>::type>::type>::type>::type type;
972 }; //struct make_signed
973 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
974 template <typename T> using make_signed_t = typename make_signed<T>::type;
975 #endif
976 
977 // make_unsigned
978 namespace internal {
979 template <typename T, bool = is_integral<T>::value || is_enum<T>::value>
980 struct make_unsigned_impl {};
981 template <> struct make_unsigned_impl<signed short, true>
982 {typedef unsigned short type;};
983 template <> struct make_unsigned_impl<signed int, true>
984 {typedef unsigned int type;};
985 template <> struct make_unsigned_impl<signed long, true>
986 {typedef unsigned long type;};
987 #if VSMC_HAS_CXX11_LONG_LONG
988 template <> struct make_unsigned_impl<signed long long, true>
989 {typedef unsigned long long type;};
990 #endif
991 template <> struct make_unsigned_impl<unsigned short, true>
992 {typedef unsigned short type;};
993 template <> struct make_unsigned_impl<unsigned int, true>
994 {typedef unsigned int type;};
995 template <> struct make_unsigned_impl<unsigned long, true>
996 {typedef unsigned long type;};
997 #if VSMC_HAS_CXX11_LONG_LONG
998 template <> struct make_unsigned_impl<unsigned long long, true>
999 {typedef unsigned long long type;};
1000 #endif
1001 } // namespace vsmc::cxx11::internal
1002 template <typename T>
1003 struct make_unsigned
1004 {
1005  typedef typename internal::apply_cv<T,
1006  typename internal::make_unsigned_impl<typename remove_cv<
1007  typename remove_reference<T>::type>::type>::type>::type type;
1008 }; // struct make_unsigned
1009 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
1010 template <typename T> using make_unsigned_t = typename make_unsigned<T>::type;
1011 #endif
1012 
1014 
1019 
1020 // remove_extent
1021 template <typename T>
1022 struct remove_extent {typedef T type;};
1023 template <typename T>
1024 struct remove_extent<T []> {typedef T type;};
1025 template <typename T, std::size_t N>
1026 struct remove_extent<T [N]> {typedef T type;};
1027 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
1028 template <typename T> using remove_extent_t = typename remove_extent<T>::type;
1029 #endif
1030 
1031 // remove_all_extents
1032 template <typename T> struct remove_all_extents {typedef T type;};
1033 template <typename T> struct remove_all_extents<T []>
1034 {typedef typename remove_all_extents<T>::type type;};
1035 template <typename T, std::size_t N> struct remove_all_extents<T [N]>
1036 {typedef typename remove_all_extents<T>::type type;};
1037 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
1038 template <typename T> using remove_all_extents_t =
1039  typename remove_all_extents<T>::type;
1040 #endif
1041 
1043 
1048 
1049 // aligned_storage
1050 // aligned_union
1051 
1052 // decay
1053 template <typename T>
1054 struct decay
1055 {
1056  private :
1057 
1058  typedef typename remove_reference<T>::type U;
1059 
1060  public :
1061 
1062  typedef
1063  typename conditional<
1064  is_array<U>::value, typename remove_extent<U>::type *,
1065  typename conditional<
1066  is_function<U>::value, typename add_pointer<U>::type,
1067  typename remove_cv<U>::type>::type>::type type;
1068 }; // struct decay
1069 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
1070 template <typename T> using decay_t = typename decay<T>::type;
1071 #endif
1072 
1073 // enable_if
1074 template <bool, typename = void> struct enable_if {};
1075 template <typename T> struct enable_if<true, T> {typedef T type;};
1076 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
1077 template <bool B, typename T = void> using enable_if_t =
1078  typename enable_if<B, T>::type;
1079 #endif
1080 
1081 // conditional
1082 template <bool, typename, typename F> struct conditional {typedef F type;};
1083 template <typename T, typename F> struct conditional<true, T, F>
1084 {typedef T type;};
1085 #if VSMC_HAS_CXX11_ALIAS_TEMPLATES
1086 template <bool B, typename T, typename F> using conditional_t =
1087  typename conditional<B, T, F>::type;
1088 #endif
1089 
1090 // common_type
1091 // underlying_type
1092 // result_of
1093 
1095 
1097 // Utilities
1099 
1104 
1105 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
1106 template <typename T>
1107 inline typename remove_reference<T>::type &&move (T &&t) VSMC_NOEXCEPT;
1108 
1109 template <typename T>
1110 inline typename remove_reference<T>::type &&move (T &&t) VSMC_NOEXCEPT
1111 {
1112  typedef typename remove_reference<T>::type U;
1113  return static_cast<U &&>(t);
1114 }
1115 
1116 template <typename T>
1117 inline T &&forward (typename remove_reference<T>::type &t) VSMC_NOEXCEPT
1118 {return static_cast<T &&>(t);}
1119 
1120 template <typename T>
1121 inline T &&forward (typename remove_reference<T>::type &&t) VSMC_NOEXCEPT
1122 {
1123  VSMC_STATIC_ASSERT_CXX11_TYPE_TRATIS_FORWARD_RVALUE;
1124  return static_cast<T&&>(t);
1125 }
1126 #endif
1127 
1129 
1131 
1132 } // namespace vsmc::cxx11
1133 
1134 } // namespace vsmc
1135 
1136 #endif // VSMC_CXX11_TYPE_TRAITS_HPP
Definition: adapter.hpp:37
constexpr value_type operator()() const noexcept
#define VSMC_CONSTEXPR
constexpr
Definition: defines.hpp:55
STL namespace.
tp_test_false is_class_test(...)
tp_test_false is_function_test(...)
integral_constant< bool, false > false_type
integral_constant< T, v > type
add_rvalue_reference< T >::type declval() noexcept
integral_constant< bool, true > true_type
tp_test_false is_polymorphic_test(...)
static constexpr const T value
#define VSMC_NOEXCEPT
noexcept
Definition: defines.hpp:71
tp_test_false is_abstract_test(T(*)[1])