| // -*- 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 <misc/type_traits.h> 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 <stl/_prolog.h> |
| #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 <class _Tp> |
| struct __instance : |
| public __select_types |
| { |
| private: |
| template <class _Up> |
| static __t1 __test(_Up(*)[1]); |
| |
| template <class> |
| 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 <class _Tp> |
| const bool __instance<_Tp>::__value = sizeof(__instance<_Tp>::__test<_Tp>(0)) == sizeof(__select_types::__t1); |
| #endif |
| |
| template <class T> |
| struct __uoc_aux : // union or class |
| public __select_types |
| { |
| private: |
| template <class _Up> |
| static __t1 __test( int _Up::* ); |
| |
| template <class> |
| static __t2 __test(...); |
| |
| public: |
| #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION |
| static const bool __value; |
| #else |
| static const bool __value = sizeof(__test<T>(0)) == sizeof(__select_types::__t1); |
| #endif |
| }; |
| |
| #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION |
| template <class T> |
| const bool __uoc_aux<T>::__value = sizeof(__uoc_aux<T>::__test<T>(0)) == sizeof(__select_types::__t1); |
| #endif |
| |
| template <class T> |
| class __empty |
| { }; |
| |
| template <class T, bool B> |
| class __inheritance_aux |
| {}; |
| |
| template <class T> |
| class __inheritance_aux<T,true> : |
| public T |
| { |
| public: |
| virtual ~__inheritance_aux() |
| { } |
| }; |
| |
| #if 0 |
| template <class T, bool B> |
| struct __virtual_aux |
| { |
| public: |
| #ifdef _STLP_STATIC_CONST_INIT_BUG |
| static const bool __value; |
| #else |
| static const bool __value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false; |
| #endif |
| }; |
| |
| #ifdef _STLP_STATIC_CONST_INIT_BUG |
| template <class T, bool B> |
| const bool __virtual_aux<T,B>::__value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false; |
| #endif |
| #endif |
| |
| } // namespace detail |
| |
| template <class _Tp, _Tp __v> |
| struct integral_constant |
| { |
| static const _Tp value = __v; |
| // enum { value = __v }; ? |
| |
| typedef _Tp value_type; |
| typedef integral_constant<_Tp, __v> type; |
| }; |
| |
| typedef integral_constant<bool, true> true_type; |
| typedef integral_constant<bool, false> false_type; |
| |
| namespace detail { |
| |
| template <typename _Tp> |
| struct __is_union_or_class : |
| public integral_constant<bool, __uoc_aux<_Tp>::__value> |
| { }; |
| |
| #if 0 |
| template<typename _Tp> |
| struct __is_vtbl : // has virtual table? |
| public integral_constant<bool, __virtual_aux<_Tp,__is_union_or_class<_Tp>::value >::__value> |
| { }; |
| #endif |
| |
| template <typename _Tp> |
| struct __is_vtbl : // has virtual table? |
| public integral_constant<bool, __is_union_or_class<_Tp>::value ? (sizeof(__inheritance_aux<_Tp,__is_union_or_class<_Tp>::value>) == sizeof(_Tp)) : false > |
| { }; |
| |
| } // namespace detail |
| |
| #define __SPEC_(C,T,B) \ |
| template <> \ |
| struct C<T> : \ |
| public integral_constant<bool, B> \ |
| { } |
| |
| #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 <class _Tp> \ |
| struct C<T> : \ |
| public integral_constant<bool, B> \ |
| { } |
| |
| #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 <class _Tp1, class _Tp2> \ |
| struct C<T> : \ |
| public integral_constant<bool, B> \ |
| { } |
| |
| #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 <class _Tp> |
| struct is_void : |
| public false_type |
| { }; |
| |
| template <> |
| struct is_void<void> : |
| public true_type |
| { }; |
| |
| template <class _Tp> |
| 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 <class _Tp> |
| 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 <class _Tp> |
| struct is_array : |
| public false_type |
| { }; |
| |
| template <class _Tp, std::size_t _Sz> |
| struct is_array<_Tp[_Sz]> : |
| public true_type |
| { }; |
| |
| template <class _Tp> |
| struct is_array<_Tp[]> : |
| public true_type |
| { }; |
| |
| template <class _Tp> |
| struct is_pointer : |
| public false_type |
| { }; |
| |
| __CV_SPEC_1(is_pointer,_Tp *,true); |
| |
| template <class _Tp> |
| struct is_lvalue_reference : |
| public false_type |
| { }; |
| |
| template <class _Tp> |
| struct is_lvalue_reference<_Tp&> : |
| public true_type |
| { }; |
| |
| template <class _Tp> |
| struct is_rvalue_reference : |
| public false_type |
| { }; |
| |
| // template <class _Tp> |
| // struct is_rvalue_reference<_Tp&&> : |
| // public true_type |
| // { }; |
| |
| template <class _Tp> |
| struct is_reference : |
| public false_type |
| { }; |
| |
| template <class _Tp> |
| struct is_reference<_Tp&> : |
| public true_type |
| { }; |
| |
| template <class _Tp> |
| struct is_function : |
| public integral_constant<bool, !(detail::__instance<_Tp>::__value |
| || detail::__is_union_or_class<_Tp>::value |
| || is_reference<_Tp>::value |
| || is_void<_Tp>::value)> |
| { }; |
| |
| template <class _Tp> |
| struct is_member_object_pointer : |
| public false_type |
| { }; |
| |
| // _SPEC_FULL2(is_member_object_pointer, _Tp1 _Tp2::*,!is_function<_Tp1>::value); |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_object_pointer<_Tp1 _Tp2::*> : |
| public integral_constant<bool, !is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_object_pointer<_Tp1 _Tp2::* const> : |
| public integral_constant<bool, !is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_object_pointer<_Tp1 _Tp2::* volatile> : |
| public integral_constant<bool, !is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_object_pointer<_Tp1 _Tp2::* const volatile> : |
| public integral_constant<bool, !is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp> |
| struct is_member_function_pointer : |
| public false_type |
| { }; |
| |
| // _SPEC_FULL2(is_member_function_pointer,_Tp1 _Tp2::*,is_function<_Tp1>::value); |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_function_pointer<_Tp1 _Tp2::*> : |
| public integral_constant<bool, is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_function_pointer<_Tp1 _Tp2::* const> : |
| public integral_constant<bool, is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_function_pointer<_Tp1 _Tp2::* volatile> : |
| public integral_constant<bool, is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp1, class _Tp2> |
| struct is_member_function_pointer<_Tp1 _Tp2::* const volatile> : |
| public integral_constant<bool, is_function<_Tp1>::value> |
| { }; |
| |
| template <class _Tp> |
| struct is_member_pointer : |
| public integral_constant<bool, (is_member_object_pointer<_Tp>::value || is_member_function_pointer<_Tp>::value)> |
| { }; |
| |
| // 4.5.2 composite type categories |
| |
| template <class _Tp> |
| struct is_arithmetic : |
| public integral_constant<bool, (is_integral<_Tp>::value || is_floating_point<_Tp>::value)> |
| { }; |
| |
| template <class _Tp> |
| struct is_fundamental : |
| public integral_constant<bool, (is_arithmetic<_Tp>::value || is_void<_Tp>::value)> |
| { }; |
| |
| // [4.5.1] primary type categories (continued): |
| |
| template <class _Tp> |
| struct is_enum : |
| public integral_constant<bool, !(is_fundamental<_Tp>::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 <class T> |
| struct is_union |
| { }; |
| |
| template <class T> |
| struct is_class |
| { }; |
| |
| // is_function (above) |
| |
| // 4.5.2 composite type categories (continued) |
| |
| // is_arithmetic (above) |
| // is_fundamental (above) |
| |
| template <class _Tp> |
| struct is_object : |
| public integral_constant<bool, (is_arithmetic<_Tp>::value || |
| is_array<_Tp>::value || |
| is_pointer<_Tp>::value || |
| is_member_pointer<_Tp>::value || |
| detail::__is_union_or_class<_Tp>::value)> |
| { }; |
| |
| template <class _Tp> |
| struct is_scalar : |
| public integral_constant<bool, (is_arithmetic<_Tp>::value |
| || is_enum<_Tp>::value |
| || is_pointer<_Tp>::value |
| || is_member_pointer<_Tp>::value)> |
| { }; |
| |
| template <class _Tp> |
| struct is_compound : |
| public integral_constant<bool, !is_fundamental<_Tp>::value> |
| { }; |
| |
| // is_member_pointer |
| |
| // 4.5.3 type properties: |
| |
| template <class _Tp> |
| struct is_const : |
| public false_type |
| { }; |
| |
| template <class _Tp> |
| struct is_const<_Tp const> : |
| public true_type |
| { }; |
| |
| template <class _Tp> |
| struct is_volatile : |
| public false_type |
| { }; |
| |
| template <class _Tp> |
| struct is_volatile<_Tp volatile> : |
| public true_type |
| { }; |
| |
| |
| // 4.7.3 array modifications: |
| |
| template <class _Tp> |
| struct remove_extent |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp, std::size_t _Sz> |
| struct remove_extent<_Tp[_Sz]> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_extent<_Tp[]> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_all_extents |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp, std::size_t _Size> |
| struct remove_all_extents<_Tp[_Size]> |
| { |
| typedef typename remove_all_extents<_Tp>::type type; |
| }; |
| |
| template<typename _Tp> |
| struct remove_all_extents<_Tp[]> |
| { |
| typedef typename remove_all_extents<_Tp>::type type; |
| }; |
| |
| // 4.5.3 type properties (continued): |
| |
| template <class _Tp> |
| struct is_trivial : |
| public integral_constant<bool, (is_void<_Tp>::value |
| || is_scalar<typename remove_all_extents<_Tp>::type>::value)> |
| { }; |
| |
| template <class _Tp> |
| struct is_standard_layout : |
| public integral_constant<bool, (is_void<_Tp>::value |
| || is_scalar<typename remove_all_extents<_Tp>::type>::value)> |
| { }; |
| |
| template <class _Tp> |
| struct is_pod : |
| public integral_constant<bool, (is_void<_Tp>::value |
| || is_scalar<typename remove_all_extents<_Tp>::type>::value)> |
| { }; |
| |
| template<typename _Tp> |
| struct is_empty |
| : public integral_constant<bool, (detail::__is_union_or_class<_Tp>::value |
| && (sizeof(detail::__empty<_Tp>) == sizeof(_Tp)))> |
| { }; |
| |
| // is_polimorphic |
| // is_abstract |
| |
| template <class _Tp> |
| struct has_trivial_constructor : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_trivial_copy : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_trivial_assign : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_trivial_destructor : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_nothrow_constructor : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_nothrow_copy : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_nothrow_assign : |
| public integral_constant<bool, is_pod<_Tp>::value> |
| { }; |
| |
| template <class _Tp> |
| struct has_virtual_destructor : |
| public false_type |
| { }; |
| |
| template <class _Tp> |
| 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 <class _Tp> |
| 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 <class _Tp1, class _Tp2> |
| struct is_same : |
| public false_type |
| { }; |
| |
| template <class _Tp> |
| struct is_same<_Tp, _Tp> : |
| public true_type |
| { }; |
| |
| // is_base_of |
| // is_convertible |
| |
| // 4.7.1 const-volatile modifications |
| |
| template <class _Tp> |
| struct remove_const |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_const<_Tp const> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_volatile |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_volatile<_Tp volatile> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_cv |
| { |
| typedef typename remove_const<typename remove_volatile<_Tp>::type>::type type; |
| }; |
| |
| template <class _Tp> |
| struct add_const |
| { |
| typedef _Tp const type; |
| }; |
| |
| template <class _Tp> |
| struct add_volatile |
| { |
| typedef _Tp volatile type; |
| }; |
| |
| template <class _Tp> |
| struct add_cv |
| { |
| typedef typename add_const<typename add_volatile<_Tp>::type>::type type; |
| }; |
| |
| // 4.7.2 reference modifications: |
| |
| template <class _Tp> |
| struct remove_reference |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_reference<_Tp&> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct add_reference |
| { |
| typedef _Tp& type; |
| }; |
| |
| template <class _Tp> |
| struct add_reference<_Tp&> |
| { |
| typedef _Tp& type; |
| }; |
| |
| // 4.7.3 array modifications (see above) |
| |
| // 4.7.4 pointer modifications: |
| |
| template <class _Tp> |
| struct remove_pointer |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_pointer<_Tp *> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_pointer<_Tp * const> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_pointer<_Tp * volatile> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct remove_pointer<_Tp * const volatile> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <class _Tp> |
| struct add_pointer |
| { |
| typedef typename remove_reference<_Tp>::type * type; |
| }; |
| |
| // 20.5.7 other transformations: |
| |
| // template <std::size_t Len, std::size_t Align> struct aligned_storage; |
| // template <std::size_t Len, class... Types> struct aligned_union; |
| |
| namespace detail { |
| |
| template <bool,class _U> |
| struct _decay_aux2 |
| { |
| typedef typename remove_cv<_U>::type type; |
| }; |
| |
| template <class _U> |
| struct _decay_aux2<true,_U> |
| { |
| typedef typename add_pointer<_U>::type type; |
| }; |
| |
| template <bool, class _U> |
| struct _decay_aux1 |
| { |
| typedef typename _decay_aux2<is_function<_U>::value,_U>::type type; |
| }; |
| |
| template <class _U> |
| struct _decay_aux1<true,_U> |
| { |
| typedef typename remove_extent<_U>::type* type; |
| }; |
| |
| } // namespace detail |
| |
| template <class _Tp> |
| class decay |
| { |
| private: |
| typedef typename remove_reference<_Tp>::type _U; |
| |
| public: |
| typedef typename detail::_decay_aux1<is_array<_U>::value,_U>::type type; |
| }; |
| |
| template <bool, class _Tp = void> |
| struct enable_if |
| { |
| }; |
| |
| template <class _Tp> |
| struct enable_if<true,_Tp> |
| { |
| typedef _Tp type; |
| }; |
| |
| template <bool, class _Tp1, class _Tp2> |
| struct conditional |
| { |
| typedef _Tp2 type; |
| }; |
| |
| template <class _Tp1, class _Tp2> |
| struct conditional<true,_Tp1,_Tp2> |
| { |
| typedef _Tp1 type; |
| }; |
| |
| // template <class... _Tp> 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 <tr1/type_traits> |
| // # endif |
| |
| #if (_STLP_OUTERMOST_HEADER_ID == 0x3) |
| # include <stl/_epilog.h> |
| # undef _STLP_OUTERMOST_HEADER_ID |
| #endif |
| |
| #endif // __STLP_TYPE_TRAITS |
| |