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