# type_traits

Go to the documentation of this file.

    00001 // TR1 type_traits -*- C++ -*-
    00002
    00003 // Copyright (C) 2004, 2005, 2006 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/type_traits
    00031  *  This is a TR1 C++ Library header.
    00032  */
    00033
    00034 #ifndef _TR1_TYPE_TRAITS
    00035 #define _TR1_TYPE_TRAITS 1
    00036
    00037 #include <bits/c++config.h>
    00038 #include <tr1/type_traits_fwd.h>
    00039
    00040 // namespace std::tr1
    00041 namespace std
    00042 {
    00043 _GLIBCXX_BEGIN_NAMESPACE(tr1)
    00044
    00045   // For use in __in_array and elsewhere.
    00046   struct __sfinae_types
    00047   {
    00048     typedef char __one;
    00049     typedef struct { char __arr[2]; } __two;
    00050   };
    00051
    00052   template<typename _Tp>
    00053     struct __in_array
    00054     : public __sfinae_types
    00055     {
    00056     private:
    00057       template<typename _Up>
    00058         static __one __test(_Up(*)[1]);
    00059       template<typename>
    00060         static __two __test(...);
    00061
    00062     public:
    00063       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
    00064     };
    00065
    00066 #define _DEFINE_SPEC_BODY(_Value)                                    \
    00067     : public integral_constant<bool, _Value> { };
    00068
    00069 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
    00070   template<>                                                         \
    00071     struct _Spec                                                     \
    00072     _DEFINE_SPEC_BODY(_Value)
    00073
    00074 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value)                         \
    00075   template<typename _Tp>                                             \
    00076     struct _Spec                                                     \
    00077     _DEFINE_SPEC_BODY(_Value)
    00078
    00079 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value)                         \
    00080   template<typename _Tp, typename _Cp>                               \
    00081     struct _Spec                                                     \
    00082     _DEFINE_SPEC_BODY(_Value)
    00083
    00084 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)                  \
    00085   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value)              \
    00086   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value)        \
    00087   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value)     \
    00088   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
    00089
    00090   /// @brief  helper classes [4.3].
    00091   template<typename _Tp, _Tp __v>
    00092     struct integral_constant
    00093     {
    00094       static const _Tp                      value = __v;
    00095       typedef _Tp                           value_type;
    00096       typedef integral_constant<_Tp, __v>   type;
    00097     };
    00098   typedef integral_constant<bool, true>     true_type;
    00099   typedef integral_constant<bool, false>    false_type;
    00100
    00101   template<typename _Tp, _Tp __v>
    00102     const _Tp integral_constant<_Tp, __v>::value;
    00103
    00104   /// @brief  primary type categories [4.5.1].
    00105   template<typename>
    00106     struct is_void
    00107     : public false_type { };
    00108   _DEFINE_SPEC(0, is_void, void, true)
    00109
    00110   template<typename>
    00111     struct is_integral
    00112     : public false_type { };
    00113   _DEFINE_SPEC(0, is_integral, bool, true)
    00114   _DEFINE_SPEC(0, is_integral, char, true)
    00115   _DEFINE_SPEC(0, is_integral, signed char, true)
    00116   _DEFINE_SPEC(0, is_integral, unsigned char, true)
    00117 #ifdef _GLIBCXX_USE_WCHAR_T
    00118   _DEFINE_SPEC(0, is_integral, wchar_t, true)
    00119 #endif
    00120   _DEFINE_SPEC(0, is_integral, short, true)
    00121   _DEFINE_SPEC(0, is_integral, unsigned short, true)
    00122   _DEFINE_SPEC(0, is_integral, int, true)
    00123   _DEFINE_SPEC(0, is_integral, unsigned int, true)
    00124   _DEFINE_SPEC(0, is_integral, long, true)
    00125   _DEFINE_SPEC(0, is_integral, unsigned long, true)
    00126   _DEFINE_SPEC(0, is_integral, long long, true)
    00127   _DEFINE_SPEC(0, is_integral, unsigned long long, true)
    00128
    00129   template<typename>
    00130     struct is_floating_point
    00131     : public false_type { };
    00132   _DEFINE_SPEC(0, is_floating_point, float, true)
    00133   _DEFINE_SPEC(0, is_floating_point, double, true)
    00134   _DEFINE_SPEC(0, is_floating_point, long double, true)
    00135
    00136   template<typename>
    00137     struct is_array
    00138     : public false_type { };
    00139
    00140   template<typename _Tp, std::size_t _Size>
    00141     struct is_array<_Tp[_Size]>
    00142     : public true_type { };
    00143
    00144   template<typename _Tp>
    00145     struct is_array<_Tp[]>
    00146     : public true_type { };
    00147
    00148   template<typename>
    00149     struct is_pointer
    00150     : public false_type { };
    00151   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
    00152
    00153   template<typename>
    00154     struct is_reference
    00155     : public false_type { };
    00156
    00157   template<typename _Tp>
    00158     struct is_reference<_Tp&>
    00159     : public true_type { };
    00160
    00161   template<typename>
    00162     struct is_member_object_pointer
    00163     : public false_type { };
    00164   _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
    00165            !is_function<_Tp>::value)
    00166
    00167   template<typename>
    00168     struct is_member_function_pointer
    00169     : public false_type { };
    00170   _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
    00171            is_function<_Tp>::value)
    00172
    00173   template<typename _Tp>
    00174     struct is_enum
    00175     : public integral_constant<bool, !(is_fundamental<_Tp>::value
    00176                        || is_array<_Tp>::value
    00177                        || is_pointer<_Tp>::value
    00178                        || is_reference<_Tp>::value
    00179                        || is_member_pointer<_Tp>::value
    00180                        || is_function<_Tp>::value
    00181                        || __is_union_or_class<_Tp>::value)>
    00182     { };
    00183
    00184   template<typename>
    00185     struct is_union { };
    00186
    00187   template<typename>
    00188     struct is_class { };
    00189
    00190   template<typename _Tp>
    00191     struct is_function
    00192     : public integral_constant<bool, !(__in_array<_Tp>::__value
    00193                        || __is_union_or_class<_Tp>::value
    00194                        || is_reference<_Tp>::value
    00195                        || is_void<_Tp>::value)>
    00196     { };
    00197
    00198   /// @brief  composite type traits [4.5.2].
    00199   template<typename _Tp>
    00200     struct is_arithmetic
    00201     : public integral_constant<bool, (is_integral<_Tp>::value
    00202                       || is_floating_point<_Tp>::value)>
    00203     { };
    00204
    00205   template<typename _Tp>
    00206     struct is_fundamental
    00207     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    00208                       || is_void<_Tp>::value)>
    00209     { };
    00210
    00211   template<typename _Tp>
    00212     struct is_object
    00213     : public integral_constant<bool, !(is_function<_Tp>::value
    00214                        || is_reference<_Tp>::value
    00215                        || is_void<_Tp>::value)>
    00216     { };
    00217
    00218   template<typename _Tp>
    00219     struct is_scalar
    00220     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    00221                       || is_enum<_Tp>::value
    00222                       || is_pointer<_Tp>::value
    00223                       || is_member_pointer<_Tp>::value)>
    00224     { };
    00225
    00226   template<typename _Tp>
    00227     struct is_compound
    00228     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
    00229
    00230   template<typename _Tp>
    00231     struct is_member_pointer
    00232     : public integral_constant<bool,
    00233                    (is_member_object_pointer<_Tp>::value
    00234                 || is_member_function_pointer<_Tp>::value)>
    00235     { };
    00236
    00237   template<typename _Tp>
    00238     struct __is_union_or_class_helper
    00239     : public __sfinae_types
    00240     {
    00241     private:
    00242       template<typename _Up>
    00243         static __one __test(int _Up::*);
    00244       template<typename>
    00245         static __two __test(...);
    00246
    00247     public:
    00248       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
    00249     };
    00250
    00251   // Extension.
    00252   template<typename _Tp>
    00253     struct __is_union_or_class
    00254     : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value>
    00255     { };
    00256
    00257   /// @brief  type properties [4.5.3].
    00258   template<typename>
    00259     struct is_const
    00260     : public false_type { };
    00261
    00262   template<typename _Tp>
    00263     struct is_const<_Tp const>
    00264     : public true_type { };
    00265
    00266   template<typename>
    00267     struct is_volatile
    00268     : public false_type { };
    00269
    00270   template<typename _Tp>
    00271     struct is_volatile<_Tp volatile>
    00272     : public true_type { };
    00273
    00274   template<typename _Tp>
    00275     struct is_pod
    00276     : public integral_constant<bool, (is_void<_Tp>::value
    00277                       || is_scalar<typename
    00278                       remove_all_extents<_Tp>::type>::value)>
    00279     { };
    00280
    00281   // NB: Without compiler support we cannot tell union from class types,
    00282   // and is_empty and is_polymorphic don't work at all with the former.
    00283   template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
    00284     struct __is_empty_helper
    00285     {
    00286     private:
    00287       template<typename>
    00288         struct __first { };
    00289       template<typename _Up>
    00290         struct __second
    00291         : public _Up { };
    00292
    00293     public:
    00294       static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
    00295     };
    00296
    00297   template<typename _Tp>
    00298     struct __is_empty_helper<_Tp, true>
    00299     { static const bool __value = false; };
    00300
    00301   template<typename _Tp>
    00302     struct is_empty
    00303     : public integral_constant<bool, __is_empty_helper<_Tp>::__value>
    00304     { };
    00305
    00306   template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
    00307     struct __is_polymorphic_helper
    00308     {
    00309     private:
    00310       template<typename _Up>
    00311         struct __first
    00312         : public _Up { };
    00313       template<typename _Up>
    00314         struct __second
    00315         : public _Up
    00316     {
    00317       virtual void __dummy();
    00318       virtual ~__second() throw();
    00319     };
    00320
    00321     public:
    00322       static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
    00323     };
    00324
    00325   template<typename _Tp>
    00326     struct __is_polymorphic_helper<_Tp, true>
    00327     { static const bool __value = false; };
    00328
    00329   template<typename _Tp>
    00330     struct is_polymorphic
    00331     : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value>
    00332     { };
    00333
    00334   // Exploit the resolution DR core/337.
    00335   template<typename _Tp>
    00336     struct is_abstract
    00337     : public integral_constant<bool, (!__in_array<_Tp>::__value
    00338                       && __is_union_or_class<_Tp>::value)> { };
    00339
    00340   template<typename _Tp>
    00341     struct has_trivial_constructor
    00342     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00343
    00344   template<typename _Tp>
    00345     struct has_trivial_copy
    00346     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00347
    00348   template<typename _Tp>
    00349     struct has_trivial_assign
    00350     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00351
    00352   template<typename _Tp>
    00353     struct has_trivial_destructor
    00354     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00355
    00356   template<typename _Tp>
    00357     struct has_nothrow_constructor
    00358     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00359
    00360   template<typename _Tp>
    00361     struct has_nothrow_copy
    00362     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00363
    00364   template<typename _Tp>
    00365     struct has_nothrow_assign
    00366     : public integral_constant<bool, is_pod<_Tp>::value> { };
    00367
    00368   template<typename>
    00369     struct has_virtual_destructor
    00370     : public false_type { };
    00371
    00372   template<typename>
    00373     struct is_signed
    00374     : public false_type { };
    00375   _DEFINE_SPEC(0, is_signed, signed char, true)
    00376   _DEFINE_SPEC(0, is_signed, short, true)
    00377   _DEFINE_SPEC(0, is_signed, int, true)
    00378   _DEFINE_SPEC(0, is_signed, long, true)
    00379   _DEFINE_SPEC(0, is_signed, long long, true)
    00380
    00381   template<typename>
    00382     struct is_unsigned
    00383     : public false_type { };
    00384   _DEFINE_SPEC(0, is_unsigned, unsigned char, true)
    00385   _DEFINE_SPEC(0, is_unsigned, unsigned short, true)
    00386   _DEFINE_SPEC(0, is_unsigned, unsigned int, true)
    00387   _DEFINE_SPEC(0, is_unsigned, unsigned long, true)
    00388   _DEFINE_SPEC(0, is_unsigned, unsigned long long, true)
    00389
    00390   template<typename _Tp>
    00391     struct alignment_of
    00392     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
    00393
    00394   template<typename>
    00395     struct rank
    00396     : public integral_constant<std::size_t, 0> { };
    00397
    00398   template<typename _Tp, std::size_t _Size>
    00399     struct rank<_Tp[_Size]>
    00400     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    00401
    00402   template<typename _Tp>
    00403     struct rank<_Tp[]>
    00404     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    00405
    00406   template<typename, unsigned>
    00407     struct extent
    00408     : public integral_constant<std::size_t, 0> { };
    00409
    00410   template<typename _Tp, unsigned _Uint, std::size_t _Size>
    00411     struct extent<_Tp[_Size], _Uint>
    00412     : public integral_constant<std::size_t,
    00413                    _Uint == 0 ? _Size : extent<_Tp,
    00414                                _Uint - 1>::value>
    00415     { };
    00416
    00417   template<typename _Tp, unsigned _Uint>
    00418     struct extent<_Tp[], _Uint>
    00419     : public integral_constant<std::size_t,
    00420                    _Uint == 0 ? 0 : extent<_Tp,
    00421                                _Uint - 1>::value>
    00422     { };
    00423
    00424   /// @brief  relationships between types [4.6].
    00425   template<typename, typename>
    00426     struct is_same
    00427     : public false_type { };
    00428
    00429   template<typename _Tp>
    00430     struct is_same<_Tp, _Tp>
    00431     : public true_type { };
    00432
    00433   // See Daveed Vandevoorde explanation in http://tinyurl.com/502f.
    00434   // Also see Rani Sharoni in http://tinyurl.com/6jvyq.
    00435   template<typename _Base, typename _Derived,
    00436        bool = (!__is_union_or_class<_Base>::value
    00437            || !__is_union_or_class<_Derived>::value
    00438            || is_same<_Base, _Derived>::value)>
    00439     struct __is_base_of_helper
    00440     : public __sfinae_types
    00441     {
    00442     private:
    00443       typedef typename remove_cv<_Base>::type     _NoCv_Base;
    00444       typedef typename remove_cv<_Derived>::type  _NoCv_Derived;
    00445
    00446       template<typename _Up>
    00447         static __one __test(_NoCv_Derived&, _Up);
    00448       static __two __test(_NoCv_Base&, int);
    00449
    00450       struct _Conv
    00451       {
    00452     operator _NoCv_Derived&();
    00453     operator _NoCv_Base&() const;
    00454       };
    00455
    00456     public:
    00457       static const bool __value = sizeof(__test(_Conv(), 0)) == 1;
    00458     };
    00459
    00460   template<typename _Base, typename _Derived>
    00461     struct __is_base_of_helper<_Base, _Derived, true>
    00462     { static const bool __value = is_same<_Base, _Derived>::value; };
    00463
    00464   template<typename _Base, typename _Derived>
    00465     struct is_base_of
    00466     : public integral_constant<bool,
    00467                    __is_base_of_helper<_Base, _Derived>::__value>
    00468     { };
    00469
    00470   template<typename _From, typename _To>
    00471     struct __is_convertible_simple
    00472     : public __sfinae_types
    00473     {
    00474     private:
    00475       static __one __test(_To);
    00476       static __two __test(...);
    00477       static _From __makeFrom();
    00478
    00479     public:
    00480       static const bool __value = sizeof(__test(__makeFrom())) == 1;
    00481     };
    00482
    00483   template<typename _Tp>
    00484     struct __is_int_or_cref
    00485     {
    00486       typedef typename remove_reference<_Tp>::type __rr_Tp;
    00487       static const bool __value = (is_integral<_Tp>::value
    00488                    || (is_integral<__rr_Tp>::value
    00489                        && is_const<__rr_Tp>::value
    00490                        && !is_volatile<__rr_Tp>::value));
    00491     };
    00492
    00493   template<typename _From, typename _To,
    00494        bool = (is_void<_From>::value || is_void<_To>::value
    00495            || is_function<_To>::value || is_array<_To>::value
    00496            // This special case is here only to avoid warnings.
    00497            || (is_floating_point<typename
    00498                remove_reference<_From>::type>::value
    00499                && __is_int_or_cref<_To>::__value))>
    00500     struct __is_convertible_helper
    00501     {
    00502       // "An imaginary lvalue of type From...".
    00503       static const bool __value = (__is_convertible_simple<typename
    00504                    add_reference<_From>::type, _To>::__value);
    00505     };
    00506
    00507   template<typename _From, typename _To>
    00508     struct __is_convertible_helper<_From, _To, true>
    00509     { static const bool __value = (is_void<_To>::value
    00510                    || (__is_int_or_cref<_To>::__value
    00511                        && !is_void<_From>::value)); };
    00512
    00513   template<typename _From, typename _To>
    00514     struct is_convertible
    00515     : public integral_constant<bool,
    00516                    __is_convertible_helper<_From, _To>::__value>
    00517     { };
    00518
    00519   /// @brief  const-volatile modifications [4.7.1].
    00520   template<typename _Tp>
    00521     struct remove_const
    00522     { typedef _Tp     type; };
    00523
    00524   template<typename _Tp>
    00525     struct remove_const<_Tp const>
    00526     { typedef _Tp     type; };
    00527
    00528   template<typename _Tp>
    00529     struct remove_volatile
    00530     { typedef _Tp     type; };
    00531
    00532   template<typename _Tp>
    00533     struct remove_volatile<_Tp volatile>
    00534     { typedef _Tp     type; };
    00535
    00536   template<typename _Tp>
    00537     struct remove_cv
    00538     {
    00539       typedef typename
    00540       remove_const<typename remove_volatile<_Tp>::type>::type     type;
    00541     };
    00542
    00543   template<typename _Tp>
    00544     struct add_const
    00545     { typedef _Tp const     type; };
    00546
    00547   template<typename _Tp>
    00548     struct add_volatile
    00549     { typedef _Tp volatile     type; };
    00550
    00551   template<typename _Tp>
    00552     struct add_cv
    00553     {
    00554       typedef typename
    00555       add_const<typename add_volatile<_Tp>::type>::type     type;
    00556     };
    00557
    00558   /// @brief  reference modifications [4.7.2].
    00559   template<typename _Tp>
    00560     struct remove_reference
    00561     { typedef _Tp     type; };
    00562
    00563   template<typename _Tp>
    00564     struct remove_reference<_Tp&>
    00565     { typedef _Tp     type; };
    00566
    00567   // NB: Careful with reference to void.
    00568   template<typename _Tp, bool = (is_void<_Tp>::value
    00569                  || is_reference<_Tp>::value)>
    00570     struct __add_reference_helper
    00571     { typedef _Tp&    type; };
    00572
    00573   template<typename _Tp>
    00574     struct __add_reference_helper<_Tp, true>
    00575     { typedef _Tp     type; };
    00576
    00577   template<typename _Tp>
    00578     struct add_reference
    00579     : public __add_reference_helper<_Tp>
    00580     { };
    00581
    00582   /// @brief  array modifications [4.7.3].
    00583   template<typename _Tp>
    00584     struct remove_extent
    00585     { typedef _Tp     type; };
    00586
    00587   template<typename _Tp, std::size_t _Size>
    00588     struct remove_extent<_Tp[_Size]>
    00589     { typedef _Tp     type; };
    00590
    00591   template<typename _Tp>
    00592     struct remove_extent<_Tp[]>
    00593     { typedef _Tp     type; };
    00594
    00595   template<typename _Tp>
    00596     struct remove_all_extents
    00597     { typedef _Tp     type; };
    00598
    00599   template<typename _Tp, std::size_t _Size>
    00600     struct remove_all_extents<_Tp[_Size]>
    00601     { typedef typename remove_all_extents<_Tp>::type     type; };
    00602
    00603   template<typename _Tp>
    00604     struct remove_all_extents<_Tp[]>
    00605     { typedef typename remove_all_extents<_Tp>::type     type; };
    00606
    00607   /// @brief  pointer modifications [4.7.4].
    00608 #undef _DEFINE_SPEC_BODY
    00609 #define _DEFINE_SPEC_BODY(_Value)      \
    00610     { typedef _Tp     type; };
    00611
    00612   template<typename _Tp>
    00613     struct remove_pointer
    00614     { typedef _Tp     type; };
    00615   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
    00616
    00617   template<typename _Tp>
    00618     struct add_pointer
    00619     { typedef typename remove_reference<_Tp>::type*     type; };
    00620
    00621   /// @brief  other transformations [4.8].
    00622
    00623   // Due to c++/19163 and c++/17743, for the time being we cannot use
    00624   // the correct, neat implementation :-(
    00625   //
    00626   // template<std::size_t _Len, std::size_t _Align>
    00627   //   struct aligned_storage
    00628   //   { typedef char type[_Len] __attribute__((__aligned__(_Align))); }
    00629   //
    00630   // Temporary workaround, useful for Align up to 32:
    00631   template<std::size_t, std::size_t>
    00632     struct aligned_storage { };
    00633
    00634   template<std::size_t _Len>
    00635     struct aligned_storage<_Len, 1>
    00636     {
    00637       union type
    00638       {
    00639     unsigned char __data[_Len];
    00640     char __align __attribute__((__aligned__(1)));
    00641       };
    00642     };
    00643
    00644   template<std::size_t _Len>
    00645     struct aligned_storage<_Len, 2>
    00646     {
    00647       union type
    00648       {
    00649     unsigned char __data[_Len];
    00650     char __align __attribute__((__aligned__(2)));
    00651       };
    00652     };
    00653
    00654   template<std::size_t _Len>
    00655     struct aligned_storage<_Len, 4>
    00656     {
    00657       union type
    00658       {
    00659     unsigned char __data[_Len];
    00660     char __align __attribute__((__aligned__(4)));
    00661       };
    00662     };
    00663
    00664   template<std::size_t _Len>
    00665     struct aligned_storage<_Len, 8>
    00666     {
    00667       union type
    00668       {
    00669     unsigned char __data[_Len];
    00670     char __align __attribute__((__aligned__(8)));
    00671       };
    00672     };
    00673
    00674   template<std::size_t _Len>
    00675     struct aligned_storage<_Len, 16>
    00676     {
    00677       union type
    00678       {
    00679     unsigned char __data[_Len];
    00680     char __align __attribute__((__aligned__(16)));
    00681       };
    00682     };
    00683
    00684   template<std::size_t _Len>
    00685     struct aligned_storage<_Len, 32>
    00686     {
    00687       union type
    00688       {
    00689     unsigned char __data[_Len];
    00690     char __align __attribute__((__aligned__(32)));
    00691       };
    00692     };
    00693
    00694 #undef _DEFINE_SPEC_0_HELPER
    00695 #undef _DEFINE_SPEC_1_HELPER
    00696 #undef _DEFINE_SPEC_2_HELPER
    00697 #undef _DEFINE_SPEC
    00698 #undef _DEFINE_SPEC_BODY
    00699
    00700 _GLIBCXX_END_NAMESPACE
    00701 }
    00702
    00703 #endif