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 }

Generated on Thu Jul 23 21:16:29 2009 for libstdc++ by  doxygen 1.5.8