1*38fd1498Szrj // Allocator traits -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2011-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file bits/alloc_traits.h 26*38fd1498Szrj * This is an internal header file, included by other library headers. 27*38fd1498Szrj * Do not attempt to use it directly. @headername{memory} 28*38fd1498Szrj */ 29*38fd1498Szrj 30*38fd1498Szrj #ifndef _ALLOC_TRAITS_H 31*38fd1498Szrj #define _ALLOC_TRAITS_H 1 32*38fd1498Szrj 33*38fd1498Szrj #if __cplusplus >= 201103L 34*38fd1498Szrj 35*38fd1498Szrj #include <bits/memoryfwd.h> 36*38fd1498Szrj #include <bits/ptr_traits.h> 37*38fd1498Szrj #include <ext/numeric_traits.h> 38*38fd1498Szrj 39*38fd1498Szrj #define __cpp_lib_allocator_traits_is_always_equal 201411 40*38fd1498Szrj 41*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 42*38fd1498Szrj { 43*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 44*38fd1498Szrj 45*38fd1498Szrj struct __allocator_traits_base 46*38fd1498Szrj { 47*38fd1498Szrj template<typename _Tp, typename _Up, typename = void> 48*38fd1498Szrj struct __rebind : __replace_first_arg<_Tp, _Up> { }; 49*38fd1498Szrj 50*38fd1498Szrj template<typename _Tp, typename _Up> 51*38fd1498Szrj struct __rebind<_Tp, _Up, 52*38fd1498Szrj __void_t<typename _Tp::template rebind<_Up>::other>> 53*38fd1498Szrj { using type = typename _Tp::template rebind<_Up>::other; }; 54*38fd1498Szrj 55*38fd1498Szrj protected: 56*38fd1498Szrj template<typename _Tp> 57*38fd1498Szrj using __pointer = typename _Tp::pointer; 58*38fd1498Szrj template<typename _Tp> 59*38fd1498Szrj using __c_pointer = typename _Tp::const_pointer; 60*38fd1498Szrj template<typename _Tp> 61*38fd1498Szrj using __v_pointer = typename _Tp::void_pointer; 62*38fd1498Szrj template<typename _Tp> 63*38fd1498Szrj using __cv_pointer = typename _Tp::const_void_pointer; 64*38fd1498Szrj template<typename _Tp> 65*38fd1498Szrj using __pocca = typename _Tp::propagate_on_container_copy_assignment; 66*38fd1498Szrj template<typename _Tp> 67*38fd1498Szrj using __pocma = typename _Tp::propagate_on_container_move_assignment; 68*38fd1498Szrj template<typename _Tp> 69*38fd1498Szrj using __pocs = typename _Tp::propagate_on_container_swap; 70*38fd1498Szrj template<typename _Tp> 71*38fd1498Szrj using __equal = typename _Tp::is_always_equal; 72*38fd1498Szrj }; 73*38fd1498Szrj 74*38fd1498Szrj template<typename _Alloc, typename _Up> 75*38fd1498Szrj using __alloc_rebind 76*38fd1498Szrj = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type; 77*38fd1498Szrj 78*38fd1498Szrj /** 79*38fd1498Szrj * @brief Uniform interface to all allocator types. 80*38fd1498Szrj * @ingroup allocators 81*38fd1498Szrj */ 82*38fd1498Szrj template<typename _Alloc> 83*38fd1498Szrj struct allocator_traits : __allocator_traits_base 84*38fd1498Szrj { 85*38fd1498Szrj /// The allocator type 86*38fd1498Szrj typedef _Alloc allocator_type; 87*38fd1498Szrj /// The allocated type 88*38fd1498Szrj typedef typename _Alloc::value_type value_type; 89*38fd1498Szrj 90*38fd1498Szrj /** 91*38fd1498Szrj * @brief The allocator's pointer type. 92*38fd1498Szrj * 93*38fd1498Szrj * @c Alloc::pointer if that type exists, otherwise @c value_type* 94*38fd1498Szrj */ 95*38fd1498Szrj using pointer = __detected_or_t<value_type*, __pointer, _Alloc>; 96*38fd1498Szrj 97*38fd1498Szrj private: 98*38fd1498Szrj // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp> 99*38fd1498Szrj template<template<typename> class _Func, typename _Tp, typename = void> 100*38fd1498Szrj struct _Ptr 101*38fd1498Szrj { 102*38fd1498Szrj using type = typename pointer_traits<pointer>::template rebind<_Tp>; 103*38fd1498Szrj }; 104*38fd1498Szrj 105*38fd1498Szrj template<template<typename> class _Func, typename _Tp> 106*38fd1498Szrj struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>> 107*38fd1498Szrj { 108*38fd1498Szrj using type = _Func<_Alloc>; 109*38fd1498Szrj }; 110*38fd1498Szrj 111*38fd1498Szrj // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type 112*38fd1498Szrj template<typename _A2, typename _PtrT, typename = void> 113*38fd1498Szrj struct _Diff 114*38fd1498Szrj { using type = typename pointer_traits<_PtrT>::difference_type; }; 115*38fd1498Szrj 116*38fd1498Szrj template<typename _A2, typename _PtrT> 117*38fd1498Szrj struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>> 118*38fd1498Szrj { using type = typename _A2::difference_type; }; 119*38fd1498Szrj 120*38fd1498Szrj // Select _A2::size_type or make_unsigned<_DiffT>::type 121*38fd1498Szrj template<typename _A2, typename _DiffT, typename = void> 122*38fd1498Szrj struct _Size : make_unsigned<_DiffT> { }; 123*38fd1498Szrj 124*38fd1498Szrj template<typename _A2, typename _DiffT> 125*38fd1498Szrj struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>> 126*38fd1498Szrj { using type = typename _A2::size_type; }; 127*38fd1498Szrj 128*38fd1498Szrj public: 129*38fd1498Szrj /** 130*38fd1498Szrj * @brief The allocator's const pointer type. 131*38fd1498Szrj * 132*38fd1498Szrj * @c Alloc::const_pointer if that type exists, otherwise 133*38fd1498Szrj * <tt> pointer_traits<pointer>::rebind<const value_type> </tt> 134*38fd1498Szrj */ 135*38fd1498Szrj using const_pointer = typename _Ptr<__c_pointer, const value_type>::type; 136*38fd1498Szrj 137*38fd1498Szrj /** 138*38fd1498Szrj * @brief The allocator's void pointer type. 139*38fd1498Szrj * 140*38fd1498Szrj * @c Alloc::void_pointer if that type exists, otherwise 141*38fd1498Szrj * <tt> pointer_traits<pointer>::rebind<void> </tt> 142*38fd1498Szrj */ 143*38fd1498Szrj using void_pointer = typename _Ptr<__v_pointer, void>::type; 144*38fd1498Szrj 145*38fd1498Szrj /** 146*38fd1498Szrj * @brief The allocator's const void pointer type. 147*38fd1498Szrj * 148*38fd1498Szrj * @c Alloc::const_void_pointer if that type exists, otherwise 149*38fd1498Szrj * <tt> pointer_traits<pointer>::rebind<const void> </tt> 150*38fd1498Szrj */ 151*38fd1498Szrj using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type; 152*38fd1498Szrj 153*38fd1498Szrj /** 154*38fd1498Szrj * @brief The allocator's difference type 155*38fd1498Szrj * 156*38fd1498Szrj * @c Alloc::difference_type if that type exists, otherwise 157*38fd1498Szrj * <tt> pointer_traits<pointer>::difference_type </tt> 158*38fd1498Szrj */ 159*38fd1498Szrj using difference_type = typename _Diff<_Alloc, pointer>::type; 160*38fd1498Szrj 161*38fd1498Szrj /** 162*38fd1498Szrj * @brief The allocator's size type 163*38fd1498Szrj * 164*38fd1498Szrj * @c Alloc::size_type if that type exists, otherwise 165*38fd1498Szrj * <tt> make_unsigned<difference_type>::type </tt> 166*38fd1498Szrj */ 167*38fd1498Szrj using size_type = typename _Size<_Alloc, difference_type>::type; 168*38fd1498Szrj 169*38fd1498Szrj /** 170*38fd1498Szrj * @brief How the allocator is propagated on copy assignment 171*38fd1498Szrj * 172*38fd1498Szrj * @c Alloc::propagate_on_container_copy_assignment if that type exists, 173*38fd1498Szrj * otherwise @c false_type 174*38fd1498Szrj */ 175*38fd1498Szrj using propagate_on_container_copy_assignment 176*38fd1498Szrj = __detected_or_t<false_type, __pocca, _Alloc>; 177*38fd1498Szrj 178*38fd1498Szrj /** 179*38fd1498Szrj * @brief How the allocator is propagated on move assignment 180*38fd1498Szrj * 181*38fd1498Szrj * @c Alloc::propagate_on_container_move_assignment if that type exists, 182*38fd1498Szrj * otherwise @c false_type 183*38fd1498Szrj */ 184*38fd1498Szrj using propagate_on_container_move_assignment 185*38fd1498Szrj = __detected_or_t<false_type, __pocma, _Alloc>; 186*38fd1498Szrj 187*38fd1498Szrj /** 188*38fd1498Szrj * @brief How the allocator is propagated on swap 189*38fd1498Szrj * 190*38fd1498Szrj * @c Alloc::propagate_on_container_swap if that type exists, 191*38fd1498Szrj * otherwise @c false_type 192*38fd1498Szrj */ 193*38fd1498Szrj using propagate_on_container_swap 194*38fd1498Szrj = __detected_or_t<false_type, __pocs, _Alloc>; 195*38fd1498Szrj 196*38fd1498Szrj /** 197*38fd1498Szrj * @brief Whether all instances of the allocator type compare equal. 198*38fd1498Szrj * 199*38fd1498Szrj * @c Alloc::is_always_equal if that type exists, 200*38fd1498Szrj * otherwise @c is_empty<Alloc>::type 201*38fd1498Szrj */ 202*38fd1498Szrj using is_always_equal 203*38fd1498Szrj = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>; 204*38fd1498Szrj 205*38fd1498Szrj template<typename _Tp> 206*38fd1498Szrj using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; 207*38fd1498Szrj template<typename _Tp> 208*38fd1498Szrj using rebind_traits = allocator_traits<rebind_alloc<_Tp>>; 209*38fd1498Szrj 210*38fd1498Szrj private: 211*38fd1498Szrj template<typename _Alloc2> 212*38fd1498Szrj static auto 213*38fd1498Szrj _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int) 214*38fd1498Szrj -> decltype(__a.allocate(__n, __hint)) 215*38fd1498Szrj { return __a.allocate(__n, __hint); } 216*38fd1498Szrj 217*38fd1498Szrj template<typename _Alloc2> 218*38fd1498Szrj static pointer 219*38fd1498Szrj _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...) 220*38fd1498Szrj { return __a.allocate(__n); } 221*38fd1498Szrj 222*38fd1498Szrj template<typename _Tp, typename... _Args> 223*38fd1498Szrj struct __construct_helper 224*38fd1498Szrj { 225*38fd1498Szrj template<typename _Alloc2, 226*38fd1498Szrj typename = decltype(std::declval<_Alloc2*>()->construct( 227*38fd1498Szrj std::declval<_Tp*>(), std::declval<_Args>()...))> 228*38fd1498Szrj static true_type __test(int); 229*38fd1498Szrj 230*38fd1498Szrj template<typename> 231*38fd1498Szrj static false_type __test(...); 232*38fd1498Szrj 233*38fd1498Szrj using type = decltype(__test<_Alloc>(0)); 234*38fd1498Szrj }; 235*38fd1498Szrj 236*38fd1498Szrj template<typename _Tp, typename... _Args> 237*38fd1498Szrj using __has_construct 238*38fd1498Szrj = typename __construct_helper<_Tp, _Args...>::type; 239*38fd1498Szrj 240*38fd1498Szrj template<typename _Tp, typename... _Args> 241*38fd1498Szrj static _Require<__has_construct<_Tp, _Args...>> 242*38fd1498Szrj _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 243*38fd1498Szrj { __a.construct(__p, std::forward<_Args>(__args)...); } 244*38fd1498Szrj 245*38fd1498Szrj template<typename _Tp, typename... _Args> 246*38fd1498Szrj static 247*38fd1498Szrj _Require<__and_<__not_<__has_construct<_Tp, _Args...>>, 248*38fd1498Szrj is_constructible<_Tp, _Args...>>> 249*38fd1498Szrj _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) 250*38fd1498Szrj { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } 251*38fd1498Szrj 252*38fd1498Szrj template<typename _Alloc2, typename _Tp> 253*38fd1498Szrj static auto 254*38fd1498Szrj _S_destroy(_Alloc2& __a, _Tp* __p, int) 255*38fd1498Szrj -> decltype(__a.destroy(__p)) 256*38fd1498Szrj { __a.destroy(__p); } 257*38fd1498Szrj 258*38fd1498Szrj template<typename _Alloc2, typename _Tp> 259*38fd1498Szrj static void 260*38fd1498Szrj _S_destroy(_Alloc2&, _Tp* __p, ...) 261*38fd1498Szrj { __p->~_Tp(); } 262*38fd1498Szrj 263*38fd1498Szrj template<typename _Alloc2> 264*38fd1498Szrj static auto 265*38fd1498Szrj _S_max_size(_Alloc2& __a, int) 266*38fd1498Szrj -> decltype(__a.max_size()) 267*38fd1498Szrj { return __a.max_size(); } 268*38fd1498Szrj 269*38fd1498Szrj template<typename _Alloc2> 270*38fd1498Szrj static size_type 271*38fd1498Szrj _S_max_size(_Alloc2&, ...) 272*38fd1498Szrj { 273*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 274*38fd1498Szrj // 2466. allocator_traits::max_size() default behavior is incorrect 275*38fd1498Szrj return __gnu_cxx::__numeric_traits<size_type>::__max 276*38fd1498Szrj / sizeof(value_type); 277*38fd1498Szrj } 278*38fd1498Szrj 279*38fd1498Szrj template<typename _Alloc2> 280*38fd1498Szrj static auto 281*38fd1498Szrj _S_select(_Alloc2& __a, int) 282*38fd1498Szrj -> decltype(__a.select_on_container_copy_construction()) 283*38fd1498Szrj { return __a.select_on_container_copy_construction(); } 284*38fd1498Szrj 285*38fd1498Szrj template<typename _Alloc2> 286*38fd1498Szrj static _Alloc2 287*38fd1498Szrj _S_select(_Alloc2& __a, ...) 288*38fd1498Szrj { return __a; } 289*38fd1498Szrj 290*38fd1498Szrj public: 291*38fd1498Szrj 292*38fd1498Szrj /** 293*38fd1498Szrj * @brief Allocate memory. 294*38fd1498Szrj * @param __a An allocator. 295*38fd1498Szrj * @param __n The number of objects to allocate space for. 296*38fd1498Szrj * 297*38fd1498Szrj * Calls @c a.allocate(n) 298*38fd1498Szrj */ 299*38fd1498Szrj static pointer 300*38fd1498Szrj allocate(_Alloc& __a, size_type __n) 301*38fd1498Szrj { return __a.allocate(__n); } 302*38fd1498Szrj 303*38fd1498Szrj /** 304*38fd1498Szrj * @brief Allocate memory. 305*38fd1498Szrj * @param __a An allocator. 306*38fd1498Szrj * @param __n The number of objects to allocate space for. 307*38fd1498Szrj * @param __hint Aid to locality. 308*38fd1498Szrj * @return Memory of suitable size and alignment for @a n objects 309*38fd1498Szrj * of type @c value_type 310*38fd1498Szrj * 311*38fd1498Szrj * Returns <tt> a.allocate(n, hint) </tt> if that expression is 312*38fd1498Szrj * well-formed, otherwise returns @c a.allocate(n) 313*38fd1498Szrj */ 314*38fd1498Szrj static pointer 315*38fd1498Szrj allocate(_Alloc& __a, size_type __n, const_void_pointer __hint) 316*38fd1498Szrj { return _S_allocate(__a, __n, __hint, 0); } 317*38fd1498Szrj 318*38fd1498Szrj /** 319*38fd1498Szrj * @brief Deallocate memory. 320*38fd1498Szrj * @param __a An allocator. 321*38fd1498Szrj * @param __p Pointer to the memory to deallocate. 322*38fd1498Szrj * @param __n The number of objects space was allocated for. 323*38fd1498Szrj * 324*38fd1498Szrj * Calls <tt> a.deallocate(p, n) </tt> 325*38fd1498Szrj */ 326*38fd1498Szrj static void 327*38fd1498Szrj deallocate(_Alloc& __a, pointer __p, size_type __n) 328*38fd1498Szrj { __a.deallocate(__p, __n); } 329*38fd1498Szrj 330*38fd1498Szrj /** 331*38fd1498Szrj * @brief Construct an object of type @a _Tp 332*38fd1498Szrj * @param __a An allocator. 333*38fd1498Szrj * @param __p Pointer to memory of suitable size and alignment for Tp 334*38fd1498Szrj * @param __args Constructor arguments. 335*38fd1498Szrj * 336*38fd1498Szrj * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt> 337*38fd1498Szrj * if that expression is well-formed, otherwise uses placement-new 338*38fd1498Szrj * to construct an object of type @a _Tp at location @a __p from the 339*38fd1498Szrj * arguments @a __args... 340*38fd1498Szrj */ 341*38fd1498Szrj template<typename _Tp, typename... _Args> 342*38fd1498Szrj static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 343*38fd1498Szrj -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) 344*38fd1498Szrj { _S_construct(__a, __p, std::forward<_Args>(__args)...); } 345*38fd1498Szrj 346*38fd1498Szrj /** 347*38fd1498Szrj * @brief Destroy an object of type @a _Tp 348*38fd1498Szrj * @param __a An allocator. 349*38fd1498Szrj * @param __p Pointer to the object to destroy 350*38fd1498Szrj * 351*38fd1498Szrj * Calls @c __a.destroy(__p) if that expression is well-formed, 352*38fd1498Szrj * otherwise calls @c __p->~_Tp() 353*38fd1498Szrj */ 354*38fd1498Szrj template<typename _Tp> 355*38fd1498Szrj static void destroy(_Alloc& __a, _Tp* __p) 356*38fd1498Szrj { _S_destroy(__a, __p, 0); } 357*38fd1498Szrj 358*38fd1498Szrj /** 359*38fd1498Szrj * @brief The maximum supported allocation size 360*38fd1498Szrj * @param __a An allocator. 361*38fd1498Szrj * @return @c __a.max_size() or @c numeric_limits<size_type>::max() 362*38fd1498Szrj * 363*38fd1498Szrj * Returns @c __a.max_size() if that expression is well-formed, 364*38fd1498Szrj * otherwise returns @c numeric_limits<size_type>::max() 365*38fd1498Szrj */ 366*38fd1498Szrj static size_type max_size(const _Alloc& __a) noexcept 367*38fd1498Szrj { return _S_max_size(__a, 0); } 368*38fd1498Szrj 369*38fd1498Szrj /** 370*38fd1498Szrj * @brief Obtain an allocator to use when copying a container. 371*38fd1498Szrj * @param __rhs An allocator. 372*38fd1498Szrj * @return @c __rhs.select_on_container_copy_construction() or @a __rhs 373*38fd1498Szrj * 374*38fd1498Szrj * Returns @c __rhs.select_on_container_copy_construction() if that 375*38fd1498Szrj * expression is well-formed, otherwise returns @a __rhs 376*38fd1498Szrj */ 377*38fd1498Szrj static _Alloc 378*38fd1498Szrj select_on_container_copy_construction(const _Alloc& __rhs) 379*38fd1498Szrj { return _S_select(__rhs, 0); } 380*38fd1498Szrj }; 381*38fd1498Szrj 382*38fd1498Szrj /// Partial specialization for std::allocator. 383*38fd1498Szrj template<typename _Tp> 384*38fd1498Szrj struct allocator_traits<allocator<_Tp>> 385*38fd1498Szrj { 386*38fd1498Szrj /// The allocator type 387*38fd1498Szrj using allocator_type = allocator<_Tp>; 388*38fd1498Szrj /// The allocated type 389*38fd1498Szrj using value_type = _Tp; 390*38fd1498Szrj 391*38fd1498Szrj /// The allocator's pointer type. 392*38fd1498Szrj using pointer = _Tp*; 393*38fd1498Szrj 394*38fd1498Szrj /// The allocator's const pointer type. 395*38fd1498Szrj using const_pointer = const _Tp*; 396*38fd1498Szrj 397*38fd1498Szrj /// The allocator's void pointer type. 398*38fd1498Szrj using void_pointer = void*; 399*38fd1498Szrj 400*38fd1498Szrj /// The allocator's const void pointer type. 401*38fd1498Szrj using const_void_pointer = const void*; 402*38fd1498Szrj 403*38fd1498Szrj /// The allocator's difference type 404*38fd1498Szrj using difference_type = std::ptrdiff_t; 405*38fd1498Szrj 406*38fd1498Szrj /// The allocator's size type 407*38fd1498Szrj using size_type = std::size_t; 408*38fd1498Szrj 409*38fd1498Szrj /// How the allocator is propagated on copy assignment 410*38fd1498Szrj using propagate_on_container_copy_assignment = false_type; 411*38fd1498Szrj 412*38fd1498Szrj /// How the allocator is propagated on move assignment 413*38fd1498Szrj using propagate_on_container_move_assignment = true_type; 414*38fd1498Szrj 415*38fd1498Szrj /// How the allocator is propagated on swap 416*38fd1498Szrj using propagate_on_container_swap = false_type; 417*38fd1498Szrj 418*38fd1498Szrj /// Whether all instances of the allocator type compare equal. 419*38fd1498Szrj using is_always_equal = true_type; 420*38fd1498Szrj 421*38fd1498Szrj template<typename _Up> 422*38fd1498Szrj using rebind_alloc = allocator<_Up>; 423*38fd1498Szrj 424*38fd1498Szrj template<typename _Up> 425*38fd1498Szrj using rebind_traits = allocator_traits<allocator<_Up>>; 426*38fd1498Szrj 427*38fd1498Szrj /** 428*38fd1498Szrj * @brief Allocate memory. 429*38fd1498Szrj * @param __a An allocator. 430*38fd1498Szrj * @param __n The number of objects to allocate space for. 431*38fd1498Szrj * 432*38fd1498Szrj * Calls @c a.allocate(n) 433*38fd1498Szrj */ 434*38fd1498Szrj static pointer 435*38fd1498Szrj allocate(allocator_type& __a, size_type __n) 436*38fd1498Szrj { return __a.allocate(__n); } 437*38fd1498Szrj 438*38fd1498Szrj /** 439*38fd1498Szrj * @brief Allocate memory. 440*38fd1498Szrj * @param __a An allocator. 441*38fd1498Szrj * @param __n The number of objects to allocate space for. 442*38fd1498Szrj * @param __hint Aid to locality. 443*38fd1498Szrj * @return Memory of suitable size and alignment for @a n objects 444*38fd1498Szrj * of type @c value_type 445*38fd1498Szrj * 446*38fd1498Szrj * Returns <tt> a.allocate(n, hint) </tt> 447*38fd1498Szrj */ 448*38fd1498Szrj static pointer 449*38fd1498Szrj allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) 450*38fd1498Szrj { return __a.allocate(__n, __hint); } 451*38fd1498Szrj 452*38fd1498Szrj /** 453*38fd1498Szrj * @brief Deallocate memory. 454*38fd1498Szrj * @param __a An allocator. 455*38fd1498Szrj * @param __p Pointer to the memory to deallocate. 456*38fd1498Szrj * @param __n The number of objects space was allocated for. 457*38fd1498Szrj * 458*38fd1498Szrj * Calls <tt> a.deallocate(p, n) </tt> 459*38fd1498Szrj */ 460*38fd1498Szrj static void 461*38fd1498Szrj deallocate(allocator_type& __a, pointer __p, size_type __n) 462*38fd1498Szrj { __a.deallocate(__p, __n); } 463*38fd1498Szrj 464*38fd1498Szrj /** 465*38fd1498Szrj * @brief Construct an object of type @a _Up 466*38fd1498Szrj * @param __a An allocator. 467*38fd1498Szrj * @param __p Pointer to memory of suitable size and alignment for Tp 468*38fd1498Szrj * @param __args Constructor arguments. 469*38fd1498Szrj * 470*38fd1498Szrj * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt> 471*38fd1498Szrj */ 472*38fd1498Szrj template<typename _Up, typename... _Args> 473*38fd1498Szrj static void 474*38fd1498Szrj construct(allocator_type& __a, _Up* __p, _Args&&... __args) 475*38fd1498Szrj { __a.construct(__p, std::forward<_Args>(__args)...); } 476*38fd1498Szrj 477*38fd1498Szrj /** 478*38fd1498Szrj * @brief Destroy an object of type @a _Up 479*38fd1498Szrj * @param __a An allocator. 480*38fd1498Szrj * @param __p Pointer to the object to destroy 481*38fd1498Szrj * 482*38fd1498Szrj * Calls @c __a.destroy(__p). 483*38fd1498Szrj */ 484*38fd1498Szrj template<typename _Up> 485*38fd1498Szrj static void 486*38fd1498Szrj destroy(allocator_type& __a, _Up* __p) 487*38fd1498Szrj { __a.destroy(__p); } 488*38fd1498Szrj 489*38fd1498Szrj /** 490*38fd1498Szrj * @brief The maximum supported allocation size 491*38fd1498Szrj * @param __a An allocator. 492*38fd1498Szrj * @return @c __a.max_size() 493*38fd1498Szrj */ 494*38fd1498Szrj static size_type 495*38fd1498Szrj max_size(const allocator_type& __a) noexcept 496*38fd1498Szrj { return __a.max_size(); } 497*38fd1498Szrj 498*38fd1498Szrj /** 499*38fd1498Szrj * @brief Obtain an allocator to use when copying a container. 500*38fd1498Szrj * @param __rhs An allocator. 501*38fd1498Szrj * @return @c __rhs 502*38fd1498Szrj */ 503*38fd1498Szrj static allocator_type 504*38fd1498Szrj select_on_container_copy_construction(const allocator_type& __rhs) 505*38fd1498Szrj { return __rhs; } 506*38fd1498Szrj }; 507*38fd1498Szrj 508*38fd1498Szrj 509*38fd1498Szrj template<typename _Alloc> 510*38fd1498Szrj inline void 511*38fd1498Szrj __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type) 512*38fd1498Szrj { __one = __two; } 513*38fd1498Szrj 514*38fd1498Szrj template<typename _Alloc> 515*38fd1498Szrj inline void 516*38fd1498Szrj __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type) 517*38fd1498Szrj { } 518*38fd1498Szrj 519*38fd1498Szrj template<typename _Alloc> 520*38fd1498Szrj inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two) 521*38fd1498Szrj { 522*38fd1498Szrj typedef allocator_traits<_Alloc> __traits; 523*38fd1498Szrj typedef typename __traits::propagate_on_container_copy_assignment __pocca; 524*38fd1498Szrj __do_alloc_on_copy(__one, __two, __pocca()); 525*38fd1498Szrj } 526*38fd1498Szrj 527*38fd1498Szrj template<typename _Alloc> 528*38fd1498Szrj inline _Alloc __alloc_on_copy(const _Alloc& __a) 529*38fd1498Szrj { 530*38fd1498Szrj typedef allocator_traits<_Alloc> __traits; 531*38fd1498Szrj return __traits::select_on_container_copy_construction(__a); 532*38fd1498Szrj } 533*38fd1498Szrj 534*38fd1498Szrj template<typename _Alloc> 535*38fd1498Szrj inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type) 536*38fd1498Szrj { __one = std::move(__two); } 537*38fd1498Szrj 538*38fd1498Szrj template<typename _Alloc> 539*38fd1498Szrj inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type) 540*38fd1498Szrj { } 541*38fd1498Szrj 542*38fd1498Szrj template<typename _Alloc> 543*38fd1498Szrj inline void __alloc_on_move(_Alloc& __one, _Alloc& __two) 544*38fd1498Szrj { 545*38fd1498Szrj typedef allocator_traits<_Alloc> __traits; 546*38fd1498Szrj typedef typename __traits::propagate_on_container_move_assignment __pocma; 547*38fd1498Szrj __do_alloc_on_move(__one, __two, __pocma()); 548*38fd1498Szrj } 549*38fd1498Szrj 550*38fd1498Szrj template<typename _Alloc> 551*38fd1498Szrj inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type) 552*38fd1498Szrj { 553*38fd1498Szrj using std::swap; 554*38fd1498Szrj swap(__one, __two); 555*38fd1498Szrj } 556*38fd1498Szrj 557*38fd1498Szrj template<typename _Alloc> 558*38fd1498Szrj inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type) 559*38fd1498Szrj { } 560*38fd1498Szrj 561*38fd1498Szrj template<typename _Alloc> 562*38fd1498Szrj inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two) 563*38fd1498Szrj { 564*38fd1498Szrj typedef allocator_traits<_Alloc> __traits; 565*38fd1498Szrj typedef typename __traits::propagate_on_container_swap __pocs; 566*38fd1498Szrj __do_alloc_on_swap(__one, __two, __pocs()); 567*38fd1498Szrj } 568*38fd1498Szrj 569*38fd1498Szrj template<typename _Alloc> 570*38fd1498Szrj class __is_copy_insertable_impl 571*38fd1498Szrj { 572*38fd1498Szrj typedef allocator_traits<_Alloc> _Traits; 573*38fd1498Szrj 574*38fd1498Szrj template<typename _Up, typename 575*38fd1498Szrj = decltype(_Traits::construct(std::declval<_Alloc&>(), 576*38fd1498Szrj std::declval<_Up*>(), 577*38fd1498Szrj std::declval<const _Up&>()))> 578*38fd1498Szrj static true_type 579*38fd1498Szrj _M_select(int); 580*38fd1498Szrj 581*38fd1498Szrj template<typename _Up> 582*38fd1498Szrj static false_type 583*38fd1498Szrj _M_select(...); 584*38fd1498Szrj 585*38fd1498Szrj public: 586*38fd1498Szrj typedef decltype(_M_select<typename _Alloc::value_type>(0)) type; 587*38fd1498Szrj }; 588*38fd1498Szrj 589*38fd1498Szrj // true if _Alloc::value_type is CopyInsertable into containers using _Alloc 590*38fd1498Szrj template<typename _Alloc> 591*38fd1498Szrj struct __is_copy_insertable 592*38fd1498Szrj : __is_copy_insertable_impl<_Alloc>::type 593*38fd1498Szrj { }; 594*38fd1498Szrj 595*38fd1498Szrj // std::allocator<_Tp> just requires CopyConstructible 596*38fd1498Szrj template<typename _Tp> 597*38fd1498Szrj struct __is_copy_insertable<allocator<_Tp>> 598*38fd1498Szrj : is_copy_constructible<_Tp> 599*38fd1498Szrj { }; 600*38fd1498Szrj 601*38fd1498Szrj #if __cplusplus >= 201103L 602*38fd1498Szrj // Trait to detect Allocator-like types. 603*38fd1498Szrj template<typename _Alloc, typename = void> 604*38fd1498Szrj struct __is_allocator : false_type { }; 605*38fd1498Szrj 606*38fd1498Szrj template<typename _Alloc> 607*38fd1498Szrj struct __is_allocator<_Alloc, 608*38fd1498Szrj __void_t<typename _Alloc::value_type, 609*38fd1498Szrj decltype(std::declval<_Alloc&>().allocate(size_t{}))>> 610*38fd1498Szrj : true_type { }; 611*38fd1498Szrj 612*38fd1498Szrj template<typename _Alloc> 613*38fd1498Szrj using _RequireAllocator 614*38fd1498Szrj = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type; 615*38fd1498Szrj #endif 616*38fd1498Szrj 617*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 618*38fd1498Szrj } // namespace std 619*38fd1498Szrj 620*38fd1498Szrj #endif 621*38fd1498Szrj #endif 622