alloc_traits.h 27 KB

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