1 // -*- C++ -*- Time-stamp: <08/07/20 19:10:15 ptr>
4 * Copyright (c) 2007, 2008
7 * Licensed under the Academic Free License version 3.0
9 * Derived from original <misc/type_traits.h> of 'complement' project
10 * [http://complement.sourceforge.net]
11 * to make it close to JTC1/SC22/WG21 C++ 0x working draft
12 * [http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2008/n2521.pdf]
15 #ifndef __STLP_TYPE_TRAITS
16 #define __STLP_TYPE_TRAITS
18 #ifndef _STLP_OUTERMOST_HEADER_ID
19 # define _STLP_OUTERMOST_HEADER_ID 0x3
20 # include <stl/_prolog.h>
23 // libstdc++ v3, timestamp 20050519 (3.4.4) has __type_traits,
24 // libstdc++ v3, timestamp 20060306 (3.4.6) has __type_traits,
25 // while libstdc++ v3, 20050921 (4.0.2) not; use libstdc++ instead
26 // # if defined(STLPORT) || (defined(__GNUC__) && (__GNUC__ < 4)) /* !defined(__GLIBCXX__) || (defined(__GNUC__) && (__GNUC__ < 4)) */
30 _STLP_BEGIN_TR1_NAMESPACE
49 static __t1 __test(_Up(*)[1]);
52 static __t2 __test(...);
55 #ifdef _STLP_STATIC_CONST_INIT_BUG
56 static const bool __value;
58 static const bool __value = sizeof(__test<_Tp>(0)) == sizeof(__select_types::__t1);
63 #ifdef _STLP_STATIC_CONST_INIT_BUG
65 const bool __instance<_Tp>::__value = sizeof(__instance<_Tp>::__test<_Tp>(0)) == sizeof(__select_types::__t1);
69 struct __uoc_aux : // union or class
74 static __t1 __test( int _Up::* );
77 static __t2 __test(...);
80 #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION
81 static const bool __value;
83 static const bool __value = sizeof(__test<T>(0)) == sizeof(__select_types::__t1);
87 #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION
89 const bool __uoc_aux<T>::__value = sizeof(__uoc_aux<T>::__test<T>(0)) == sizeof(__select_types::__t1);
96 template <class T, bool B>
97 class __inheritance_aux
101 class __inheritance_aux<T,true> :
105 virtual ~__inheritance_aux()
110 template <class T, bool B>
114 #ifdef _STLP_STATIC_CONST_INIT_BUG
115 static const bool __value;
117 static const bool __value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false;
121 #ifdef _STLP_STATIC_CONST_INIT_BUG
122 template <class T, bool B>
123 const bool __virtual_aux<T,B>::__value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false;
127 } // namespace detail
129 template <class _Tp, _Tp __v>
130 struct integral_constant
132 static const _Tp value = __v;
133 // enum { value = __v }; ?
135 typedef _Tp value_type;
136 typedef integral_constant<_Tp, __v> type;
139 typedef integral_constant<bool, true> true_type;
140 typedef integral_constant<bool, false> false_type;
144 template <typename _Tp>
145 struct __is_union_or_class :
146 public integral_constant<bool, __uoc_aux<_Tp>::__value>
150 template<typename _Tp>
151 struct __is_vtbl : // has virtual table?
152 public integral_constant<bool, __virtual_aux<_Tp,__is_union_or_class<_Tp>::value >::__value>
156 template <typename _Tp>
157 struct __is_vtbl : // has virtual table?
158 public integral_constant<bool, __is_union_or_class<_Tp>::value ? (sizeof(__inheritance_aux<_Tp,__is_union_or_class<_Tp>::value>) == sizeof(_Tp)) : false >
161 } // namespace detail
163 #define __SPEC_(C,T,B) \
166 public integral_constant<bool, B> \
169 #define __CV_SPEC(C,T,B) \
171 __SPEC_(C,const T,B); \
172 __SPEC_(C,volatile T,B); \
173 __SPEC_(C,const volatile T,B)
175 #define __SPEC_1(C,T,B) \
176 template <class _Tp> \
178 public integral_constant<bool, B> \
181 #define __CV_SPEC_1(C,T,B) \
183 __SPEC_1(C,T const,B); \
184 __SPEC_1(C,T volatile,B); \
185 __SPEC_1(C,T const volatile,B)
187 #define __SPEC_2(C,T,B) \
188 template <class _Tp1, class _Tp2> \
190 public integral_constant<bool, B> \
193 #define __CV_SPEC_2(C,T,B) \
195 __SPEC_2(C,T const,B); \
196 __SPEC_2(C,T volatile,B); \
197 __SPEC_2(C,T const volatile,B)
199 // [4.5.1] primary type categories:
207 struct is_void<void> :
216 __CV_SPEC(is_integral,bool,true);
217 __CV_SPEC(is_integral,char,true);
218 __CV_SPEC(is_integral,signed char,true);
219 __CV_SPEC(is_integral,unsigned char,true);
220 __CV_SPEC(is_integral,wchar_t,true);
221 __CV_SPEC(is_integral,short,true);
222 __CV_SPEC(is_integral,unsigned short,true);
223 __CV_SPEC(is_integral,int,true);
224 __CV_SPEC(is_integral,unsigned int,true);
225 __CV_SPEC(is_integral,long,true);
226 __CV_SPEC(is_integral,unsigned long,true);
227 __CV_SPEC(is_integral,long long,true);
228 __CV_SPEC(is_integral,unsigned long long,true);
231 struct is_floating_point :
235 __CV_SPEC(is_floating_point,float,true);
236 __CV_SPEC(is_floating_point,double,true);
237 __CV_SPEC(is_floating_point,long double,true);
244 template <class _Tp, std::size_t _Sz>
245 struct is_array<_Tp[_Sz]> :
250 struct is_array<_Tp[]> :
259 __CV_SPEC_1(is_pointer,_Tp *,true);
262 struct is_lvalue_reference :
267 struct is_lvalue_reference<_Tp&> :
272 struct is_rvalue_reference :
276 // template <class _Tp>
277 // struct is_rvalue_reference<_Tp&&> :
282 struct is_reference :
287 struct is_reference<_Tp&> :
293 public integral_constant<bool, !(detail::__instance<_Tp>::__value
294 || detail::__is_union_or_class<_Tp>::value
295 || is_reference<_Tp>::value
296 || is_void<_Tp>::value)>
300 struct is_member_object_pointer :
304 // _SPEC_FULL2(is_member_object_pointer, _Tp1 _Tp2::*,!is_function<_Tp1>::value);
306 template <class _Tp1, class _Tp2>
307 struct is_member_object_pointer<_Tp1 _Tp2::*> :
308 public integral_constant<bool, !is_function<_Tp1>::value>
311 template <class _Tp1, class _Tp2>
312 struct is_member_object_pointer<_Tp1 _Tp2::* const> :
313 public integral_constant<bool, !is_function<_Tp1>::value>
316 template <class _Tp1, class _Tp2>
317 struct is_member_object_pointer<_Tp1 _Tp2::* volatile> :
318 public integral_constant<bool, !is_function<_Tp1>::value>
321 template <class _Tp1, class _Tp2>
322 struct is_member_object_pointer<_Tp1 _Tp2::* const volatile> :
323 public integral_constant<bool, !is_function<_Tp1>::value>
327 struct is_member_function_pointer :
331 // _SPEC_FULL2(is_member_function_pointer,_Tp1 _Tp2::*,is_function<_Tp1>::value);
333 template <class _Tp1, class _Tp2>
334 struct is_member_function_pointer<_Tp1 _Tp2::*> :
335 public integral_constant<bool, is_function<_Tp1>::value>
338 template <class _Tp1, class _Tp2>
339 struct is_member_function_pointer<_Tp1 _Tp2::* const> :
340 public integral_constant<bool, is_function<_Tp1>::value>
343 template <class _Tp1, class _Tp2>
344 struct is_member_function_pointer<_Tp1 _Tp2::* volatile> :
345 public integral_constant<bool, is_function<_Tp1>::value>
348 template <class _Tp1, class _Tp2>
349 struct is_member_function_pointer<_Tp1 _Tp2::* const volatile> :
350 public integral_constant<bool, is_function<_Tp1>::value>
354 struct is_member_pointer :
355 public integral_constant<bool, (is_member_object_pointer<_Tp>::value || is_member_function_pointer<_Tp>::value)>
358 // 4.5.2 composite type categories
361 struct is_arithmetic :
362 public integral_constant<bool, (is_integral<_Tp>::value || is_floating_point<_Tp>::value)>
366 struct is_fundamental :
367 public integral_constant<bool, (is_arithmetic<_Tp>::value || is_void<_Tp>::value)>
370 // [4.5.1] primary type categories (continued):
374 public integral_constant<bool, !(is_fundamental<_Tp>::value
375 || is_array<_Tp>::value
376 || is_pointer<_Tp>::value
377 || is_reference<_Tp>::value
378 || is_member_pointer<_Tp>::value
379 || is_function<_Tp>::value
380 || detail::__is_union_or_class<_Tp>::value) >
391 // is_function (above)
393 // 4.5.2 composite type categories (continued)
395 // is_arithmetic (above)
396 // is_fundamental (above)
400 public integral_constant<bool, (is_arithmetic<_Tp>::value ||
401 is_array<_Tp>::value ||
402 is_pointer<_Tp>::value ||
403 is_member_pointer<_Tp>::value ||
404 detail::__is_union_or_class<_Tp>::value)>
409 public integral_constant<bool, (is_arithmetic<_Tp>::value
410 || is_enum<_Tp>::value
411 || is_pointer<_Tp>::value
412 || is_member_pointer<_Tp>::value)>
417 public integral_constant<bool, !is_fundamental<_Tp>::value>
422 // 4.5.3 type properties:
430 struct is_const<_Tp const> :
440 struct is_volatile<_Tp volatile> :
445 // 4.7.3 array modifications:
453 template <class _Tp, std::size_t _Sz>
454 struct remove_extent<_Tp[_Sz]>
460 struct remove_extent<_Tp[]>
466 struct remove_all_extents
471 template <class _Tp, std::size_t _Size>
472 struct remove_all_extents<_Tp[_Size]>
474 typedef typename remove_all_extents<_Tp>::type type;
477 template<typename _Tp>
478 struct remove_all_extents<_Tp[]>
480 typedef typename remove_all_extents<_Tp>::type type;
483 // 4.5.3 type properties (continued):
487 public integral_constant<bool, (is_void<_Tp>::value
488 || is_scalar<typename remove_all_extents<_Tp>::type>::value)>
492 struct is_standard_layout :
493 public integral_constant<bool, (is_void<_Tp>::value
494 || is_scalar<typename remove_all_extents<_Tp>::type>::value)>
499 public integral_constant<bool, (is_void<_Tp>::value
500 || is_scalar<typename remove_all_extents<_Tp>::type>::value)>
503 template<typename _Tp>
505 : public integral_constant<bool, (detail::__is_union_or_class<_Tp>::value
506 && (sizeof(detail::__empty<_Tp>) == sizeof(_Tp)))>
513 struct has_trivial_constructor :
514 public integral_constant<bool, is_pod<_Tp>::value>
518 struct has_trivial_copy :
519 public integral_constant<bool, is_pod<_Tp>::value>
523 struct has_trivial_assign :
524 public integral_constant<bool, is_pod<_Tp>::value>
528 struct has_trivial_destructor :
529 public integral_constant<bool, is_pod<_Tp>::value>
533 struct has_nothrow_constructor :
534 public integral_constant<bool, is_pod<_Tp>::value>
538 struct has_nothrow_copy :
539 public integral_constant<bool, is_pod<_Tp>::value>
543 struct has_nothrow_assign :
544 public integral_constant<bool, is_pod<_Tp>::value>
548 struct has_virtual_destructor :
557 __CV_SPEC(is_signed,signed char,true);
558 __CV_SPEC(is_signed,short,true);
559 __CV_SPEC(is_signed,int,true);
560 __CV_SPEC(is_signed,long,true);
561 __CV_SPEC(is_signed,long long,true);
568 __CV_SPEC(is_unsigned,unsigned char,true);
569 __CV_SPEC(is_unsigned,unsigned short,true);
570 __CV_SPEC(is_unsigned,unsigned int,true);
571 __CV_SPEC(is_unsigned,unsigned long,true);
572 __CV_SPEC(is_unsigned,unsigned long long,true);
578 // 4.6 type relations:
580 template <class _Tp1, class _Tp2>
586 struct is_same<_Tp, _Tp> :
593 // 4.7.1 const-volatile modifications
602 struct remove_const<_Tp const>
608 struct remove_volatile
614 struct remove_volatile<_Tp volatile>
622 typedef typename remove_const<typename remove_volatile<_Tp>::type>::type type;
628 typedef _Tp const type;
634 typedef _Tp volatile type;
640 typedef typename add_const<typename add_volatile<_Tp>::type>::type type;
643 // 4.7.2 reference modifications:
646 struct remove_reference
652 struct remove_reference<_Tp&>
664 struct add_reference<_Tp&>
669 // 4.7.3 array modifications (see above)
671 // 4.7.4 pointer modifications:
674 struct remove_pointer
680 struct remove_pointer<_Tp *>
686 struct remove_pointer<_Tp * const>
692 struct remove_pointer<_Tp * volatile>
698 struct remove_pointer<_Tp * const volatile>
706 typedef typename remove_reference<_Tp>::type * type;
709 // 20.5.7 other transformations:
711 // template <std::size_t Len, std::size_t Align> struct aligned_storage;
712 // template <std::size_t Len, class... Types> struct aligned_union;
716 template <bool,class _U>
719 typedef typename remove_cv<_U>::type type;
723 struct _decay_aux2<true,_U>
725 typedef typename add_pointer<_U>::type type;
728 template <bool, class _U>
731 typedef typename _decay_aux2<is_function<_U>::value,_U>::type type;
735 struct _decay_aux1<true,_U>
737 typedef typename remove_extent<_U>::type* type;
740 } // namespace detail
746 typedef typename remove_reference<_Tp>::type _U;
749 typedef typename detail::_decay_aux1<is_array<_U>::value,_U>::type type;
752 template <bool, class _Tp = void>
758 struct enable_if<true,_Tp>
763 template <bool, class _Tp1, class _Tp2>
769 template <class _Tp1, class _Tp2>
770 struct conditional<true,_Tp1,_Tp2>
775 // template <class... _Tp> struct common_type;
784 _STLP_END_NAMESPACE // tr1
788 // # else // __GLIBCXX__ && (__GNUC__ >= 4) && !STLPORT
789 // # include <tr1/type_traits>
792 #if (_STLP_OUTERMOST_HEADER_ID == 0x3)
793 # include <stl/_epilog.h>
794 # undef _STLP_OUTERMOST_HEADER_ID
797 #endif // __STLP_TYPE_TRAITS