type_traits

Go to the documentation of this file.
00001 // C++0x type_traits -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/type_traits
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_TYPE_TRAITS
00030 #define _GLIBCXX_TYPE_TRAITS 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
00039 #  error C++0x header cannot be included from TR1 header
00040 #endif
00041 
00042 #include <bits/c++config.h>
00043 
00044 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
00045 #  include <tr1_impl/type_traits>
00046 #else
00047 #  define _GLIBCXX_INCLUDE_AS_CXX0X
00048 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1
00049 #  define _GLIBCXX_END_NAMESPACE_TR1
00050 #  define _GLIBCXX_TR1
00051 #  include <tr1_impl/type_traits>
00052 #  undef _GLIBCXX_TR1
00053 #  undef _GLIBCXX_END_NAMESPACE_TR1
00054 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
00055 #  undef _GLIBCXX_INCLUDE_AS_CXX0X
00056 #endif
00057 
00058 namespace std
00059 {
00060   /**
00061    * @addtogroup metaprogramming
00062    * @{
00063    */
00064 
00065   // Primary classification traits.
00066 
00067   /// is_lvalue_reference
00068   template<typename>
00069     struct is_lvalue_reference
00070     : public false_type { };
00071 
00072   template<typename _Tp>
00073     struct is_lvalue_reference<_Tp&>
00074     : public true_type { };
00075 
00076   /// is_rvalue_reference
00077   template<typename>
00078     struct is_rvalue_reference
00079     : public false_type { };
00080 
00081   template<typename _Tp>
00082     struct is_rvalue_reference<_Tp&&>
00083     : public true_type { };
00084 
00085   // Secondary classification traits.
00086 
00087   /// is_reference
00088   template<typename _Tp>
00089     struct is_reference
00090     : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
00091                       || is_rvalue_reference<_Tp>::value)>
00092     { };
00093 
00094   // Reference transformations.
00095 
00096   /// remove_reference
00097   template<typename _Tp>
00098     struct remove_reference
00099     { typedef _Tp   type; };
00100 
00101   template<typename _Tp>
00102     struct remove_reference<_Tp&>
00103     { typedef _Tp   type; };
00104 
00105   template<typename _Tp>
00106     struct remove_reference<_Tp&&>
00107     { typedef _Tp   type; };
00108 
00109   template<typename _Tp,
00110        bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
00111        bool = is_rvalue_reference<_Tp>::value>
00112     struct __add_lvalue_reference_helper
00113     { typedef _Tp   type; };
00114 
00115   template<typename _Tp>
00116     struct __add_lvalue_reference_helper<_Tp, true, false>
00117     { typedef _Tp&   type; };
00118 
00119   template<typename _Tp>
00120     struct __add_lvalue_reference_helper<_Tp, false, true>
00121     { typedef typename remove_reference<_Tp>::type&   type; };
00122 
00123   /// add_lvalue_reference
00124   template<typename _Tp>
00125     struct add_lvalue_reference
00126     : public __add_lvalue_reference_helper<_Tp>
00127     { };
00128 
00129   template<typename _Tp,
00130        bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
00131     struct __add_rvalue_reference_helper
00132     { typedef _Tp   type; };
00133 
00134   template<typename _Tp>
00135     struct __add_rvalue_reference_helper<_Tp, true>
00136     { typedef _Tp&&   type; };
00137 
00138   /// add_rvalue_reference
00139   template<typename _Tp>
00140     struct add_rvalue_reference
00141     : public __add_rvalue_reference_helper<_Tp>
00142     { };
00143 
00144   // Scalar properties and transformations.
00145 
00146   template<typename _Tp,
00147        bool = is_integral<_Tp>::value,
00148        bool = is_floating_point<_Tp>::value>
00149     struct __is_signed_helper
00150     : public false_type { };
00151 
00152   template<typename _Tp>
00153     struct __is_signed_helper<_Tp, false, true>
00154     : public true_type { };
00155 
00156   template<typename _Tp>
00157     struct __is_signed_helper<_Tp, true, false>
00158     : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
00159     { };
00160 
00161   /// is_signed
00162   template<typename _Tp>
00163     struct is_signed
00164     : public integral_constant<bool, __is_signed_helper<_Tp>::value>
00165     { };
00166 
00167   /// is_unsigned
00168   template<typename _Tp>
00169     struct is_unsigned
00170     : public integral_constant<bool, (is_arithmetic<_Tp>::value
00171                       && !is_signed<_Tp>::value)>
00172     { };
00173 
00174   // Member introspection.
00175 
00176   /// is_trivial
00177   template<typename _Tp>
00178     struct is_trivial
00179     : public integral_constant<bool, __is_trivial(_Tp)>
00180     { };
00181 
00182   /// is_standard_layout
00183   template<typename _Tp>
00184     struct is_standard_layout
00185     : public integral_constant<bool, __is_standard_layout(_Tp)>
00186     { };
00187 
00188   /// is_pod
00189   // Could use is_standard_layout && is_trivial instead of the builtin.
00190   template<typename _Tp>
00191     struct is_pod
00192     : public integral_constant<bool, __is_pod(_Tp)>
00193     { };
00194 
00195   template<typename _Tp>
00196     typename add_rvalue_reference<_Tp>::type declval() noexcept;
00197 
00198   template<typename _Tp, typename... _Args>
00199     class __is_constructible_helper
00200     : public __sfinae_types
00201     {
00202       template<typename _Tp1, typename... _Args1>
00203         static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
00204 
00205       template<typename, typename...>
00206         static __two __test(...);
00207 
00208     public:
00209       static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
00210     };
00211 
00212   template<typename _Tp, typename _Arg>
00213     class __is_constructible_helper<_Tp, _Arg>
00214     : public __sfinae_types
00215     {
00216       template<typename _Tp1, typename _Arg1>
00217         static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
00218     __test(int);
00219 
00220       template<typename, typename>
00221         static __two __test(...);
00222 
00223     public:
00224       static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
00225     };
00226 
00227   /// is_constructible
00228   // XXX FIXME
00229   // The C++0x specifications require front-end support, see N2255.
00230   template<typename _Tp, typename... _Args>
00231     struct is_constructible
00232     : public integral_constant<bool,
00233                    __is_constructible_helper<_Tp,
00234                              _Args...>::__value>
00235     { };
00236 
00237   template<bool, typename _Tp, typename... _Args>
00238     struct __is_nt_constructible_helper
00239     { static const bool __value = false; };
00240 
00241   template<typename _Tp, typename... _Args>
00242     struct __is_nt_constructible_helper<true, _Tp, _Args...>
00243     { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
00244 
00245   template<typename _Tp, typename _Arg>
00246     struct __is_nt_constructible_helper<true, _Tp, _Arg>
00247     {
00248       static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
00249     };
00250 
00251   /// is_nothrow_constructible
00252   template<typename _Tp, typename... _Args>
00253     struct is_nothrow_constructible
00254     : public integral_constant<bool,
00255       __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
00256                        _Tp, _Args...>::__value>
00257     { };
00258 
00259   /// has_trivial_default_constructor
00260   template<typename _Tp>
00261     struct has_trivial_default_constructor
00262     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
00263     { };
00264 
00265   /// has_trivial_copy_constructor
00266   template<typename _Tp>
00267     struct has_trivial_copy_constructor
00268     : public integral_constant<bool, __has_trivial_copy(_Tp)>
00269     { };
00270 
00271   /// has_trivial_copy_assign
00272   template<typename _Tp>
00273     struct has_trivial_copy_assign
00274     : public integral_constant<bool, __has_trivial_assign(_Tp)>
00275     { };
00276 
00277   /// has_trivial_destructor
00278   template<typename _Tp>
00279     struct has_trivial_destructor
00280     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
00281     { };
00282 
00283   /// has_nothrow_default_constructor
00284   template<typename _Tp>
00285     struct has_nothrow_default_constructor
00286     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
00287     { };
00288 
00289   /// has_nothrow_copy_constructor
00290   template<typename _Tp>
00291     struct has_nothrow_copy_constructor
00292     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
00293     { };
00294 
00295   /// has_nothrow_copy_assign
00296   template<typename _Tp>
00297     struct has_nothrow_copy_assign
00298     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
00299     { };
00300 
00301   // Relationships between types.
00302 
00303   /// is_base_of
00304   template<typename _Base, typename _Derived>
00305     struct is_base_of
00306     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
00307     { };
00308 
00309   template<typename _From, typename _To,
00310        bool = (is_void<_From>::value || is_function<_To>::value
00311            || is_array<_To>::value)>
00312     struct __is_convertible_helper
00313     { static const bool __value = is_void<_To>::value; };
00314 
00315   template<typename _From, typename _To>
00316     class __is_convertible_helper<_From, _To, false>
00317     : public __sfinae_types
00318     {
00319       template<typename _To1>
00320         static void __test_aux(_To1);
00321 
00322       template<typename _From1, typename _To1>
00323         static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
00324     __test(int);
00325 
00326       template<typename, typename>
00327         static __two __test(...);
00328 
00329     public:
00330       static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
00331     };
00332 
00333   /// is_convertible
00334   // XXX FIXME
00335   // The C++0x specifications require front-end support, see N2255.
00336   template<typename _From, typename _To>
00337     struct is_convertible
00338     : public integral_constant<bool,
00339                    __is_convertible_helper<_From, _To>::__value>
00340     { };
00341 
00342   /// is_explicitly_convertible
00343   template<typename _From, typename _To>
00344     struct is_explicitly_convertible
00345     : public is_constructible<_To, _From>
00346     { };
00347 
00348   template<std::size_t _Len>
00349     struct __aligned_storage_msa
00350     { 
00351       union __type
00352       {
00353     unsigned char __data[_Len];
00354     struct __attribute__((__aligned__)) { } __align; 
00355       };
00356     };
00357 
00358   /**
00359    *  @brief Alignment type.
00360    *
00361    *  The value of _Align is a default-alignment which shall be the
00362    *  most stringent alignment requirement for any C++ object type
00363    *  whose size is no greater than _Len (3.9). The member typedef
00364    *  type shall be a POD type suitable for use as uninitialized
00365    *  storage for any object whose size is at most _Len and whose
00366    *  alignment is a divisor of _Align.
00367   */
00368   template<std::size_t _Len, std::size_t _Align =
00369        __alignof__(typename __aligned_storage_msa<_Len>::__type)>
00370     struct aligned_storage
00371     { 
00372       union type
00373       {
00374     unsigned char __data[_Len];
00375     struct __attribute__((__aligned__((_Align)))) { } __align; 
00376       };
00377     };
00378 
00379 
00380   // Define a nested type if some predicate holds.
00381   // Primary template.
00382   /// enable_if
00383   template<bool, typename _Tp = void>
00384     struct enable_if 
00385     { };
00386 
00387   // Partial specialization for true.
00388   template<typename _Tp>
00389     struct enable_if<true, _Tp>
00390     { typedef _Tp type; };
00391 
00392 
00393   // A conditional expression, but for types. If true, first, if false, second.
00394   // Primary template.
00395   /// conditional
00396   template<bool _Cond, typename _Iftrue, typename _Iffalse>
00397     struct conditional
00398     { typedef _Iftrue type; };
00399 
00400   // Partial specialization for false.
00401   template<typename _Iftrue, typename _Iffalse>
00402     struct conditional<false, _Iftrue, _Iffalse>
00403     { typedef _Iffalse type; };
00404 
00405 
00406   // Decay trait for arrays and functions, used for perfect forwarding
00407   // in make_pair, make_tuple, etc.
00408   template<typename _Up, 
00409        bool _IsArray = is_array<_Up>::value,
00410        bool _IsFunction = is_function<_Up>::value> 
00411     struct __decay_selector;
00412 
00413   // NB: DR 705.
00414   template<typename _Up> 
00415     struct __decay_selector<_Up, false, false>
00416     { typedef typename remove_cv<_Up>::type __type; };
00417 
00418   template<typename _Up> 
00419     struct __decay_selector<_Up, true, false>
00420     { typedef typename remove_extent<_Up>::type* __type; };
00421 
00422   template<typename _Up> 
00423     struct __decay_selector<_Up, false, true>
00424     { typedef typename add_pointer<_Up>::type __type; };
00425 
00426   /// decay
00427   template<typename _Tp> 
00428     class decay 
00429     { 
00430       typedef typename remove_reference<_Tp>::type __remove_type;
00431 
00432     public:
00433       typedef typename __decay_selector<__remove_type>::__type type;
00434     };
00435 
00436   template<typename _Tp>
00437     class reference_wrapper;
00438 
00439   // Helper which adds a reference to a type when given a reference_wrapper
00440   template<typename _Tp>
00441     struct __strip_reference_wrapper
00442     {
00443       typedef _Tp __type;
00444     };
00445 
00446   template<typename _Tp>
00447     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
00448     {
00449       typedef _Tp& __type;
00450     };
00451 
00452   template<typename _Tp>
00453     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
00454     {
00455       typedef _Tp& __type;
00456     };
00457 
00458   template<typename _Tp>
00459     struct __decay_and_strip
00460     {
00461       typedef typename __strip_reference_wrapper<
00462     typename decay<_Tp>::type>::__type __type;
00463     };
00464 
00465 
00466   // Utility for constructing identically cv-qualified types.
00467   template<typename _Unqualified, bool _IsConst, bool _IsVol>
00468     struct __cv_selector;
00469 
00470   template<typename _Unqualified>
00471     struct __cv_selector<_Unqualified, false, false>
00472     { typedef _Unqualified __type; };
00473 
00474   template<typename _Unqualified>
00475     struct __cv_selector<_Unqualified, false, true>
00476     { typedef volatile _Unqualified __type; };
00477 
00478   template<typename _Unqualified>
00479     struct __cv_selector<_Unqualified, true, false>
00480     { typedef const _Unqualified __type; };
00481 
00482   template<typename _Unqualified>
00483     struct __cv_selector<_Unqualified, true, true>
00484     { typedef const volatile _Unqualified __type; };
00485 
00486   template<typename _Qualified, typename _Unqualified,
00487        bool _IsConst = is_const<_Qualified>::value,
00488        bool _IsVol = is_volatile<_Qualified>::value>
00489     class __match_cv_qualifiers
00490     {
00491       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
00492 
00493     public:
00494       typedef typename __match::__type __type; 
00495     };
00496 
00497 
00498   // Utility for finding the unsigned versions of signed integral types.
00499   template<typename _Tp>
00500     struct __make_unsigned
00501     { typedef _Tp __type; };
00502 
00503   template<>
00504     struct __make_unsigned<char>
00505     { typedef unsigned char __type; };
00506 
00507   template<>
00508     struct __make_unsigned<signed char>
00509     { typedef unsigned char __type; };
00510 
00511   template<>
00512     struct __make_unsigned<short>
00513     { typedef unsigned short __type; };
00514 
00515   template<>
00516     struct __make_unsigned<int>
00517     { typedef unsigned int __type; };
00518 
00519   template<>
00520     struct __make_unsigned<long>
00521     { typedef unsigned long __type; };
00522 
00523   template<>
00524     struct __make_unsigned<long long>
00525     { typedef unsigned long long __type; };
00526 
00527 
00528   // Select between integral and enum: not possible to be both.
00529   template<typename _Tp, 
00530        bool _IsInt = is_integral<_Tp>::value,
00531        bool _IsEnum = is_enum<_Tp>::value>
00532     class __make_unsigned_selector;
00533 
00534   template<typename _Tp>
00535     class __make_unsigned_selector<_Tp, true, false>
00536     {
00537       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
00538       typedef typename __unsignedt::__type __unsigned_type;
00539       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
00540 
00541     public:
00542       typedef typename __cv_unsigned::__type __type;
00543     };
00544 
00545   template<typename _Tp>
00546     class __make_unsigned_selector<_Tp, false, true>
00547     {
00548       // With -fshort-enums, an enum may be as small as a char.
00549       typedef unsigned char __smallest;
00550       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
00551       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
00552       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
00553       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
00554       typedef typename __cond2::type __cond2_type;
00555       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
00556       typedef typename __cond1::type __cond1_type;
00557 
00558     public:
00559       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
00560     };
00561 
00562   // Given an integral/enum type, return the corresponding unsigned
00563   // integer type.
00564   // Primary template.
00565   /// make_unsigned
00566   template<typename _Tp>
00567     struct make_unsigned 
00568     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
00569 
00570   // Integral, but don't define.
00571   template<>
00572     struct make_unsigned<bool>;
00573 
00574 
00575   // Utility for finding the signed versions of unsigned integral types.
00576   template<typename _Tp>
00577     struct __make_signed
00578     { typedef _Tp __type; };
00579 
00580   template<>
00581     struct __make_signed<char>
00582     { typedef signed char __type; };
00583 
00584   template<>
00585     struct __make_signed<unsigned char>
00586     { typedef signed char __type; };
00587 
00588   template<>
00589     struct __make_signed<unsigned short>
00590     { typedef signed short __type; };
00591 
00592   template<>
00593     struct __make_signed<unsigned int>
00594     { typedef signed int __type; };
00595 
00596   template<>
00597     struct __make_signed<unsigned long>
00598     { typedef signed long __type; };
00599 
00600   template<>
00601     struct __make_signed<unsigned long long>
00602     { typedef signed long long __type; };
00603 
00604 
00605   // Select between integral and enum: not possible to be both.
00606   template<typename _Tp, 
00607        bool _IsInt = is_integral<_Tp>::value,
00608        bool _IsEnum = is_enum<_Tp>::value>
00609     class __make_signed_selector;
00610 
00611   template<typename _Tp>
00612     class __make_signed_selector<_Tp, true, false>
00613     {
00614       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
00615       typedef typename __signedt::__type __signed_type;
00616       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
00617 
00618     public:
00619       typedef typename __cv_signed::__type __type;
00620     };
00621 
00622   template<typename _Tp>
00623     class __make_signed_selector<_Tp, false, true>
00624     {
00625       // With -fshort-enums, an enum may be as small as a char.
00626       typedef signed char __smallest;
00627       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
00628       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
00629       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
00630       typedef conditional<__b2, signed int, signed long> __cond2;
00631       typedef typename __cond2::type __cond2_type;
00632       typedef conditional<__b1, signed short, __cond2_type> __cond1;
00633       typedef typename __cond1::type __cond1_type;
00634 
00635     public:
00636       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
00637     };
00638 
00639   // Given an integral/enum type, return the corresponding signed
00640   // integer type.
00641   // Primary template.
00642   /// make_signed
00643   template<typename _Tp>
00644     struct make_signed 
00645     { typedef typename __make_signed_selector<_Tp>::__type type; };
00646 
00647   // Integral, but don't define.
00648   template<>
00649     struct make_signed<bool>;
00650 
00651   /// common_type
00652   template<typename... _Tp>
00653     struct common_type;
00654 
00655   template<typename _Tp>
00656     struct common_type<_Tp>
00657     { typedef _Tp type; };
00658 
00659   template<typename _Tp, typename _Up>
00660     struct common_type<_Tp, _Up>
00661     { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
00662 
00663   template<typename _Tp, typename _Up, typename... _Vp>
00664     struct common_type<_Tp, _Up, _Vp...>
00665     {
00666       typedef typename
00667         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
00668     };
00669 
00670   /// declval
00671   template<typename _Tp>
00672     struct __declval_protector
00673     {
00674       static const bool __stop = false;
00675       static typename add_rvalue_reference<_Tp>::type __delegate();
00676     };
00677 
00678   template<typename _Tp>
00679     inline typename add_rvalue_reference<_Tp>::type
00680     declval() noexcept
00681     {
00682       static_assert(__declval_protector<_Tp>::__stop,
00683             "declval() must not be used!");
00684       return __declval_protector<_Tp>::__delegate();
00685     }
00686 
00687   /// result_of
00688   template<typename _Signature>
00689     class result_of;
00690 
00691   template<typename _Functor, typename... _ArgTypes>
00692     struct result_of<_Functor(_ArgTypes...)>
00693     {
00694       typedef
00695         decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
00696         type;
00697     };
00698 
00699   /**
00700    *  Use SFINAE to determine if the type _Tp has a publicly-accessible
00701    *  member type _NTYPE.
00702    */
00703 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE)                         \
00704   template<typename _Tp>                                         \
00705     class __has_##_NTYPE##_helper                                \
00706     : __sfinae_types                                             \
00707     {                                                            \
00708       template<typename _Up>                                     \
00709         struct _Wrap_type                                        \
00710     { };                                                     \
00711                                                                  \
00712       template<typename _Up>                                     \
00713         static __one __test(_Wrap_type<typename _Up::_NTYPE>*);  \
00714                                                                  \
00715       template<typename _Up>                                     \
00716         static __two __test(...);                                \
00717                                                                  \
00718     public:                                                      \
00719       static const bool value = sizeof(__test<_Tp>(0)) == 1;     \
00720     };                                                           \
00721                                                                  \
00722   template<typename _Tp>                                         \
00723     struct __has_##_NTYPE                                        \
00724     : integral_constant<bool, __has_##_NTYPE##_helper            \
00725             <typename remove_cv<_Tp>::type>::value>  \
00726     { };
00727 
00728   // @} group metaprogramming
00729 }
00730 
00731 #endif  // __GXX_EXPERIMENTAL_CXX0X__
00732 
00733 #endif  // _GLIBCXX_TYPE_TRAITS