# tr1_impl/type_traits

Go to the documentation of this file.

    00001 // TR1 type_traits -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 3, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // Under Section 7 of GPL version 3, you are granted additional
    00017 // permissions described in the GCC Runtime Library Exception, version
    00018 // 3.1, as published by the Free Software Foundation.
    00019
    00020 // You should have received a copy of the GNU General Public License and
    00021 // a copy of the GCC Runtime Library Exception along with this program;
    00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00023 // <http://www.gnu.org/licenses/>.
    00024
    00025 /** @file tr1_impl/type_traits
    00026 *  This is an internal header file, included by other library headers.
    00027 *  You should not attempt to use it directly.
    00028 */
    00029
    00030 namespace std
    00031 {
    00032 _GLIBCXX_BEGIN_NAMESPACE_TR1
    00033
    00034   /**
    00035    * @defgroup metaprogramming Type Traits
    00036    * @ingroup utilities
    00037    *
    00038    * Compile time type transformation and information.
    00039    * @{
    00040    */
    00041
    00042   // For use in __is_convertible_simple.
    00043   struct __sfinae_types
    00044   {
    00045     typedef char __one;
    00046     typedef struct { char __arr[2]; } __two;
    00047   };
    00048
    00049 #define _DEFINE_SPEC_0_HELPER                          \
    00050   template<>
    00051
    00052 #define _DEFINE_SPEC_1_HELPER                          \
    00053   template<typename _Tp>
    00054
    00055 #define _DEFINE_SPEC_2_HELPER                          \
    00056   template<typename _Tp, typename _Cp>
    00057
    00058 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
    00059   _DEFINE_SPEC_##_Order##_HELPER                       \
    00060     struct _Trait<_Type>                               \
    00061     : public integral_constant<bool, _Value> { };
    00062
    00063   // helper classes [4.3].
    00064
    00065   /// integral_constant
    00066   template<typename _Tp, _Tp __v>
    00067     struct integral_constant
    00068     {
    00069       static const _Tp                      value = __v;
    00070       typedef _Tp                           value_type;
    00071       typedef integral_constant<_Tp, __v>   type;
    00072     };
    00073
    00074   /// typedef for true_type
    00075   typedef integral_constant<bool, true>     true_type;
    00076
    00077   /// typedef for false_type
    00078   typedef integral_constant<bool, false>    false_type;
    00079
    00080   template<typename _Tp, _Tp __v>
    00081     const _Tp integral_constant<_Tp, __v>::value;
    00082
    00083   /// remove_cv
    00084   template<typename>
    00085     struct remove_cv;
    00086
    00087   template<typename>
    00088     struct __is_void_helper
    00089     : public false_type { };
    00090   _DEFINE_SPEC(0, __is_void_helper, void, true)
    00091
    00092   // primary type categories [4.5.1].
    00093
    00094   /// is_void
    00095   template<typename _Tp>
    00096     struct is_void
    00097     : public integral_constant<bool, (__is_void_helper<typename
    00098                       remove_cv<_Tp>::type>::value)>
    00099     { };
    00100
    00101   template<typename>
    00102     struct __is_integral_helper
    00103     : public false_type { };
    00104   _DEFINE_SPEC(0, __is_integral_helper, bool, true)
    00105   _DEFINE_SPEC(0, __is_integral_helper, char, true)
    00106   _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
    00107   _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
    00108 #ifdef _GLIBCXX_USE_WCHAR_T
    00109   _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
    00110 #endif
    00111 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    00112   _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
    00113   _DEFINE_SPEC(0, __is_integral_helper, char32_t, true)
    00114 #endif
    00115   _DEFINE_SPEC(0, __is_integral_helper, short, true)
    00116   _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
    00117   _DEFINE_SPEC(0, __is_integral_helper, int, true)
    00118   _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
    00119   _DEFINE_SPEC(0, __is_integral_helper, long, true)
    00120   _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
    00121   _DEFINE_SPEC(0, __is_integral_helper, long long, true)
    00122   _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
    00123
    00124   /// is_integral
    00125   template<typename _Tp>
    00126     struct is_integral
    00127     : public integral_constant<bool, (__is_integral_helper<typename
    00128                       remove_cv<_Tp>::type>::value)>
    00129     { };
    00130
    00131   template<typename>
    00132     struct __is_floating_point_helper
    00133     : public false_type { };
    00134   _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
    00135   _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
    00136   _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
    00137
    00138   /// is_floating_point
    00139   template<typename _Tp>
    00140     struct is_floating_point
    00141     : public integral_constant<bool, (__is_floating_point_helper<typename
    00142                       remove_cv<_Tp>::type>::value)>
    00143     { };
    00144
    00145   /// is_array
    00146   template<typename>
    00147     struct is_array
    00148     : public false_type { };
    00149
    00150   template<typename _Tp, std::size_t _Size>
    00151     struct is_array<_Tp[_Size]>
    00152     : public true_type { };
    00153
    00154   template<typename _Tp>
    00155     struct is_array<_Tp[]>
    00156     : public true_type { };
    00157
    00158   template<typename>
    00159     struct __is_pointer_helper
    00160     : public false_type { };
    00161   _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
    00162
    00163   /// is_pointer
    00164   template<typename _Tp>
    00165     struct is_pointer
    00166     : public integral_constant<bool, (__is_pointer_helper<typename
    00167                       remove_cv<_Tp>::type>::value)>
    00168     { };
    00169
    00170   /// is_reference
    00171   template<typename _Tp>
    00172     struct is_reference;
    00173
    00174   /// is_function
    00175   template<typename _Tp>
    00176     struct is_function;
    00177
    00178   template<typename>
    00179     struct __is_member_object_pointer_helper
    00180     : public false_type { };
    00181   _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
    00182            !is_function<_Tp>::value)
    00183
    00184   /// is_member_object_pointer
    00185   template<typename _Tp>
    00186     struct is_member_object_pointer
    00187     : public integral_constant<bool, (__is_member_object_pointer_helper<
    00188                       typename remove_cv<_Tp>::type>::value)>
    00189     { };
    00190
    00191   template<typename>
    00192     struct __is_member_function_pointer_helper
    00193     : public false_type { };
    00194   _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
    00195            is_function<_Tp>::value)
    00196
    00197   /// is_member_function_pointer
    00198   template<typename _Tp>
    00199     struct is_member_function_pointer
    00200     : public integral_constant<bool, (__is_member_function_pointer_helper<
    00201                       typename remove_cv<_Tp>::type>::value)>
    00202     { };
    00203
    00204   /// is_enum
    00205   template<typename _Tp>
    00206     struct is_enum
    00207     : public integral_constant<bool, __is_enum(_Tp)>
    00208     { };
    00209
    00210   /// is_union
    00211   template<typename _Tp>
    00212     struct is_union
    00213     : public integral_constant<bool, __is_union(_Tp)>
    00214     { };
    00215
    00216   /// is_class
    00217   template<typename _Tp>
    00218     struct is_class
    00219     : public integral_constant<bool, __is_class(_Tp)>
    00220     { };
    00221
    00222   /// is_function
    00223   template<typename>
    00224     struct is_function
    00225     : public false_type { };
    00226   template<typename _Res, typename... _ArgTypes>
    00227     struct is_function<_Res(_ArgTypes...)>
    00228     : public true_type { };
    00229   template<typename _Res, typename... _ArgTypes>
    00230     struct is_function<_Res(_ArgTypes......)>
    00231     : public true_type { };
    00232   template<typename _Res, typename... _ArgTypes>
    00233     struct is_function<_Res(_ArgTypes...) const>
    00234     : public true_type { };
    00235   template<typename _Res, typename... _ArgTypes>
    00236     struct is_function<_Res(_ArgTypes......) const>
    00237     : public true_type { };
    00238   template<typename _Res, typename... _ArgTypes>
    00239     struct is_function<_Res(_ArgTypes...) volatile>
    00240     : public true_type { };
    00241   template<typename _Res, typename... _ArgTypes>
    00242     struct is_function<_Res(_ArgTypes......) volatile>
    00243     : public true_type { };
    00244   template<typename _Res, typename... _ArgTypes>
    00245     struct is_function<_Res(_ArgTypes...) const volatile>
    00246     : public true_type { };
    00247   template<typename _Res, typename... _ArgTypes>
    00248     struct is_function<_Res(_ArgTypes......) const volatile>
    00249     : public true_type { };
    00250
    00251   // composite type traits [4.5.2].
    00252
    00253   /// is_arithmetic
    00254   template<typename _Tp>
    00255     struct is_arithmetic
    00256     : public integral_constant<bool, (is_integral<_Tp>::value
    00257                       || is_floating_point<_Tp>::value)>
    00258     { };
    00259
    00260   /// is_fundamental
    00261   template<typename _Tp>
    00262     struct is_fundamental
    00263     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    00264                       || is_void<_Tp>::value)>
    00265     { };
    00266
    00267   /// is_object
    00268   template<typename _Tp>
    00269     struct is_object
    00270     : public integral_constant<bool, !(is_function<_Tp>::value
    00271                        || is_reference<_Tp>::value
    00272                        || is_void<_Tp>::value)>
    00273     { };
    00274
    00275   /// is_member_pointer
    00276   template<typename _Tp>
    00277     struct is_member_pointer;
    00278
    00279   /// is_scalar
    00280   template<typename _Tp>
    00281     struct is_scalar
    00282     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    00283                       || is_enum<_Tp>::value
    00284                       || is_pointer<_Tp>::value
    00285                       || is_member_pointer<_Tp>::value)>
    00286     { };
    00287
    00288   /// is_compound
    00289   template<typename _Tp>
    00290     struct is_compound
    00291     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
    00292
    00293   /// is_member_pointer
    00294   template<typename _Tp>
    00295     struct __is_member_pointer_helper
    00296     : public false_type { };
    00297   _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
    00298
    00299   template<typename _Tp>
    00300   struct is_member_pointer
    00301     : public integral_constant<bool, (__is_member_pointer_helper<
    00302                       typename remove_cv<_Tp>::type>::value)>
    00303     { };
    00304
    00305   // type properties [4.5.3].
    00306   /// is_const
    00307   template<typename>
    00308     struct is_const
    00309     : public false_type { };
    00310
    00311   template<typename _Tp>
    00312     struct is_const<_Tp const>
    00313     : public true_type { };
    00314
    00315   /// is_volatile
    00316   template<typename>
    00317     struct is_volatile
    00318     : public false_type { };
    00319
    00320   template<typename _Tp>
    00321     struct is_volatile<_Tp volatile>
    00322     : public true_type { };
    00323
    00324   /// is_empty
    00325   template<typename _Tp>
    00326     struct is_empty
    00327     : public integral_constant<bool, __is_empty(_Tp)>
    00328     { };
    00329
    00330   /// is_polymorphic
    00331   template<typename _Tp>
    00332     struct is_polymorphic
    00333     : public integral_constant<bool, __is_polymorphic(_Tp)>
    00334     { };
    00335
    00336   /// is_abstract
    00337   template<typename _Tp>
    00338     struct is_abstract
    00339     : public integral_constant<bool, __is_abstract(_Tp)>
    00340     { };
    00341
    00342   /// has_virtual_destructor
    00343   template<typename _Tp>
    00344     struct has_virtual_destructor
    00345     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
    00346     { };
    00347
    00348   /// alignment_of
    00349   template<typename _Tp>
    00350     struct alignment_of
    00351     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
    00352
    00353   /// rank
    00354   template<typename>
    00355     struct rank
    00356     : public integral_constant<std::size_t, 0> { };
    00357
    00358   template<typename _Tp, std::size_t _Size>
    00359     struct rank<_Tp[_Size]>
    00360     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    00361
    00362   template<typename _Tp>
    00363     struct rank<_Tp[]>
    00364     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    00365
    00366   /// extent
    00367   template<typename, unsigned _Uint = 0>
    00368     struct extent
    00369     : public integral_constant<std::size_t, 0> { };
    00370
    00371   template<typename _Tp, unsigned _Uint, std::size_t _Size>
    00372     struct extent<_Tp[_Size], _Uint>
    00373     : public integral_constant<std::size_t,
    00374                    _Uint == 0 ? _Size : extent<_Tp,
    00375                                _Uint - 1>::value>
    00376     { };
    00377
    00378   template<typename _Tp, unsigned _Uint>
    00379     struct extent<_Tp[], _Uint>
    00380     : public integral_constant<std::size_t,
    00381                    _Uint == 0 ? 0 : extent<_Tp,
    00382                                _Uint - 1>::value>
    00383     { };
    00384
    00385   // relationships between types [4.6].
    00386
    00387   /// is_same
    00388   template<typename, typename>
    00389     struct is_same
    00390     : public false_type { };
    00391
    00392   template<typename _Tp>
    00393     struct is_same<_Tp, _Tp>
    00394     : public true_type { };
    00395
    00396   // const-volatile modifications [4.7.1].
    00397
    00398   /// remove_const
    00399   template<typename _Tp>
    00400     struct remove_const
    00401     { typedef _Tp     type; };
    00402
    00403   template<typename _Tp>
    00404     struct remove_const<_Tp const>
    00405     { typedef _Tp     type; };
    00406
    00407   /// remove_volatile
    00408   template<typename _Tp>
    00409     struct remove_volatile
    00410     { typedef _Tp     type; };
    00411
    00412   template<typename _Tp>
    00413     struct remove_volatile<_Tp volatile>
    00414     { typedef _Tp     type; };
    00415
    00416   /// remove_cv
    00417   template<typename _Tp>
    00418     struct remove_cv
    00419     {
    00420       typedef typename
    00421       remove_const<typename remove_volatile<_Tp>::type>::type     type;
    00422     };
    00423
    00424   /// add_const
    00425   template<typename _Tp>
    00426     struct add_const
    00427     { typedef _Tp const     type; };
    00428
    00429   /// add_volatile
    00430   template<typename _Tp>
    00431     struct add_volatile
    00432     { typedef _Tp volatile     type; };
    00433
    00434   /// add_cv
    00435   template<typename _Tp>
    00436     struct add_cv
    00437     {
    00438       typedef typename
    00439       add_const<typename add_volatile<_Tp>::type>::type     type;
    00440     };
    00441
    00442   // array modifications [4.7.3].
    00443
    00444   /// remove_extent
    00445   template<typename _Tp>
    00446     struct remove_extent
    00447     { typedef _Tp     type; };
    00448
    00449   template<typename _Tp, std::size_t _Size>
    00450     struct remove_extent<_Tp[_Size]>
    00451     { typedef _Tp     type; };
    00452
    00453   template<typename _Tp>
    00454     struct remove_extent<_Tp[]>
    00455     { typedef _Tp     type; };
    00456
    00457   /// remove_all_extents
    00458   template<typename _Tp>
    00459     struct remove_all_extents
    00460     { typedef _Tp     type; };
    00461
    00462   template<typename _Tp, std::size_t _Size>
    00463     struct remove_all_extents<_Tp[_Size]>
    00464     { typedef typename remove_all_extents<_Tp>::type     type; };
    00465
    00466   template<typename _Tp>
    00467     struct remove_all_extents<_Tp[]>
    00468     { typedef typename remove_all_extents<_Tp>::type     type; };
    00469
    00470   // pointer modifications [4.7.4].
    00471
    00472   template<typename _Tp, typename>
    00473     struct __remove_pointer_helper
    00474     { typedef _Tp     type; };
    00475
    00476   template<typename _Tp, typename _Up>
    00477     struct __remove_pointer_helper<_Tp, _Up*>
    00478     { typedef _Up     type; };
    00479
    00480   /// remove_pointer
    00481   template<typename _Tp>
    00482     struct remove_pointer
    00483     : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
    00484     { };
    00485
    00486   template<typename>
    00487     struct remove_reference;
    00488
    00489   /// add_pointer
    00490   template<typename _Tp>
    00491     struct add_pointer
    00492     { typedef typename remove_reference<_Tp>::type*     type; };
    00493
    00494 #undef _DEFINE_SPEC_0_HELPER
    00495 #undef _DEFINE_SPEC_1_HELPER
    00496 #undef _DEFINE_SPEC_2_HELPER
    00497 #undef _DEFINE_SPEC
    00498
    00499   // @} group metaprogramming
    00500 _GLIBCXX_END_NAMESPACE_TR1
    00501 }