type_traits

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

Generated on Sat Oct 1 15:08:55 2005 for libstdc++ source by  doxygen 1.4.4