scoped_allocator 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_SCOPED_ALLOCATOR
  10. #define _LIBCPP_SCOPED_ALLOCATOR
  11. /*
  12. scoped_allocator synopsis
  13. namespace std
  14. {
  15. template <class OuterAlloc, class... InnerAllocs>
  16. class scoped_allocator_adaptor : public OuterAlloc
  17. {
  18. typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
  19. scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
  20. public:
  21. typedef OuterAlloc outer_allocator_type;
  22. typedef see below inner_allocator_type;
  23. typedef typename OuterTraits::value_type value_type;
  24. typedef typename OuterTraits::size_type size_type;
  25. typedef typename OuterTraits::difference_type difference_type;
  26. typedef typename OuterTraits::pointer pointer;
  27. typedef typename OuterTraits::const_pointer const_pointer;
  28. typedef typename OuterTraits::void_pointer void_pointer;
  29. typedef typename OuterTraits::const_void_pointer const_void_pointer;
  30. typedef see below propagate_on_container_copy_assignment;
  31. typedef see below propagate_on_container_move_assignment;
  32. typedef see below propagate_on_container_swap;
  33. typedef see below is_always_equal;
  34. template <class Tp>
  35. struct rebind
  36. {
  37. typedef scoped_allocator_adaptor<
  38. OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
  39. };
  40. scoped_allocator_adaptor();
  41. template <class OuterA2>
  42. scoped_allocator_adaptor(OuterA2&& outerAlloc,
  43. const InnerAllocs&... innerAllocs) noexcept;
  44. scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
  45. scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
  46. template <class OuterA2>
  47. scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
  48. template <class OuterA2>
  49. scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
  50. scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
  51. scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
  52. ~scoped_allocator_adaptor();
  53. inner_allocator_type& inner_allocator() noexcept;
  54. const inner_allocator_type& inner_allocator() const noexcept;
  55. outer_allocator_type& outer_allocator() noexcept;
  56. const outer_allocator_type& outer_allocator() const noexcept;
  57. pointer allocate(size_type n); // [[nodiscard]] in C++20
  58. pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20
  59. void deallocate(pointer p, size_type n) noexcept;
  60. size_type max_size() const;
  61. template <class T, class... Args> void construct(T* p, Args&& args);
  62. template <class T1, class T2, class... Args1, class... Args2>
  63. void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
  64. tuple<Args2...> y);
  65. template <class T1, class T2>
  66. void construct(pair<T1, T2>* p);
  67. template <class T1, class T2, class U, class V>
  68. void construct(pair<T1, T2>* p, U&& x, V&& y);
  69. template <class T1, class T2, class U, class V>
  70. void construct(pair<T1, T2>* p, const pair<U, V>& x);
  71. template <class T1, class T2, class U, class V>
  72. void construct(pair<T1, T2>* p, pair<U, V>&& x);
  73. template <class T> void destroy(T* p);
  74. template <class T> void destroy(T* p) noexcept;
  75. scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
  76. };
  77. template<class OuterAlloc, class... InnerAllocs>
  78. scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
  79. -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
  80. template <class OuterA1, class OuterA2, class... InnerAllocs>
  81. bool
  82. operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
  83. const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  84. template <class OuterA1, class OuterA2, class... InnerAllocs>
  85. bool
  86. operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
  87. const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; // removed in C++20
  88. } // std
  89. */
  90. #include <__config>
  91. #include <__memory/allocator_traits.h>
  92. #include <__memory/uses_allocator_construction.h>
  93. #include <__type_traits/common_type.h>
  94. #include <__type_traits/enable_if.h>
  95. #include <__type_traits/integral_constant.h>
  96. #include <__type_traits/is_constructible.h>
  97. #include <__type_traits/remove_reference.h>
  98. #include <__utility/declval.h>
  99. #include <__utility/forward.h>
  100. #include <__utility/move.h>
  101. #include <__utility/pair.h>
  102. #include <__utility/piecewise_construct.h>
  103. #include <tuple>
  104. #include <version>
  105. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  106. # pragma GCC system_header
  107. #endif
  108. _LIBCPP_PUSH_MACROS
  109. #include <__undef_macros>
  110. _LIBCPP_BEGIN_NAMESPACE_STD
  111. #if !defined(_LIBCPP_CXX03_LANG)
  112. // scoped_allocator_adaptor
  113. template <class... _Allocs>
  114. class scoped_allocator_adaptor;
  115. template <class... _Allocs>
  116. struct __get_poc_copy_assignment;
  117. template <class _A0>
  118. struct __get_poc_copy_assignment<_A0> {
  119. static const bool value = allocator_traits<_A0>::propagate_on_container_copy_assignment::value;
  120. };
  121. template <class _A0, class... _Allocs>
  122. struct __get_poc_copy_assignment<_A0, _Allocs...> {
  123. static const bool value = allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
  124. __get_poc_copy_assignment<_Allocs...>::value;
  125. };
  126. template <class... _Allocs>
  127. struct __get_poc_move_assignment;
  128. template <class _A0>
  129. struct __get_poc_move_assignment<_A0> {
  130. static const bool value = allocator_traits<_A0>::propagate_on_container_move_assignment::value;
  131. };
  132. template <class _A0, class... _Allocs>
  133. struct __get_poc_move_assignment<_A0, _Allocs...> {
  134. static const bool value = allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
  135. __get_poc_move_assignment<_Allocs...>::value;
  136. };
  137. template <class... _Allocs>
  138. struct __get_poc_swap;
  139. template <class _A0>
  140. struct __get_poc_swap<_A0> {
  141. static const bool value = allocator_traits<_A0>::propagate_on_container_swap::value;
  142. };
  143. template <class _A0, class... _Allocs>
  144. struct __get_poc_swap<_A0, _Allocs...> {
  145. static const bool value =
  146. allocator_traits<_A0>::propagate_on_container_swap::value || __get_poc_swap<_Allocs...>::value;
  147. };
  148. template <class... _Allocs>
  149. struct __get_is_always_equal;
  150. template <class _A0>
  151. struct __get_is_always_equal<_A0> {
  152. static const bool value = allocator_traits<_A0>::is_always_equal::value;
  153. };
  154. template <class _A0, class... _Allocs>
  155. struct __get_is_always_equal<_A0, _Allocs...> {
  156. static const bool value = allocator_traits<_A0>::is_always_equal::value && __get_is_always_equal<_Allocs...>::value;
  157. };
  158. template <class... _Allocs>
  159. class __scoped_allocator_storage;
  160. template <class _OuterAlloc, class... _InnerAllocs>
  161. class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> : public _OuterAlloc {
  162. typedef _OuterAlloc outer_allocator_type;
  163. protected:
  164. typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
  165. private:
  166. inner_allocator_type __inner_;
  167. protected:
  168. _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage() _NOEXCEPT {}
  169. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  170. _LIBCPP_HIDE_FROM_ABI
  171. __scoped_allocator_storage(_OuterA2&& __outer_alloc, const _InnerAllocs&... __inner_allocs) _NOEXCEPT
  172. : outer_allocator_type(std::forward<_OuterA2>(__outer_alloc)),
  173. __inner_(__inner_allocs...) {}
  174. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
  175. _LIBCPP_HIDE_FROM_ABI
  176. __scoped_allocator_storage(const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  177. : outer_allocator_type(__other.outer_allocator()),
  178. __inner_(__other.inner_allocator()) {}
  179. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  180. _LIBCPP_HIDE_FROM_ABI
  181. __scoped_allocator_storage(__scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  182. : outer_allocator_type(std::move(__other.outer_allocator())),
  183. __inner_(std::move(__other.inner_allocator())) {}
  184. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  185. _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(_OuterA2&& __o, const inner_allocator_type& __i) _NOEXCEPT
  186. : outer_allocator_type(std::forward<_OuterA2>(__o)),
  187. __inner_(__i) {}
  188. _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return __inner_; }
  189. _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT { return __inner_; }
  190. _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT {
  191. return static_cast<outer_allocator_type&>(*this);
  192. }
  193. _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT {
  194. return static_cast<const outer_allocator_type&>(*this);
  195. }
  196. scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> _LIBCPP_HIDE_FROM_ABI
  197. select_on_container_copy_construction() const _NOEXCEPT {
  198. return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>(
  199. allocator_traits<outer_allocator_type>::select_on_container_copy_construction(outer_allocator()),
  200. allocator_traits<inner_allocator_type>::select_on_container_copy_construction(inner_allocator()));
  201. }
  202. template <class...>
  203. friend class __scoped_allocator_storage;
  204. };
  205. template <class _OuterAlloc>
  206. class __scoped_allocator_storage<_OuterAlloc> : public _OuterAlloc {
  207. typedef _OuterAlloc outer_allocator_type;
  208. protected:
  209. typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
  210. _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage() _NOEXCEPT {}
  211. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  212. _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT
  213. : outer_allocator_type(std::forward<_OuterA2>(__outer_alloc)) {}
  214. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
  215. _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
  216. : outer_allocator_type(__other.outer_allocator()) {}
  217. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  218. _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(__scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
  219. : outer_allocator_type(std::move(__other.outer_allocator())) {}
  220. _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT {
  221. return static_cast<inner_allocator_type&>(*this);
  222. }
  223. _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT {
  224. return static_cast<const inner_allocator_type&>(*this);
  225. }
  226. _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT {
  227. return static_cast<outer_allocator_type&>(*this);
  228. }
  229. _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT {
  230. return static_cast<const outer_allocator_type&>(*this);
  231. }
  232. _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor<outer_allocator_type>
  233. select_on_container_copy_construction() const _NOEXCEPT {
  234. return scoped_allocator_adaptor<outer_allocator_type>(
  235. allocator_traits<outer_allocator_type>::select_on_container_copy_construction(outer_allocator()));
  236. }
  237. __scoped_allocator_storage(const outer_allocator_type& __o, const inner_allocator_type& __i) _NOEXCEPT;
  238. template <class...>
  239. friend class __scoped_allocator_storage;
  240. };
  241. // __outermost
  242. template <class _Alloc>
  243. decltype(std::declval<_Alloc>().outer_allocator(), true_type()) __has_outer_allocator_test(_Alloc&& __a);
  244. template <class _Alloc>
  245. false_type __has_outer_allocator_test(const volatile _Alloc& __a);
  246. template <class _Alloc>
  247. struct __has_outer_allocator
  248. : public common_type< decltype(std::__has_outer_allocator_test(std::declval<_Alloc&>())) >::type {};
  249. template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
  250. struct __outermost {
  251. typedef _Alloc type;
  252. _LIBCPP_HIDE_FROM_ABI type& operator()(type& __a) const _NOEXCEPT { return __a; }
  253. };
  254. template <class _Alloc>
  255. struct __outermost<_Alloc, true> {
  256. typedef __libcpp_remove_reference_t< decltype(std::declval<_Alloc>().outer_allocator()) > _OuterAlloc;
  257. typedef typename __outermost<_OuterAlloc>::type type;
  258. _LIBCPP_HIDE_FROM_ABI type& operator()(_Alloc& __a) const _NOEXCEPT {
  259. return __outermost<_OuterAlloc>()(__a.outer_allocator());
  260. }
  261. };
  262. template <class _OuterAlloc, class... _InnerAllocs>
  263. class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
  264. : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> {
  265. typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> _Base;
  266. typedef allocator_traits<_OuterAlloc> _OuterTraits;
  267. public:
  268. typedef _OuterAlloc outer_allocator_type;
  269. typedef typename _Base::inner_allocator_type inner_allocator_type;
  270. typedef typename _OuterTraits::size_type size_type;
  271. typedef typename _OuterTraits::difference_type difference_type;
  272. typedef typename _OuterTraits::pointer pointer;
  273. typedef typename _OuterTraits::const_pointer const_pointer;
  274. typedef typename _OuterTraits::void_pointer void_pointer;
  275. typedef typename _OuterTraits::const_void_pointer const_void_pointer;
  276. typedef integral_constant< bool, __get_poc_copy_assignment<outer_allocator_type, _InnerAllocs...>::value >
  277. propagate_on_container_copy_assignment;
  278. typedef integral_constant< bool, __get_poc_move_assignment<outer_allocator_type, _InnerAllocs...>::value >
  279. propagate_on_container_move_assignment;
  280. typedef integral_constant< bool, __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value >
  281. propagate_on_container_swap;
  282. typedef integral_constant< bool, __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value >
  283. is_always_equal;
  284. template <class _Tp>
  285. struct rebind {
  286. typedef scoped_allocator_adaptor< typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs... > other;
  287. };
  288. _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor() _NOEXCEPT {}
  289. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  290. _LIBCPP_HIDE_FROM_ABI
  291. scoped_allocator_adaptor(_OuterA2&& __outer_alloc, const _InnerAllocs&... __inner_allocs) _NOEXCEPT
  292. : _Base(std::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
  293. // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
  294. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
  295. _LIBCPP_HIDE_FROM_ABI
  296. scoped_allocator_adaptor(const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  297. : _Base(__other) {}
  298. template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  299. _LIBCPP_HIDE_FROM_ABI
  300. scoped_allocator_adaptor(scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  301. : _Base(std::move(__other)) {}
  302. // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
  303. // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
  304. // ~scoped_allocator_adaptor() = default;
  305. _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return _Base::inner_allocator(); }
  306. _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT {
  307. return _Base::inner_allocator();
  308. }
  309. _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { return _Base::outer_allocator(); }
  310. _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT {
  311. return _Base::outer_allocator();
  312. }
  313. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI pointer allocate(size_type __n) {
  314. return allocator_traits<outer_allocator_type>::allocate(outer_allocator(), __n);
  315. }
  316. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI pointer allocate(size_type __n, const_void_pointer __hint) {
  317. return allocator_traits<outer_allocator_type>::allocate(outer_allocator(), __n, __hint);
  318. }
  319. _LIBCPP_HIDE_FROM_ABI void deallocate(pointer __p, size_type __n) _NOEXCEPT {
  320. allocator_traits<outer_allocator_type>::deallocate(outer_allocator(), __p, __n);
  321. }
  322. _LIBCPP_HIDE_FROM_ABI size_type max_size() const {
  323. return allocator_traits<outer_allocator_type>::max_size(outer_allocator());
  324. }
  325. # if _LIBCPP_STD_VER >= 20
  326. template <class _Type, class... _Args>
  327. _LIBCPP_HIDE_FROM_ABI void construct(_Type* __ptr, _Args&&... __args) {
  328. using _OM = __outermost<outer_allocator_type>;
  329. std::apply(
  330. [__ptr, this](auto&&... __newargs) {
  331. allocator_traits<typename _OM::type>::construct(
  332. _OM()(outer_allocator()), __ptr, std::forward<decltype(__newargs)>(__newargs)...);
  333. },
  334. std::uses_allocator_construction_args<_Type>(inner_allocator(), std::forward<_Args>(__args)...));
  335. }
  336. # else
  337. template <class _Tp, class... _Args>
  338. _LIBCPP_HIDE_FROM_ABI void construct(_Tp* __p, _Args&&... __args) {
  339. __construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(), __p, std::forward<_Args>(__args)...);
  340. }
  341. template <class _T1, class _T2, class... _Args1, class... _Args2>
  342. _LIBCPP_HIDE_FROM_ABI void
  343. construct(pair<_T1, _T2>* __p, piecewise_construct_t, tuple<_Args1...> __x, tuple<_Args2...> __y) {
  344. typedef __outermost<outer_allocator_type> _OM;
  345. allocator_traits<typename _OM::type>::construct(
  346. _OM()(outer_allocator()),
  347. __p,
  348. piecewise_construct,
  349. __transform_tuple(typename __uses_alloc_ctor< _T1, inner_allocator_type&, _Args1... >::type(),
  350. std::move(__x),
  351. typename __make_tuple_indices<sizeof...(_Args1)>::type{}),
  352. __transform_tuple(typename __uses_alloc_ctor< _T2, inner_allocator_type&, _Args2... >::type(),
  353. std::move(__y),
  354. typename __make_tuple_indices<sizeof...(_Args2)>::type{}));
  355. }
  356. template <class _T1, class _T2>
  357. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p) {
  358. construct(__p, piecewise_construct, tuple<>{}, tuple<>{});
  359. }
  360. template <class _T1, class _T2, class _Up, class _Vp>
  361. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
  362. construct(__p,
  363. piecewise_construct,
  364. std::forward_as_tuple(std::forward<_Up>(__x)),
  365. std::forward_as_tuple(std::forward<_Vp>(__y)));
  366. }
  367. template <class _T1, class _T2, class _Up, class _Vp>
  368. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
  369. construct(__p, piecewise_construct, std::forward_as_tuple(__x.first), std::forward_as_tuple(__x.second));
  370. }
  371. template <class _T1, class _T2, class _Up, class _Vp>
  372. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
  373. construct(__p,
  374. piecewise_construct,
  375. std::forward_as_tuple(std::forward<_Up>(__x.first)),
  376. std::forward_as_tuple(std::forward<_Vp>(__x.second)));
  377. }
  378. # endif
  379. template <class _Tp>
  380. _LIBCPP_HIDE_FROM_ABI void destroy(_Tp* __p) {
  381. typedef __outermost<outer_allocator_type> _OM;
  382. allocator_traits<typename _OM::type>::destroy(_OM()(outer_allocator()), __p);
  383. }
  384. _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT {
  385. return _Base::select_on_container_copy_construction();
  386. }
  387. private:
  388. _LIBCPP_HIDE_FROM_ABI explicit scoped_allocator_adaptor(
  389. outer_allocator_type&& __o, inner_allocator_type&& __i) _NOEXCEPT : _Base(std::move(__o), std::move(__i)) {}
  390. template <class _Tp, class... _Args>
  391. _LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 0>, _Tp* __p, _Args&&... __args) {
  392. typedef __outermost<outer_allocator_type> _OM;
  393. allocator_traits<typename _OM::type>::construct(_OM()(outer_allocator()), __p, std::forward<_Args>(__args)...);
  394. }
  395. template <class _Tp, class... _Args>
  396. _LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 1>, _Tp* __p, _Args&&... __args) {
  397. typedef __outermost<outer_allocator_type> _OM;
  398. allocator_traits<typename _OM::type>::construct(
  399. _OM()(outer_allocator()), __p, allocator_arg, inner_allocator(), std::forward<_Args>(__args)...);
  400. }
  401. template <class _Tp, class... _Args>
  402. _LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 2>, _Tp* __p, _Args&&... __args) {
  403. typedef __outermost<outer_allocator_type> _OM;
  404. allocator_traits<typename _OM::type>::construct(
  405. _OM()(outer_allocator()), __p, std::forward<_Args>(__args)..., inner_allocator());
  406. }
  407. template <class... _Args, size_t... _Idx>
  408. _LIBCPP_HIDE_FROM_ABI tuple<_Args&&...>
  409. __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) {
  410. return std::forward_as_tuple(std::get<_Idx>(std::move(__t))...);
  411. }
  412. template <class... _Args, size_t... _Idx>
  413. _LIBCPP_HIDE_FROM_ABI tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
  414. __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) {
  415. using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
  416. return _Tup(allocator_arg, inner_allocator(), std::get<_Idx>(std::move(__t))...);
  417. }
  418. template <class... _Args, size_t... _Idx>
  419. _LIBCPP_HIDE_FROM_ABI tuple<_Args&&..., inner_allocator_type&>
  420. __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) {
  421. using _Tup = tuple<_Args&&..., inner_allocator_type&>;
  422. return _Tup(std::get<_Idx>(std::move(__t))..., inner_allocator());
  423. }
  424. template <class...>
  425. friend class __scoped_allocator_storage;
  426. };
  427. # if _LIBCPP_STD_VER >= 17
  428. template <class _OuterAlloc, class... _InnerAllocs>
  429. scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...) -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
  430. # endif
  431. template <class _OuterA1, class _OuterA2>
  432. inline _LIBCPP_HIDE_FROM_ABI bool
  433. operator==(const scoped_allocator_adaptor<_OuterA1>& __a, const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT {
  434. return __a.outer_allocator() == __b.outer_allocator();
  435. }
  436. template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
  437. inline _LIBCPP_HIDE_FROM_ABI bool
  438. operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
  439. const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT {
  440. return __a.outer_allocator() == __b.outer_allocator() && __a.inner_allocator() == __b.inner_allocator();
  441. }
  442. # if _LIBCPP_STD_VER <= 17
  443. template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
  444. inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
  445. const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT {
  446. return !(__a == __b);
  447. }
  448. # endif // _LIBCPP_STD_VER <= 17
  449. #endif // !defined(_LIBCPP_CXX03_LANG)
  450. _LIBCPP_END_NAMESPACE_STD
  451. _LIBCPP_POP_MACROS
  452. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  453. # include <atomic>
  454. # include <climits>
  455. # include <concepts>
  456. # include <cstring>
  457. # include <ctime>
  458. # include <iterator>
  459. # include <memory>
  460. # include <ratio>
  461. # include <stdexcept>
  462. # include <type_traits>
  463. # include <variant>
  464. #endif
  465. #endif // _LIBCPP_SCOPED_ALLOCATOR