// -*- C++ -*- Time-stamp: <08/07/20 19:10:15 ptr> /* * Copyright (c) 2007, 2008 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 * * Derived from original of 'complement' project * [http://complement.sourceforge.net] * to make it close to JTC1/SC22/WG21 C++ 0x working draft * [http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2008/n2521.pdf] */ #ifndef __STLP_TYPE_TRAITS #define __STLP_TYPE_TRAITS #ifndef _STLP_OUTERMOST_HEADER_ID # define _STLP_OUTERMOST_HEADER_ID 0x3 # include #endif // libstdc++ v3, timestamp 20050519 (3.4.4) has __type_traits, // libstdc++ v3, timestamp 20060306 (3.4.6) has __type_traits, // while libstdc++ v3, 20050921 (4.0.2) not; use libstdc++ instead // # if defined(STLPORT) || (defined(__GNUC__) && (__GNUC__ < 4)) /* !defined(__GLIBCXX__) || (defined(__GNUC__) && (__GNUC__ < 4)) */ _STLP_BEGIN_NAMESPACE _STLP_BEGIN_TR1_NAMESPACE namespace detail { struct __select_types { typedef char __t1; struct __t2 { char __two[2]; }; }; template struct __instance : public __select_types { private: template static __t1 __test(_Up(*)[1]); template static __t2 __test(...); public: #ifdef _STLP_STATIC_CONST_INIT_BUG static const bool __value; #else static const bool __value = sizeof(__test<_Tp>(0)) == sizeof(__select_types::__t1); #endif }; #ifdef _STLP_STATIC_CONST_INIT_BUG template const bool __instance<_Tp>::__value = sizeof(__instance<_Tp>::__test<_Tp>(0)) == sizeof(__select_types::__t1); #endif template struct __uoc_aux : // union or class public __select_types { private: template static __t1 __test( int _Up::* ); template static __t2 __test(...); public: #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION static const bool __value; #else static const bool __value = sizeof(__test(0)) == sizeof(__select_types::__t1); #endif }; #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION template const bool __uoc_aux::__value = sizeof(__uoc_aux::__test(0)) == sizeof(__select_types::__t1); #endif template class __empty { }; template class __inheritance_aux {}; template class __inheritance_aux : public T { public: virtual ~__inheritance_aux() { } }; #if 0 template struct __virtual_aux { public: #ifdef _STLP_STATIC_CONST_INIT_BUG static const bool __value; #else static const bool __value = B ? (sizeof(__inheritance_aux) == sizeof(T)) : false; #endif }; #ifdef _STLP_STATIC_CONST_INIT_BUG template const bool __virtual_aux::__value = B ? (sizeof(__inheritance_aux) == sizeof(T)) : false; #endif #endif } // namespace detail template struct integral_constant { static const _Tp value = __v; // enum { value = __v }; ? typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; }; typedef integral_constant true_type; typedef integral_constant false_type; namespace detail { template struct __is_union_or_class : public integral_constant::__value> { }; #if 0 template struct __is_vtbl : // has virtual table? public integral_constant::value >::__value> { }; #endif template struct __is_vtbl : // has virtual table? public integral_constant::value ? (sizeof(__inheritance_aux<_Tp,__is_union_or_class<_Tp>::value>) == sizeof(_Tp)) : false > { }; } // namespace detail #define __SPEC_(C,T,B) \ template <> \ struct C : \ public integral_constant \ { } #define __CV_SPEC(C,T,B) \ __SPEC_(C,T,B); \ __SPEC_(C,const T,B); \ __SPEC_(C,volatile T,B); \ __SPEC_(C,const volatile T,B) #define __SPEC_1(C,T,B) \ template \ struct C : \ public integral_constant \ { } #define __CV_SPEC_1(C,T,B) \ __SPEC_1(C,T,B); \ __SPEC_1(C,T const,B); \ __SPEC_1(C,T volatile,B); \ __SPEC_1(C,T const volatile,B) #define __SPEC_2(C,T,B) \ template \ struct C : \ public integral_constant \ { } #define __CV_SPEC_2(C,T,B) \ __SPEC_2(C,T,B); \ __SPEC_2(C,T const,B); \ __SPEC_2(C,T volatile,B); \ __SPEC_2(C,T const volatile,B) // [4.5.1] primary type categories: template struct is_void : public false_type { }; template <> struct is_void : public true_type { }; template struct is_integral : public false_type { }; __CV_SPEC(is_integral,bool,true); __CV_SPEC(is_integral,char,true); __CV_SPEC(is_integral,signed char,true); __CV_SPEC(is_integral,unsigned char,true); __CV_SPEC(is_integral,wchar_t,true); __CV_SPEC(is_integral,short,true); __CV_SPEC(is_integral,unsigned short,true); __CV_SPEC(is_integral,int,true); __CV_SPEC(is_integral,unsigned int,true); __CV_SPEC(is_integral,long,true); __CV_SPEC(is_integral,unsigned long,true); __CV_SPEC(is_integral,long long,true); __CV_SPEC(is_integral,unsigned long long,true); template struct is_floating_point : public false_type { }; __CV_SPEC(is_floating_point,float,true); __CV_SPEC(is_floating_point,double,true); __CV_SPEC(is_floating_point,long double,true); template struct is_array : public false_type { }; template struct is_array<_Tp[_Sz]> : public true_type { }; template struct is_array<_Tp[]> : public true_type { }; template struct is_pointer : public false_type { }; __CV_SPEC_1(is_pointer,_Tp *,true); template struct is_lvalue_reference : public false_type { }; template struct is_lvalue_reference<_Tp&> : public true_type { }; template struct is_rvalue_reference : public false_type { }; // template // struct is_rvalue_reference<_Tp&&> : // public true_type // { }; template struct is_reference : public false_type { }; template struct is_reference<_Tp&> : public true_type { }; template struct is_function : public integral_constant::__value || detail::__is_union_or_class<_Tp>::value || is_reference<_Tp>::value || is_void<_Tp>::value)> { }; template struct is_member_object_pointer : public false_type { }; // _SPEC_FULL2(is_member_object_pointer, _Tp1 _Tp2::*,!is_function<_Tp1>::value); template struct is_member_object_pointer<_Tp1 _Tp2::*> : public integral_constant::value> { }; template struct is_member_object_pointer<_Tp1 _Tp2::* const> : public integral_constant::value> { }; template struct is_member_object_pointer<_Tp1 _Tp2::* volatile> : public integral_constant::value> { }; template struct is_member_object_pointer<_Tp1 _Tp2::* const volatile> : public integral_constant::value> { }; template struct is_member_function_pointer : public false_type { }; // _SPEC_FULL2(is_member_function_pointer,_Tp1 _Tp2::*,is_function<_Tp1>::value); template struct is_member_function_pointer<_Tp1 _Tp2::*> : public integral_constant::value> { }; template struct is_member_function_pointer<_Tp1 _Tp2::* const> : public integral_constant::value> { }; template struct is_member_function_pointer<_Tp1 _Tp2::* volatile> : public integral_constant::value> { }; template struct is_member_function_pointer<_Tp1 _Tp2::* const volatile> : public integral_constant::value> { }; template struct is_member_pointer : public integral_constant::value || is_member_function_pointer<_Tp>::value)> { }; // 4.5.2 composite type categories template struct is_arithmetic : public integral_constant::value || is_floating_point<_Tp>::value)> { }; template struct is_fundamental : public integral_constant::value || is_void<_Tp>::value)> { }; // [4.5.1] primary type categories (continued): template struct is_enum : public integral_constant::value || is_array<_Tp>::value || is_pointer<_Tp>::value || is_reference<_Tp>::value || is_member_pointer<_Tp>::value || is_function<_Tp>::value || detail::__is_union_or_class<_Tp>::value) > { }; template struct is_union { }; template struct is_class { }; // is_function (above) // 4.5.2 composite type categories (continued) // is_arithmetic (above) // is_fundamental (above) template struct is_object : public integral_constant::value || is_array<_Tp>::value || is_pointer<_Tp>::value || is_member_pointer<_Tp>::value || detail::__is_union_or_class<_Tp>::value)> { }; template struct is_scalar : public integral_constant::value || is_enum<_Tp>::value || is_pointer<_Tp>::value || is_member_pointer<_Tp>::value)> { }; template struct is_compound : public integral_constant::value> { }; // is_member_pointer // 4.5.3 type properties: template struct is_const : public false_type { }; template struct is_const<_Tp const> : public true_type { }; template struct is_volatile : public false_type { }; template struct is_volatile<_Tp volatile> : public true_type { }; // 4.7.3 array modifications: template struct remove_extent { typedef _Tp type; }; template struct remove_extent<_Tp[_Sz]> { typedef _Tp type; }; template struct remove_extent<_Tp[]> { typedef _Tp type; }; template struct remove_all_extents { typedef _Tp type; }; template struct remove_all_extents<_Tp[_Size]> { typedef typename remove_all_extents<_Tp>::type type; }; template struct remove_all_extents<_Tp[]> { typedef typename remove_all_extents<_Tp>::type type; }; // 4.5.3 type properties (continued): template struct is_trivial : public integral_constant::value || is_scalar::type>::value)> { }; template struct is_standard_layout : public integral_constant::value || is_scalar::type>::value)> { }; template struct is_pod : public integral_constant::value || is_scalar::type>::value)> { }; template struct is_empty : public integral_constant::value && (sizeof(detail::__empty<_Tp>) == sizeof(_Tp)))> { }; // is_polimorphic // is_abstract template struct has_trivial_constructor : public integral_constant::value> { }; template struct has_trivial_copy : public integral_constant::value> { }; template struct has_trivial_assign : public integral_constant::value> { }; template struct has_trivial_destructor : public integral_constant::value> { }; template struct has_nothrow_constructor : public integral_constant::value> { }; template struct has_nothrow_copy : public integral_constant::value> { }; template struct has_nothrow_assign : public integral_constant::value> { }; template struct has_virtual_destructor : public false_type { }; template struct is_signed : public false_type { }; __CV_SPEC(is_signed,signed char,true); __CV_SPEC(is_signed,short,true); __CV_SPEC(is_signed,int,true); __CV_SPEC(is_signed,long,true); __CV_SPEC(is_signed,long long,true); template struct is_unsigned : public false_type { }; __CV_SPEC(is_unsigned,unsigned char,true); __CV_SPEC(is_unsigned,unsigned short,true); __CV_SPEC(is_unsigned,unsigned int,true); __CV_SPEC(is_unsigned,unsigned long,true); __CV_SPEC(is_unsigned,unsigned long long,true); // alignment_of // rank // extent // 4.6 type relations: template struct is_same : public false_type { }; template struct is_same<_Tp, _Tp> : public true_type { }; // is_base_of // is_convertible // 4.7.1 const-volatile modifications template struct remove_const { typedef _Tp type; }; template struct remove_const<_Tp const> { typedef _Tp type; }; template struct remove_volatile { typedef _Tp type; }; template struct remove_volatile<_Tp volatile> { typedef _Tp type; }; template struct remove_cv { typedef typename remove_const::type>::type type; }; template struct add_const { typedef _Tp const type; }; template struct add_volatile { typedef _Tp volatile type; }; template struct add_cv { typedef typename add_const::type>::type type; }; // 4.7.2 reference modifications: template struct remove_reference { typedef _Tp type; }; template struct remove_reference<_Tp&> { typedef _Tp type; }; template struct add_reference { typedef _Tp& type; }; template struct add_reference<_Tp&> { typedef _Tp& type; }; // 4.7.3 array modifications (see above) // 4.7.4 pointer modifications: template struct remove_pointer { typedef _Tp type; }; template struct remove_pointer<_Tp *> { typedef _Tp type; }; template struct remove_pointer<_Tp * const> { typedef _Tp type; }; template struct remove_pointer<_Tp * volatile> { typedef _Tp type; }; template struct remove_pointer<_Tp * const volatile> { typedef _Tp type; }; template struct add_pointer { typedef typename remove_reference<_Tp>::type * type; }; // 20.5.7 other transformations: // template struct aligned_storage; // template struct aligned_union; namespace detail { template struct _decay_aux2 { typedef typename remove_cv<_U>::type type; }; template struct _decay_aux2 { typedef typename add_pointer<_U>::type type; }; template struct _decay_aux1 { typedef typename _decay_aux2::value,_U>::type type; }; template struct _decay_aux1 { typedef typename remove_extent<_U>::type* type; }; } // namespace detail template class decay { private: typedef typename remove_reference<_Tp>::type _U; public: typedef typename detail::_decay_aux1::value,_U>::type type; }; template struct enable_if { }; template struct enable_if { typedef _Tp type; }; template struct conditional { typedef _Tp2 type; }; template struct conditional { typedef _Tp1 type; }; // template struct common_type; #undef __CV_SPEC #undef __SPEC_ #undef __CV_SPEC_1 #undef __SPEC_1 #undef __CV_SPEC_2 #undef __SPEC_2 _STLP_END_NAMESPACE // tr1 _STLP_END_NAMESPACE // # else // __GLIBCXX__ && (__GNUC__ >= 4) && !STLPORT // # include // # endif #if (_STLP_OUTERMOST_HEADER_ID == 0x3) # include # undef _STLP_OUTERMOST_HEADER_ID #endif #endif // __STLP_TYPE_TRAITS