| // TR1 type_traits -*- C++ -*- |
| |
| // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. |
| // |
| // This file is part of the GNU ISO C++ Library. This library is free |
| // software; you can redistribute it and/or modify it under the |
| // terms of the GNU General Public License as published by the |
| // Free Software Foundation; either version 3, or (at your option) |
| // any later version. |
| |
| // This library is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| // Under Section 7 of GPL version 3, you are granted additional |
| // permissions described in the GCC Runtime Library Exception, version |
| // 3.1, as published by the Free Software Foundation. |
| |
| // You should have received a copy of the GNU General Public License and |
| // a copy of the GCC Runtime Library Exception along with this program; |
| // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
| // <http://www.gnu.org/licenses/>. |
| |
| /** @file tr1_impl/type_traits |
| * This is an internal header file, included by other library headers. |
| * You should not attempt to use it directly. |
| */ |
| |
| namespace std |
| { |
| _GLIBCXX_BEGIN_NAMESPACE_TR1 |
| |
| /** |
| * @defgroup metaprogramming Type Traits |
| * @ingroup utilities |
| * |
| * Compile time type transformation and information. |
| * @{ |
| */ |
| |
| // For use in __is_convertible_simple. |
| struct __sfinae_types |
| { |
| typedef char __one; |
| typedef struct { char __arr[2]; } __two; |
| }; |
| |
| #define _DEFINE_SPEC_0_HELPER \ |
| template<> |
| |
| #define _DEFINE_SPEC_1_HELPER \ |
| template<typename _Tp> |
| |
| #define _DEFINE_SPEC_2_HELPER \ |
| template<typename _Tp, typename _Cp> |
| |
| #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ |
| _DEFINE_SPEC_##_Order##_HELPER \ |
| struct _Trait<_Type> \ |
| : public integral_constant<bool, _Value> { }; |
| |
| // helper classes [4.3]. |
| |
| /// integral_constant |
| template<typename _Tp, _Tp __v> |
| struct integral_constant |
| { |
| static const _Tp value = __v; |
| typedef _Tp value_type; |
| typedef integral_constant<_Tp, __v> type; |
| }; |
| |
| /// typedef for true_type |
| typedef integral_constant<bool, true> true_type; |
| |
| /// typedef for false_type |
| typedef integral_constant<bool, false> false_type; |
| |
| template<typename _Tp, _Tp __v> |
| const _Tp integral_constant<_Tp, __v>::value; |
| |
| /// remove_cv |
| template<typename> |
| struct remove_cv; |
| |
| template<typename> |
| struct __is_void_helper |
| : public false_type { }; |
| _DEFINE_SPEC(0, __is_void_helper, void, true) |
| |
| // primary type categories [4.5.1]. |
| |
| /// is_void |
| template<typename _Tp> |
| struct is_void |
| : public integral_constant<bool, (__is_void_helper<typename |
| remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| template<typename> |
| struct __is_integral_helper |
| : public false_type { }; |
| _DEFINE_SPEC(0, __is_integral_helper, bool, true) |
| _DEFINE_SPEC(0, __is_integral_helper, char, true) |
| _DEFINE_SPEC(0, __is_integral_helper, signed char, true) |
| _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) |
| #ifdef _GLIBCXX_USE_WCHAR_T |
| _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) |
| #endif |
| #ifdef _GLIBCXX_INCLUDE_AS_CXX0X |
| _DEFINE_SPEC(0, __is_integral_helper, char16_t, true) |
| _DEFINE_SPEC(0, __is_integral_helper, char32_t, true) |
| #endif |
| _DEFINE_SPEC(0, __is_integral_helper, short, true) |
| _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) |
| _DEFINE_SPEC(0, __is_integral_helper, int, true) |
| _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) |
| _DEFINE_SPEC(0, __is_integral_helper, long, true) |
| _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) |
| _DEFINE_SPEC(0, __is_integral_helper, long long, true) |
| _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) |
| |
| /// is_integral |
| template<typename _Tp> |
| struct is_integral |
| : public integral_constant<bool, (__is_integral_helper<typename |
| remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| template<typename> |
| struct __is_floating_point_helper |
| : public false_type { }; |
| _DEFINE_SPEC(0, __is_floating_point_helper, float, true) |
| _DEFINE_SPEC(0, __is_floating_point_helper, double, true) |
| _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) |
| |
| /// is_floating_point |
| template<typename _Tp> |
| struct is_floating_point |
| : public integral_constant<bool, (__is_floating_point_helper<typename |
| remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| /// is_array |
| template<typename> |
| struct is_array |
| : public false_type { }; |
| |
| template<typename _Tp, std::size_t _Size> |
| struct is_array<_Tp[_Size]> |
| : public true_type { }; |
| |
| template<typename _Tp> |
| struct is_array<_Tp[]> |
| : public true_type { }; |
| |
| template<typename> |
| struct __is_pointer_helper |
| : public false_type { }; |
| _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) |
| |
| /// is_pointer |
| template<typename _Tp> |
| struct is_pointer |
| : public integral_constant<bool, (__is_pointer_helper<typename |
| remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| /// is_reference |
| template<typename _Tp> |
| struct is_reference; |
| |
| /// is_function |
| template<typename _Tp> |
| struct is_function; |
| |
| template<typename> |
| struct __is_member_object_pointer_helper |
| : public false_type { }; |
| _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, |
| !is_function<_Tp>::value) |
| |
| /// is_member_object_pointer |
| template<typename _Tp> |
| struct is_member_object_pointer |
| : public integral_constant<bool, (__is_member_object_pointer_helper< |
| typename remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| template<typename> |
| struct __is_member_function_pointer_helper |
| : public false_type { }; |
| _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, |
| is_function<_Tp>::value) |
| |
| /// is_member_function_pointer |
| template<typename _Tp> |
| struct is_member_function_pointer |
| : public integral_constant<bool, (__is_member_function_pointer_helper< |
| typename remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| /// is_enum |
| template<typename _Tp> |
| struct is_enum |
| : public integral_constant<bool, __is_enum(_Tp)> |
| { }; |
| |
| /// is_union |
| template<typename _Tp> |
| struct is_union |
| : public integral_constant<bool, __is_union(_Tp)> |
| { }; |
| |
| /// is_class |
| template<typename _Tp> |
| struct is_class |
| : public integral_constant<bool, __is_class(_Tp)> |
| { }; |
| |
| /// is_function |
| template<typename> |
| struct is_function |
| : public false_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes...)> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes......)> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes...) const> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes......) const> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes...) volatile> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes......) volatile> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes...) const volatile> |
| : public true_type { }; |
| template<typename _Res, typename... _ArgTypes> |
| struct is_function<_Res(_ArgTypes......) const volatile> |
| : public true_type { }; |
| |
| // composite type traits [4.5.2]. |
| |
| /// is_arithmetic |
| template<typename _Tp> |
| struct is_arithmetic |
| : public integral_constant<bool, (is_integral<_Tp>::value |
| || is_floating_point<_Tp>::value)> |
| { }; |
| |
| /// is_fundamental |
| template<typename _Tp> |
| struct is_fundamental |
| : public integral_constant<bool, (is_arithmetic<_Tp>::value |
| || is_void<_Tp>::value)> |
| { }; |
| |
| /// is_object |
| template<typename _Tp> |
| struct is_object |
| : public integral_constant<bool, !(is_function<_Tp>::value |
| || is_reference<_Tp>::value |
| || is_void<_Tp>::value)> |
| { }; |
| |
| /// is_member_pointer |
| template<typename _Tp> |
| struct is_member_pointer; |
| |
| /// is_scalar |
| template<typename _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)> |
| { }; |
| |
| /// is_compound |
| template<typename _Tp> |
| struct is_compound |
| : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; |
| |
| /// is_member_pointer |
| template<typename _Tp> |
| struct __is_member_pointer_helper |
| : public false_type { }; |
| _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) |
| |
| template<typename _Tp> |
| struct is_member_pointer |
| : public integral_constant<bool, (__is_member_pointer_helper< |
| typename remove_cv<_Tp>::type>::value)> |
| { }; |
| |
| // type properties [4.5.3]. |
| /// is_const |
| template<typename> |
| struct is_const |
| : public false_type { }; |
| |
| template<typename _Tp> |
| struct is_const<_Tp const> |
| : public true_type { }; |
| |
| /// is_volatile |
| template<typename> |
| struct is_volatile |
| : public false_type { }; |
| |
| template<typename _Tp> |
| struct is_volatile<_Tp volatile> |
| : public true_type { }; |
| |
| /// is_empty |
| template<typename _Tp> |
| struct is_empty |
| : public integral_constant<bool, __is_empty(_Tp)> |
| { }; |
| |
| /// is_polymorphic |
| template<typename _Tp> |
| struct is_polymorphic |
| : public integral_constant<bool, __is_polymorphic(_Tp)> |
| { }; |
| |
| /// is_abstract |
| template<typename _Tp> |
| struct is_abstract |
| : public integral_constant<bool, __is_abstract(_Tp)> |
| { }; |
| |
| /// has_virtual_destructor |
| template<typename _Tp> |
| struct has_virtual_destructor |
| : public integral_constant<bool, __has_virtual_destructor(_Tp)> |
| { }; |
| |
| /// alignment_of |
| template<typename _Tp> |
| struct alignment_of |
| : public integral_constant<std::size_t, __alignof__(_Tp)> { }; |
| |
| /// rank |
| template<typename> |
| struct rank |
| : public integral_constant<std::size_t, 0> { }; |
| |
| template<typename _Tp, std::size_t _Size> |
| struct rank<_Tp[_Size]> |
| : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; |
| |
| template<typename _Tp> |
| struct rank<_Tp[]> |
| : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; |
| |
| /// extent |
| template<typename, unsigned _Uint = 0> |
| struct extent |
| : public integral_constant<std::size_t, 0> { }; |
| |
| template<typename _Tp, unsigned _Uint, std::size_t _Size> |
| struct extent<_Tp[_Size], _Uint> |
| : public integral_constant<std::size_t, |
| _Uint == 0 ? _Size : extent<_Tp, |
| _Uint - 1>::value> |
| { }; |
| |
| template<typename _Tp, unsigned _Uint> |
| struct extent<_Tp[], _Uint> |
| : public integral_constant<std::size_t, |
| _Uint == 0 ? 0 : extent<_Tp, |
| _Uint - 1>::value> |
| { }; |
| |
| // relationships between types [4.6]. |
| |
| /// is_same |
| template<typename, typename> |
| struct is_same |
| : public false_type { }; |
| |
| template<typename _Tp> |
| struct is_same<_Tp, _Tp> |
| : public true_type { }; |
| |
| // const-volatile modifications [4.7.1]. |
| |
| /// remove_const |
| template<typename _Tp> |
| struct remove_const |
| { typedef _Tp type; }; |
| |
| template<typename _Tp> |
| struct remove_const<_Tp const> |
| { typedef _Tp type; }; |
| |
| /// remove_volatile |
| template<typename _Tp> |
| struct remove_volatile |
| { typedef _Tp type; }; |
| |
| template<typename _Tp> |
| struct remove_volatile<_Tp volatile> |
| { typedef _Tp type; }; |
| |
| /// remove_cv |
| template<typename _Tp> |
| struct remove_cv |
| { |
| typedef typename |
| remove_const<typename remove_volatile<_Tp>::type>::type type; |
| }; |
| |
| /// add_const |
| template<typename _Tp> |
| struct add_const |
| { typedef _Tp const type; }; |
| |
| /// add_volatile |
| template<typename _Tp> |
| struct add_volatile |
| { typedef _Tp volatile type; }; |
| |
| /// add_cv |
| template<typename _Tp> |
| struct add_cv |
| { |
| typedef typename |
| add_const<typename add_volatile<_Tp>::type>::type type; |
| }; |
| |
| // array modifications [4.7.3]. |
| |
| /// remove_extent |
| template<typename _Tp> |
| struct remove_extent |
| { typedef _Tp type; }; |
| |
| template<typename _Tp, std::size_t _Size> |
| struct remove_extent<_Tp[_Size]> |
| { typedef _Tp type; }; |
| |
| template<typename _Tp> |
| struct remove_extent<_Tp[]> |
| { typedef _Tp type; }; |
| |
| /// remove_all_extents |
| template<typename _Tp> |
| struct remove_all_extents |
| { typedef _Tp type; }; |
| |
| template<typename _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; }; |
| |
| // pointer modifications [4.7.4]. |
| |
| template<typename _Tp, typename> |
| struct __remove_pointer_helper |
| { typedef _Tp type; }; |
| |
| template<typename _Tp, typename _Up> |
| struct __remove_pointer_helper<_Tp, _Up*> |
| { typedef _Up type; }; |
| |
| /// remove_pointer |
| template<typename _Tp> |
| struct remove_pointer |
| : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> |
| { }; |
| |
| template<typename> |
| struct remove_reference; |
| |
| /// add_pointer |
| template<typename _Tp> |
| struct add_pointer |
| { typedef typename remove_reference<_Tp>::type* type; }; |
| |
| #undef _DEFINE_SPEC_0_HELPER |
| #undef _DEFINE_SPEC_1_HELPER |
| #undef _DEFINE_SPEC_2_HELPER |
| #undef _DEFINE_SPEC |
| |
| // @} group metaprogramming |
| _GLIBCXX_END_NAMESPACE_TR1 |
| } |