alloc_traits.h 30 KB

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