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