libstdc++
alloc_traits.h
Go to the documentation of this file.
00001 // Allocator traits -*- C++ -*-
00002 
00003 // Copyright (C) 2011-2015 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 bits/alloc_traits.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{memory}
00028  */
00029 
00030 #ifndef _ALLOC_TRAITS_H
00031 #define _ALLOC_TRAITS_H 1
00032 
00033 #if __cplusplus >= 201103L
00034 
00035 #include <bits/memoryfwd.h>
00036 #include <bits/ptr_traits.h>
00037 #include <ext/numeric_traits.h>
00038 
00039 namespace std _GLIBCXX_VISIBILITY(default)
00040 {
00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00042 
00043   template<typename _Alloc, typename _Tp>
00044     class __alloctr_rebind_helper
00045     {
00046       template<typename _Alloc2, typename _Tp2>
00047         static constexpr true_type
00048         _S_chk(typename _Alloc2::template rebind<_Tp2>::other*);
00049 
00050       template<typename, typename>
00051         static constexpr false_type
00052         _S_chk(...);
00053 
00054     public:
00055       using __type = decltype(_S_chk<_Alloc, _Tp>(nullptr));
00056     };
00057 
00058   template<typename _Alloc, typename _Tp,
00059            bool = __alloctr_rebind_helper<_Alloc, _Tp>::__type::value>
00060     struct __alloctr_rebind;
00061 
00062   template<typename _Alloc, typename _Tp>
00063     struct __alloctr_rebind<_Alloc, _Tp, true>
00064     {
00065       typedef typename _Alloc::template rebind<_Tp>::other __type;
00066     };
00067 
00068   template<template<typename, typename...> class _Alloc, typename _Tp,
00069            typename _Up, typename... _Args>
00070     struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false>
00071     {
00072       typedef _Alloc<_Tp, _Args...> __type;
00073     };
00074 
00075   template<typename _Alloc, typename _Tp>
00076     using __alloc_rebind = typename __alloctr_rebind<_Alloc, _Tp>::__type;
00077 
00078   /**
00079    * @brief  Uniform interface to all allocator types.
00080    * @ingroup allocators
00081   */
00082   template<typename _Alloc>
00083     struct allocator_traits
00084     {
00085       /// The allocator type
00086       typedef _Alloc allocator_type;
00087       /// The allocated type
00088       typedef typename _Alloc::value_type value_type;
00089 
00090 #define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \
00091   private: \
00092   template<typename _Tp> \
00093     static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \
00094   static _ALT _S_##_NTYPE##_helper(...); \
00095     typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \
00096   public:
00097 
00098 _GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*)
00099 
00100       /**
00101        * @brief   The allocator's pointer type.
00102        *
00103        * @c Alloc::pointer if that type exists, otherwise @c value_type*
00104       */
00105       typedef __pointer pointer;
00106 
00107 _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer,
00108   typename pointer_traits<pointer>::template rebind<const value_type>)
00109 
00110       /**
00111        * @brief   The allocator's const pointer type.
00112        *
00113        * @c Alloc::const_pointer if that type exists, otherwise
00114        * <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
00115       */
00116       typedef __const_pointer const_pointer;
00117 
00118 _GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer,
00119   typename pointer_traits<pointer>::template rebind<void>)
00120 
00121       /**
00122        * @brief   The allocator's void pointer type.
00123        *
00124        * @c Alloc::void_pointer if that type exists, otherwise
00125        * <tt> pointer_traits<pointer>::rebind<void> </tt>
00126       */
00127       typedef __void_pointer void_pointer;
00128 
00129 _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer,
00130   typename pointer_traits<pointer>::template rebind<const void>)
00131 
00132       /**
00133        * @brief   The allocator's const void pointer type.
00134        *
00135        * @c Alloc::const_void_pointer if that type exists, otherwise
00136        * <tt> pointer_traits<pointer>::rebind<const void> </tt>
00137       */
00138       typedef __const_void_pointer const_void_pointer;
00139 
00140 _GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
00141                               typename pointer_traits<pointer>::difference_type)
00142 
00143       /**
00144        * @brief   The allocator's difference type
00145        *
00146        * @c Alloc::difference_type if that type exists, otherwise
00147        * <tt> pointer_traits<pointer>::difference_type </tt>
00148       */
00149       typedef __difference_type difference_type;
00150 
00151 _GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
00152                               typename make_unsigned<difference_type>::type)
00153 
00154       /**
00155        * @brief   The allocator's size type
00156        *
00157        * @c Alloc::size_type if that type exists, otherwise
00158        * <tt> make_unsigned<difference_type>::type </tt>
00159       */
00160       typedef __size_type size_type;
00161 
00162 _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
00163                               false_type)
00164 
00165       /**
00166        * @brief   How the allocator is propagated on copy assignment
00167        *
00168        * @c Alloc::propagate_on_container_copy_assignment if that type exists,
00169        * otherwise @c false_type
00170       */
00171       typedef __propagate_on_container_copy_assignment
00172         propagate_on_container_copy_assignment;
00173 
00174 _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
00175                               false_type)
00176 
00177       /**
00178        * @brief   How the allocator is propagated on move assignment
00179        *
00180        * @c Alloc::propagate_on_container_move_assignment if that type exists,
00181        * otherwise @c false_type
00182       */
00183       typedef __propagate_on_container_move_assignment
00184         propagate_on_container_move_assignment;
00185 
00186 _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
00187                               false_type)
00188 
00189       /**
00190        * @brief   How the allocator is propagated on swap
00191        *
00192        * @c Alloc::propagate_on_container_swap if that type exists,
00193        * otherwise @c false_type
00194       */
00195       typedef __propagate_on_container_swap propagate_on_container_swap;
00196 
00197 #undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
00198 
00199       template<typename _Tp>
00200         using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;
00201       template<typename _Tp>
00202         using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
00203 
00204     private:
00205       template<typename _Alloc2>
00206         struct __allocate_helper
00207         {
00208           template<typename _Alloc3,
00209             typename = decltype(std::declval<_Alloc3*>()->allocate(
00210                   std::declval<size_type>(),
00211                   std::declval<const_void_pointer>()))>
00212             static true_type __test(int);
00213 
00214           template<typename>
00215             static false_type __test(...);
00216 
00217           using type = decltype(__test<_Alloc>(0));
00218         };
00219 
00220       template<typename _Alloc2>
00221         using __has_allocate = typename __allocate_helper<_Alloc2>::type;
00222 
00223       template<typename _Alloc2,
00224                typename = _Require<__has_allocate<_Alloc2>>>
00225         static pointer
00226         _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
00227         { return __a.allocate(__n, __hint); }
00228 
00229       template<typename _Alloc2, typename _UnusedHint,
00230                typename = _Require<__not_<__has_allocate<_Alloc2>>>>
00231         static pointer
00232         _S_allocate(_Alloc2& __a, size_type __n, _UnusedHint)
00233         { return __a.allocate(__n); }
00234 
00235       template<typename _Tp, typename... _Args>
00236         struct __construct_helper
00237         {
00238           template<typename _Alloc2,
00239             typename = decltype(std::declval<_Alloc2*>()->construct(
00240                   std::declval<_Tp*>(), std::declval<_Args>()...))>
00241             static true_type __test(int);
00242 
00243           template<typename>
00244             static false_type __test(...);
00245 
00246           using type = decltype(__test<_Alloc>(0));
00247         };
00248 
00249       template<typename _Tp, typename... _Args>
00250         using __has_construct
00251           = typename __construct_helper<_Tp, _Args...>::type;
00252 
00253       template<typename _Tp, typename... _Args>
00254         static _Require<__has_construct<_Tp, _Args...>>
00255         _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
00256         { __a.construct(__p, std::forward<_Args>(__args)...); }
00257 
00258       template<typename _Tp, typename... _Args>
00259         static
00260         _Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
00261                                is_constructible<_Tp, _Args...>>>
00262         _S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
00263         { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
00264 
00265       template<typename _Tp>
00266         struct __destroy_helper
00267         {
00268           template<typename _Alloc2,
00269             typename = decltype(std::declval<_Alloc2*>()->destroy(
00270                   std::declval<_Tp*>()))>
00271             static true_type __test(int);
00272 
00273           template<typename>
00274             static false_type __test(...);
00275 
00276           using type = decltype(__test<_Alloc>(0));
00277         };
00278 
00279       template<typename _Tp>
00280         using __has_destroy = typename __destroy_helper<_Tp>::type;
00281 
00282       template<typename _Tp>
00283         static _Require<__has_destroy<_Tp>>
00284         _S_destroy(_Alloc& __a, _Tp* __p)
00285         { __a.destroy(__p); }
00286 
00287       template<typename _Tp>
00288         static _Require<__not_<__has_destroy<_Tp>>>
00289         _S_destroy(_Alloc&, _Tp* __p)
00290         { __p->~_Tp(); }
00291 
00292       template<typename _Alloc2>
00293         struct __maxsize_helper
00294         {
00295           template<typename _Alloc3,
00296             typename = decltype(std::declval<_Alloc3*>()->max_size())>
00297             static true_type __test(int);
00298 
00299           template<typename>
00300             static false_type __test(...);
00301 
00302           using type = decltype(__test<_Alloc2>(0));
00303         };
00304 
00305       template<typename _Alloc2>
00306         using __has_max_size = typename __maxsize_helper<_Alloc2>::type;
00307 
00308       template<typename _Alloc2,
00309                typename = _Require<__has_max_size<_Alloc2>>>
00310         static size_type
00311         _S_max_size(_Alloc2& __a, int)
00312         { return __a.max_size(); }
00313 
00314       template<typename _Alloc2,
00315                typename = _Require<__not_<__has_max_size<_Alloc2>>>>
00316         static size_type
00317         _S_max_size(_Alloc2&, ...)
00318         { return __gnu_cxx::__numeric_traits<size_type>::__max; }
00319 
00320       template<typename _Alloc2>
00321         struct __select_helper
00322         {
00323           template<typename _Alloc3, typename
00324             = decltype(std::declval<_Alloc3*>()
00325                 ->select_on_container_copy_construction())>
00326             static true_type __test(int);
00327 
00328           template<typename>
00329             static false_type __test(...);
00330 
00331           using type = decltype(__test<_Alloc2>(0));
00332         };
00333 
00334       template<typename _Alloc2>
00335         using __has_soccc = typename __select_helper<_Alloc2>::type;
00336 
00337       template<typename _Alloc2,
00338                typename = _Require<__has_soccc<_Alloc2>>>
00339         static _Alloc2
00340         _S_select(_Alloc2& __a, int)
00341         { return __a.select_on_container_copy_construction(); }
00342 
00343       template<typename _Alloc2,
00344                typename = _Require<__not_<__has_soccc<_Alloc2>>>>
00345         static _Alloc2
00346         _S_select(_Alloc2& __a, ...)
00347         { return __a; }
00348 
00349     public:
00350 
00351       /**
00352        *  @brief  Allocate memory.
00353        *  @param  __a  An allocator.
00354        *  @param  __n  The number of objects to allocate space for.
00355        *
00356        *  Calls @c a.allocate(n)
00357       */
00358       static pointer
00359       allocate(_Alloc& __a, size_type __n)
00360       { return __a.allocate(__n); }
00361 
00362       /**
00363        *  @brief  Allocate memory.
00364        *  @param  __a  An allocator.
00365        *  @param  __n  The number of objects to allocate space for.
00366        *  @param  __hint Aid to locality.
00367        *  @return Memory of suitable size and alignment for @a n objects
00368        *          of type @c value_type
00369        *
00370        *  Returns <tt> a.allocate(n, hint) </tt> if that expression is
00371        *  well-formed, otherwise returns @c a.allocate(n)
00372       */
00373       static pointer
00374       allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
00375       { return _S_allocate(__a, __n, __hint); }
00376 
00377       /**
00378        *  @brief  Deallocate memory.
00379        *  @param  __a  An allocator.
00380        *  @param  __p  Pointer to the memory to deallocate.
00381        *  @param  __n  The number of objects space was allocated for.
00382        *
00383        *  Calls <tt> a.deallocate(p, n) </tt>
00384       */
00385       static void deallocate(_Alloc& __a, pointer __p, size_type __n)
00386       { __a.deallocate(__p, __n); }
00387 
00388       /**
00389        *  @brief  Construct an object of type @a _Tp
00390        *  @param  __a  An allocator.
00391        *  @param  __p  Pointer to memory of suitable size and alignment for Tp
00392        *  @param  __args Constructor arguments.
00393        *
00394        *  Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
00395        *  if that expression is well-formed, otherwise uses placement-new
00396        *  to construct an object of type @a _Tp at location @a __p from the
00397        *  arguments @a __args...
00398       */
00399       template<typename _Tp, typename... _Args>
00400         static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
00401         -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
00402         { _S_construct(__a, __p, std::forward<_Args>(__args)...); }
00403 
00404       /**
00405        *  @brief  Destroy an object of type @a _Tp
00406        *  @param  __a  An allocator.
00407        *  @param  __p  Pointer to the object to destroy
00408        *
00409        *  Calls @c __a.destroy(__p) if that expression is well-formed,
00410        *  otherwise calls @c __p->~_Tp()
00411       */
00412       template<typename _Tp>
00413         static void destroy(_Alloc& __a, _Tp* __p)
00414         { _S_destroy(__a, __p); }
00415 
00416       /**
00417        *  @brief  The maximum supported allocation size
00418        *  @param  __a  An allocator.
00419        *  @return @c __a.max_size() or @c numeric_limits<size_type>::max()
00420        *
00421        *  Returns @c __a.max_size() if that expression is well-formed,
00422        *  otherwise returns @c numeric_limits<size_type>::max()
00423       */
00424       static size_type max_size(const _Alloc& __a) noexcept
00425       { return _S_max_size(__a, 0); }
00426 
00427       /**
00428        *  @brief  Obtain an allocator to use when copying a container.
00429        *  @param  __rhs  An allocator.
00430        *  @return @c __rhs.select_on_container_copy_construction() or @a __rhs
00431        *
00432        *  Returns @c __rhs.select_on_container_copy_construction() if that
00433        *  expression is well-formed, otherwise returns @a __rhs
00434       */
00435       static _Alloc
00436       select_on_container_copy_construction(const _Alloc& __rhs)
00437       { return _S_select(__rhs, 0); }
00438     };
00439 
00440   /// Partial specialization for std::allocator.
00441   template<typename _Tp>
00442     struct allocator_traits<allocator<_Tp>>
00443     {
00444       /// The allocator type
00445       using allocator_type = allocator<_Tp>;
00446       /// The allocated type
00447       using value_type = _Tp;
00448 
00449       /// The allocator's pointer type.
00450       using pointer = _Tp*;
00451 
00452       /// The allocator's const pointer type.
00453       using const_pointer = const _Tp*;
00454 
00455       /// The allocator's void pointer type.
00456       using void_pointer = void*;
00457 
00458       /// The allocator's const void pointer type.
00459       using const_void_pointer = const void*;
00460 
00461       /// The allocator's difference type
00462       using difference_type = std::ptrdiff_t;
00463 
00464       /// The allocator's size type
00465       using size_type = std::size_t;
00466 
00467       /// How the allocator is propagated on copy assignment
00468       using propagate_on_container_copy_assignment = false_type;
00469 
00470       /// How the allocator is propagated on move assignment
00471       using propagate_on_container_move_assignment = true_type;
00472 
00473       /// How the allocator is propagated on swap
00474       using propagate_on_container_swap = false_type;
00475 
00476       template<typename _Up>
00477         using rebind_alloc = allocator<_Up>;
00478 
00479       template<typename _Up>
00480         using rebind_traits = allocator_traits<allocator<_Up>>;
00481 
00482       /**
00483        *  @brief  Allocate memory.
00484        *  @param  __a  An allocator.
00485        *  @param  __n  The number of objects to allocate space for.
00486        *
00487        *  Calls @c a.allocate(n)
00488       */
00489       static pointer
00490       allocate(allocator_type& __a, size_type __n)
00491       { return __a.allocate(__n); }
00492 
00493       /**
00494        *  @brief  Allocate memory.
00495        *  @param  __a  An allocator.
00496        *  @param  __n  The number of objects to allocate space for.
00497        *  @param  __hint Aid to locality.
00498        *  @return Memory of suitable size and alignment for @a n objects
00499        *          of type @c value_type
00500        *
00501        *  Returns <tt> a.allocate(n, hint) </tt>
00502       */
00503       static pointer
00504       allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
00505       { return __a.allocate(__n, __hint); }
00506 
00507       /**
00508        *  @brief  Deallocate memory.
00509        *  @param  __a  An allocator.
00510        *  @param  __p  Pointer to the memory to deallocate.
00511        *  @param  __n  The number of objects space was allocated for.
00512        *
00513        *  Calls <tt> a.deallocate(p, n) </tt>
00514       */
00515       static void
00516       deallocate(allocator_type& __a, pointer __p, size_type __n)
00517       { __a.deallocate(__p, __n); }
00518 
00519       /**
00520        *  @brief  Construct an object of type @a _Up
00521        *  @param  __a  An allocator.
00522        *  @param  __p  Pointer to memory of suitable size and alignment for Tp
00523        *  @param  __args Constructor arguments.
00524        *
00525        *  Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
00526       */
00527       template<typename _Up, typename... _Args>
00528         static void
00529         construct(allocator_type& __a, _Up* __p, _Args&&... __args)
00530         { __a.construct(__p, std::forward<_Args>(__args)...); }
00531 
00532       /**
00533        *  @brief  Destroy an object of type @a _Up
00534        *  @param  __a  An allocator.
00535        *  @param  __p  Pointer to the object to destroy
00536        *
00537        *  Calls @c __a.destroy(__p).
00538       */
00539       template<typename _Up>
00540         static void
00541         destroy(allocator_type& __a, _Up* __p)
00542         { __a.destroy(__p); }
00543 
00544       /**
00545        *  @brief  The maximum supported allocation size
00546        *  @param  __a  An allocator.
00547        *  @return @c __a.max_size()
00548       */
00549       static size_type
00550       max_size(const allocator_type& __a) noexcept
00551       { return __a.max_size(); }
00552 
00553       /**
00554        *  @brief  Obtain an allocator to use when copying a container.
00555        *  @param  __rhs  An allocator.
00556        *  @return @c __rhs
00557       */
00558       static allocator_type
00559       select_on_container_copy_construction(const allocator_type& __rhs)
00560       { return __rhs; }
00561     };
00562 
00563 
00564   template<typename _Alloc>
00565     inline void
00566     __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
00567     { __one = __two; }
00568 
00569   template<typename _Alloc>
00570     inline void
00571     __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
00572     { }
00573 
00574   template<typename _Alloc>
00575     inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
00576     {
00577       typedef allocator_traits<_Alloc> __traits;
00578       typedef typename __traits::propagate_on_container_copy_assignment __pocca;
00579       __do_alloc_on_copy(__one, __two, __pocca());
00580     }
00581 
00582   template<typename _Alloc>
00583     inline _Alloc __alloc_on_copy(const _Alloc& __a)
00584     {
00585       typedef allocator_traits<_Alloc> __traits;
00586       return __traits::select_on_container_copy_construction(__a);
00587     }
00588 
00589   template<typename _Alloc>
00590     inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
00591     { __one = std::move(__two); }
00592 
00593   template<typename _Alloc>
00594     inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
00595     { }
00596 
00597   template<typename _Alloc>
00598     inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
00599     {
00600       typedef allocator_traits<_Alloc> __traits;
00601       typedef typename __traits::propagate_on_container_move_assignment __pocma;
00602       __do_alloc_on_move(__one, __two, __pocma());
00603     }
00604 
00605   template<typename _Alloc>
00606     inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
00607     {
00608       using std::swap;
00609       swap(__one, __two);
00610     }
00611 
00612   template<typename _Alloc>
00613     inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
00614     { }
00615 
00616   template<typename _Alloc>
00617     inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
00618     {
00619       typedef allocator_traits<_Alloc> __traits;
00620       typedef typename __traits::propagate_on_container_swap __pocs;
00621       __do_alloc_on_swap(__one, __two, __pocs());
00622     }
00623 
00624   template<typename _Alloc>
00625     class __is_copy_insertable_impl
00626     {
00627       typedef allocator_traits<_Alloc> _Traits;
00628 
00629       template<typename _Up, typename
00630                = decltype(_Traits::construct(std::declval<_Alloc&>(),
00631                                              std::declval<_Up*>(),
00632                                              std::declval<const _Up&>()))>
00633         static true_type
00634         _M_select(int);
00635 
00636       template<typename _Up>
00637         static false_type
00638         _M_select(...);
00639 
00640     public:
00641       typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
00642     };
00643 
00644   // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
00645   template<typename _Alloc>
00646     struct __is_copy_insertable
00647     : __is_copy_insertable_impl<_Alloc>::type
00648     { };
00649 
00650   // std::allocator<_Tp> just requires CopyConstructible
00651   template<typename _Tp>
00652     struct __is_copy_insertable<allocator<_Tp>>
00653     : is_copy_constructible<_Tp>
00654     { };
00655 
00656 _GLIBCXX_END_NAMESPACE_VERSION
00657 } // namespace std
00658 
00659 #endif
00660 #endif