tr1_impl/type_traits

Go to the documentation of this file.
00001 // TR1 type_traits -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /** @file tr1_impl/type_traits
00031 *  This is an internal header file, included by other library headers.
00032 *  You should not attempt to use it directly.
00033 */
00034 
00035 namespace std
00036 {
00037 _GLIBCXX_BEGIN_NAMESPACE_TR1
00038 
00039   // For use in __is_convertible_simple.
00040   struct __sfinae_types
00041   {
00042     typedef char __one;
00043     typedef struct { char __arr[2]; } __two;
00044   };
00045 
00046 #define _DEFINE_SPEC_BODY(_Value)                                    \
00047     : public integral_constant<bool, _Value> { };
00048 
00049 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
00050   template<>                                                         \
00051     struct _Spec                                                     \
00052     _DEFINE_SPEC_BODY(_Value)
00053 
00054 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value)                         \
00055   template<typename _Tp>                                             \
00056     struct _Spec                                                     \
00057     _DEFINE_SPEC_BODY(_Value)
00058       
00059 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value)                         \
00060   template<typename _Tp, typename _Cp>                               \
00061     struct _Spec                                                     \
00062     _DEFINE_SPEC_BODY(_Value)
00063 
00064 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)                  \
00065   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value)              \
00066   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value)        \
00067   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value)     \
00068   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
00069 
00070   /// helper classes [4.3].
00071   template<typename _Tp, _Tp __v>
00072     struct integral_constant
00073     {
00074       static const _Tp                      value = __v;
00075       typedef _Tp                           value_type;
00076       typedef integral_constant<_Tp, __v>   type;
00077     };
00078   
00079   /// typedef for true_type
00080   typedef integral_constant<bool, true>     true_type;
00081 
00082   /// typedef for true_type
00083   typedef integral_constant<bool, false>    false_type;
00084 
00085   template<typename _Tp, _Tp __v>
00086     const _Tp integral_constant<_Tp, __v>::value;
00087 
00088   /// primary type categories [4.5.1].
00089   template<typename>
00090     struct is_void
00091     : public false_type { };
00092   _DEFINE_SPEC(0, is_void, void, true)
00093 
00094   /// is_integral
00095   template<typename>
00096     struct is_integral
00097     : public false_type { };
00098   _DEFINE_SPEC(0, is_integral, bool, true)
00099   _DEFINE_SPEC(0, is_integral, char, true)
00100   _DEFINE_SPEC(0, is_integral, signed char, true)
00101   _DEFINE_SPEC(0, is_integral, unsigned char, true)
00102 #ifdef _GLIBCXX_USE_WCHAR_T
00103   _DEFINE_SPEC(0, is_integral, wchar_t, true)
00104 #endif
00105   _DEFINE_SPEC(0, is_integral, short, true)
00106   _DEFINE_SPEC(0, is_integral, unsigned short, true)
00107   _DEFINE_SPEC(0, is_integral, int, true)
00108   _DEFINE_SPEC(0, is_integral, unsigned int, true)
00109   _DEFINE_SPEC(0, is_integral, long, true)
00110   _DEFINE_SPEC(0, is_integral, unsigned long, true)
00111   _DEFINE_SPEC(0, is_integral, long long, true)
00112   _DEFINE_SPEC(0, is_integral, unsigned long long, true)
00113 
00114   /// is_floating_point
00115   template<typename>
00116     struct is_floating_point
00117     : public false_type { };
00118   _DEFINE_SPEC(0, is_floating_point, float, true)
00119   _DEFINE_SPEC(0, is_floating_point, double, true)
00120   _DEFINE_SPEC(0, is_floating_point, long double, true)
00121 
00122   /// is_array
00123   template<typename>
00124     struct is_array
00125     : public false_type { };
00126 
00127   template<typename _Tp, std::size_t _Size>
00128     struct is_array<_Tp[_Size]>
00129     : public true_type { };
00130 
00131   template<typename _Tp>
00132     struct is_array<_Tp[]>
00133     : public true_type { };
00134 
00135   /// is_pointer
00136   template<typename>
00137     struct is_pointer
00138     : public false_type { };
00139   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
00140 
00141   /// is_reference
00142   template<typename _Tp>
00143     struct is_reference;
00144 
00145   /// is_function
00146   template<typename _Tp>
00147     struct is_function;
00148 
00149   /// is_member_object_pointer
00150   template<typename>
00151     struct is_member_object_pointer
00152     : public false_type { };
00153   _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
00154            !is_function<_Tp>::value)
00155 
00156   /// is_member_function_pointer
00157   template<typename>
00158     struct is_member_function_pointer
00159     : public false_type { };
00160   _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
00161            is_function<_Tp>::value)
00162 
00163   /// is_enum
00164   template<typename _Tp>
00165     struct is_enum
00166     : public integral_constant<bool, __is_enum(_Tp)>
00167     { };
00168 
00169   /// is_union
00170   template<typename _Tp>
00171     struct is_union
00172     : public integral_constant<bool, __is_union(_Tp)>
00173     { };
00174 
00175   /// is_class
00176   template<typename _Tp>
00177     struct is_class
00178     : public integral_constant<bool, __is_class(_Tp)>
00179     { };
00180 
00181   template<typename _Tp>
00182     struct __in_array
00183     : public __sfinae_types
00184     {
00185     private:
00186       template<typename _Up>
00187         static __one __test(_Up(*)[1]);
00188       template<typename>
00189         static __two __test(...);
00190     
00191     public:
00192       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
00193     };
00194 
00195   /// is_abstract
00196   template<typename _Tp>
00197     struct is_abstract;
00198 
00199   /// is_function
00200   template<typename _Tp>
00201     struct is_function
00202     : public integral_constant<bool, !(__in_array<_Tp>::__value
00203                        || is_abstract<_Tp>::value
00204                        || is_reference<_Tp>::value
00205                        || is_void<_Tp>::value)>
00206     { };
00207 
00208   /// composite type traits [4.5.2].
00209   template<typename _Tp>
00210     struct is_arithmetic
00211     : public integral_constant<bool, (is_integral<_Tp>::value
00212                       || is_floating_point<_Tp>::value)>
00213     { };
00214 
00215   /// is_fundamental
00216   template<typename _Tp>
00217     struct is_fundamental
00218     : public integral_constant<bool, (is_arithmetic<_Tp>::value
00219                       || is_void<_Tp>::value)>
00220     { };
00221 
00222   /// is_object
00223   template<typename _Tp>
00224     struct is_object
00225     : public integral_constant<bool, !(is_function<_Tp>::value
00226                        || is_reference<_Tp>::value
00227                        || is_void<_Tp>::value)>
00228     { };
00229 
00230   /// is_member_pointer
00231   template<typename _Tp>
00232     struct is_member_pointer;
00233 
00234   /// is_scalal
00235   template<typename _Tp>
00236     struct is_scalar
00237     : public integral_constant<bool, (is_arithmetic<_Tp>::value
00238                       || is_enum<_Tp>::value
00239                       || is_pointer<_Tp>::value
00240                       || is_member_pointer<_Tp>::value)>
00241     { };
00242 
00243   /// is_compound
00244   template<typename _Tp>
00245     struct is_compound
00246     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
00247 
00248   /// is_member_pointer
00249   template<typename _Tp>
00250     struct is_member_pointer
00251     : public integral_constant<bool,
00252                    (is_member_object_pointer<_Tp>::value
00253                 || is_member_function_pointer<_Tp>::value)>
00254     { };
00255 
00256   /// type properties [4.5.3].
00257   template<typename>
00258     struct is_const
00259     : public false_type { };
00260 
00261   /// is_const
00262   template<typename _Tp>
00263     struct is_const<_Tp const>
00264     : public true_type { };
00265   
00266   /// is_volatile
00267   template<typename>
00268     struct is_volatile
00269     : public false_type { };
00270 
00271   template<typename _Tp>
00272     struct is_volatile<_Tp volatile>
00273     : public true_type { };
00274 
00275   /// is_empty
00276   template<typename _Tp>
00277     struct is_empty
00278     : public integral_constant<bool, __is_empty(_Tp)>
00279     { };
00280 
00281   /// is_polymorphic
00282   template<typename _Tp>
00283     struct is_polymorphic
00284     : public integral_constant<bool, __is_polymorphic(_Tp)>
00285     { };
00286 
00287   /// is_abstract
00288   template<typename _Tp>
00289     struct is_abstract
00290     : public integral_constant<bool, __is_abstract(_Tp)>
00291     { };
00292 
00293   /// has_virtual_destructor
00294   template<typename _Tp>
00295     struct has_virtual_destructor
00296     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
00297     { };
00298 
00299   /// alignment_of
00300   template<typename _Tp>
00301     struct alignment_of
00302     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
00303   
00304   /// rank
00305   template<typename>
00306     struct rank
00307     : public integral_constant<std::size_t, 0> { };
00308    
00309   template<typename _Tp, std::size_t _Size>
00310     struct rank<_Tp[_Size]>
00311     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
00312 
00313   template<typename _Tp>
00314     struct rank<_Tp[]>
00315     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
00316 
00317   /// extent
00318   template<typename, unsigned _Uint = 0>
00319     struct extent
00320     : public integral_constant<std::size_t, 0> { };
00321   
00322   template<typename _Tp, unsigned _Uint, std::size_t _Size>
00323     struct extent<_Tp[_Size], _Uint>
00324     : public integral_constant<std::size_t,
00325                    _Uint == 0 ? _Size : extent<_Tp,
00326                                _Uint - 1>::value>
00327     { };
00328 
00329   template<typename _Tp, unsigned _Uint>
00330     struct extent<_Tp[], _Uint>
00331     : public integral_constant<std::size_t,
00332                    _Uint == 0 ? 0 : extent<_Tp,
00333                                _Uint - 1>::value>
00334     { };
00335 
00336   /// relationships between types [4.6].
00337   template<typename, typename>
00338     struct is_same
00339     : public false_type { };
00340 
00341   template<typename _Tp>
00342     struct is_same<_Tp, _Tp>
00343     : public true_type { };
00344 
00345   /// const-volatile modifications [4.7.1].
00346   template<typename _Tp>
00347     struct remove_const
00348     { typedef _Tp     type; };
00349 
00350   template<typename _Tp>
00351     struct remove_const<_Tp const>
00352     { typedef _Tp     type; };
00353   
00354   /// remove_volatile
00355   template<typename _Tp>
00356     struct remove_volatile
00357     { typedef _Tp     type; };
00358 
00359   template<typename _Tp>
00360     struct remove_volatile<_Tp volatile>
00361     { typedef _Tp     type; };
00362   
00363   /// remove_cv
00364   template<typename _Tp>
00365     struct remove_cv
00366     {
00367       typedef typename
00368       remove_const<typename remove_volatile<_Tp>::type>::type     type;
00369     };
00370   
00371   /// add_const
00372   template<typename _Tp>
00373     struct add_const
00374     { typedef _Tp const     type; };
00375    
00376   /// add_volatile
00377   template<typename _Tp>
00378     struct add_volatile
00379     { typedef _Tp volatile     type; };
00380   
00381   /// add_cv
00382   template<typename _Tp>
00383     struct add_cv
00384     {
00385       typedef typename
00386       add_const<typename add_volatile<_Tp>::type>::type     type;
00387     };
00388 
00389   /// array modifications [4.7.3].
00390   template<typename _Tp>
00391     struct remove_extent
00392     { typedef _Tp     type; };
00393 
00394   template<typename _Tp, std::size_t _Size>
00395     struct remove_extent<_Tp[_Size]>
00396     { typedef _Tp     type; };
00397 
00398   template<typename _Tp>
00399     struct remove_extent<_Tp[]>
00400     { typedef _Tp     type; };
00401 
00402   /// remove_all_extents
00403   template<typename _Tp>
00404     struct remove_all_extents
00405     { typedef _Tp     type; };
00406 
00407   template<typename _Tp, std::size_t _Size>
00408     struct remove_all_extents<_Tp[_Size]>
00409     { typedef typename remove_all_extents<_Tp>::type     type; };
00410 
00411   template<typename _Tp>
00412     struct remove_all_extents<_Tp[]>
00413     { typedef typename remove_all_extents<_Tp>::type     type; };
00414 
00415   /// pointer modifications [4.7.4].
00416 #undef _DEFINE_SPEC_BODY
00417 #define _DEFINE_SPEC_BODY(_Value)      \
00418     { typedef _Tp     type; };
00419 
00420   /// remove_pointer
00421   template<typename _Tp>
00422     struct remove_pointer
00423     { typedef _Tp     type; };
00424   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
00425 
00426   /// remove_reference
00427   template<typename _Tp>
00428     struct remove_reference;
00429 
00430   /// add_pointer
00431   template<typename _Tp>
00432     struct add_pointer
00433     { typedef typename remove_reference<_Tp>::type*     type; };
00434 
00435 #undef _DEFINE_SPEC_0_HELPER
00436 #undef _DEFINE_SPEC_1_HELPER
00437 #undef _DEFINE_SPEC_2_HELPER
00438 #undef _DEFINE_SPEC
00439 #undef _DEFINE_SPEC_BODY
00440 
00441 _GLIBCXX_END_NAMESPACE_TR1
00442 }

Generated on Wed Mar 26 00:43:19 2008 for libstdc++ by  doxygen 1.5.1