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

Generated on Thu Nov 1 13:12:47 2007 for libstdc++ by  doxygen 1.5.1