# 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 }