scoped_allocator 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  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 <__assert> // all public C++ headers provide the assertion handler
  91. #include <__config>
  92. #include <__memory/allocator_traits.h>
  93. #include <__memory/uses_allocator_construction.h>
  94. #include <__type_traits/common_type.h>
  95. #include <__type_traits/enable_if.h>
  96. #include <__type_traits/integral_constant.h>
  97. #include <__type_traits/is_constructible.h>
  98. #include <__type_traits/remove_reference.h>
  99. #include <__utility/declval.h>
  100. #include <__utility/forward.h>
  101. #include <__utility/move.h>
  102. #include <__utility/pair.h>
  103. #include <__utility/piecewise_construct.h>
  104. #include <tuple>
  105. #include <version>
  106. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  107. # pragma GCC system_header
  108. #endif
  109. _LIBCPP_PUSH_MACROS
  110. #include <__undef_macros>
  111. _LIBCPP_BEGIN_NAMESPACE_STD
  112. #if !defined(_LIBCPP_CXX03_LANG)
  113. // scoped_allocator_adaptor
  114. template <class ..._Allocs>
  115. class scoped_allocator_adaptor;
  116. template <class ..._Allocs> struct __get_poc_copy_assignment;
  117. template <class _A0>
  118. struct __get_poc_copy_assignment<_A0>
  119. {
  120. static const bool value = allocator_traits<_A0>::
  121. propagate_on_container_copy_assignment::value;
  122. };
  123. template <class _A0, class ..._Allocs>
  124. struct __get_poc_copy_assignment<_A0, _Allocs...>
  125. {
  126. static const bool value =
  127. allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
  128. __get_poc_copy_assignment<_Allocs...>::value;
  129. };
  130. template <class ..._Allocs> struct __get_poc_move_assignment;
  131. template <class _A0>
  132. struct __get_poc_move_assignment<_A0>
  133. {
  134. static const bool value = allocator_traits<_A0>::
  135. propagate_on_container_move_assignment::value;
  136. };
  137. template <class _A0, class ..._Allocs>
  138. struct __get_poc_move_assignment<_A0, _Allocs...>
  139. {
  140. static const bool value =
  141. allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
  142. __get_poc_move_assignment<_Allocs...>::value;
  143. };
  144. template <class ..._Allocs> struct __get_poc_swap;
  145. template <class _A0>
  146. struct __get_poc_swap<_A0>
  147. {
  148. static const bool value = allocator_traits<_A0>::
  149. propagate_on_container_swap::value;
  150. };
  151. template <class _A0, class ..._Allocs>
  152. struct __get_poc_swap<_A0, _Allocs...>
  153. {
  154. static const bool value =
  155. allocator_traits<_A0>::propagate_on_container_swap::value ||
  156. __get_poc_swap<_Allocs...>::value;
  157. };
  158. template <class ..._Allocs> struct __get_is_always_equal;
  159. template <class _A0>
  160. struct __get_is_always_equal<_A0>
  161. {
  162. static const bool value = allocator_traits<_A0>::is_always_equal::value;
  163. };
  164. template <class _A0, class ..._Allocs>
  165. struct __get_is_always_equal<_A0, _Allocs...>
  166. {
  167. static const bool value =
  168. allocator_traits<_A0>::is_always_equal::value &&
  169. __get_is_always_equal<_Allocs...>::value;
  170. };
  171. template <class ..._Allocs>
  172. class __scoped_allocator_storage;
  173. template <class _OuterAlloc, class... _InnerAllocs>
  174. class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
  175. : public _OuterAlloc
  176. {
  177. typedef _OuterAlloc outer_allocator_type;
  178. protected:
  179. typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
  180. private:
  181. inner_allocator_type __inner_;
  182. protected:
  183. _LIBCPP_INLINE_VISIBILITY
  184. __scoped_allocator_storage() _NOEXCEPT {}
  185. template <class _OuterA2,
  186. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  187. _LIBCPP_INLINE_VISIBILITY
  188. __scoped_allocator_storage(_OuterA2&& __outer_alloc,
  189. const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
  190. : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)),
  191. __inner_(__inner_allocs...) {}
  192. template <class _OuterA2,
  193. __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
  194. _LIBCPP_INLINE_VISIBILITY
  195. __scoped_allocator_storage(
  196. const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  197. : outer_allocator_type(__other.outer_allocator()),
  198. __inner_(__other.inner_allocator()) {}
  199. template <class _OuterA2,
  200. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  201. _LIBCPP_INLINE_VISIBILITY
  202. __scoped_allocator_storage(
  203. __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  204. : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
  205. __inner_(_VSTD::move(__other.inner_allocator())) {}
  206. template <class _OuterA2,
  207. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  208. _LIBCPP_INLINE_VISIBILITY
  209. __scoped_allocator_storage(_OuterA2&& __o,
  210. const inner_allocator_type& __i) _NOEXCEPT
  211. : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
  212. __inner_(__i)
  213. {
  214. }
  215. _LIBCPP_INLINE_VISIBILITY
  216. inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
  217. _LIBCPP_INLINE_VISIBILITY
  218. const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
  219. _LIBCPP_INLINE_VISIBILITY
  220. outer_allocator_type& outer_allocator() _NOEXCEPT
  221. {return static_cast<outer_allocator_type&>(*this);}
  222. _LIBCPP_INLINE_VISIBILITY
  223. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  224. {return static_cast<const outer_allocator_type&>(*this);}
  225. scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
  226. _LIBCPP_INLINE_VISIBILITY
  227. select_on_container_copy_construction() const _NOEXCEPT
  228. {
  229. return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
  230. (
  231. allocator_traits<outer_allocator_type>::
  232. select_on_container_copy_construction(outer_allocator()),
  233. allocator_traits<inner_allocator_type>::
  234. select_on_container_copy_construction(inner_allocator())
  235. );
  236. }
  237. template <class...> friend class __scoped_allocator_storage;
  238. };
  239. template <class _OuterAlloc>
  240. class __scoped_allocator_storage<_OuterAlloc>
  241. : public _OuterAlloc
  242. {
  243. typedef _OuterAlloc outer_allocator_type;
  244. protected:
  245. typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
  246. _LIBCPP_INLINE_VISIBILITY
  247. __scoped_allocator_storage() _NOEXCEPT {}
  248. template <class _OuterA2,
  249. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  250. _LIBCPP_INLINE_VISIBILITY
  251. __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT
  252. : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)) {}
  253. template <class _OuterA2,
  254. __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
  255. _LIBCPP_INLINE_VISIBILITY
  256. __scoped_allocator_storage(
  257. const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
  258. : outer_allocator_type(__other.outer_allocator()) {}
  259. template <class _OuterA2,
  260. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  261. _LIBCPP_INLINE_VISIBILITY
  262. __scoped_allocator_storage(
  263. __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
  264. : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
  265. _LIBCPP_INLINE_VISIBILITY
  266. inner_allocator_type& inner_allocator() _NOEXCEPT
  267. {return static_cast<inner_allocator_type&>(*this);}
  268. _LIBCPP_INLINE_VISIBILITY
  269. const inner_allocator_type& inner_allocator() const _NOEXCEPT
  270. {return static_cast<const inner_allocator_type&>(*this);}
  271. _LIBCPP_INLINE_VISIBILITY
  272. outer_allocator_type& outer_allocator() _NOEXCEPT
  273. {return static_cast<outer_allocator_type&>(*this);}
  274. _LIBCPP_INLINE_VISIBILITY
  275. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  276. {return static_cast<const outer_allocator_type&>(*this);}
  277. _LIBCPP_INLINE_VISIBILITY
  278. scoped_allocator_adaptor<outer_allocator_type>
  279. select_on_container_copy_construction() const _NOEXCEPT
  280. {return scoped_allocator_adaptor<outer_allocator_type>(
  281. allocator_traits<outer_allocator_type>::
  282. select_on_container_copy_construction(outer_allocator())
  283. );}
  284. __scoped_allocator_storage(const outer_allocator_type& __o,
  285. const inner_allocator_type& __i) _NOEXCEPT;
  286. template <class...> friend class __scoped_allocator_storage;
  287. };
  288. // __outermost
  289. template <class _Alloc>
  290. decltype(std::declval<_Alloc>().outer_allocator(), true_type())
  291. __has_outer_allocator_test(_Alloc&& __a);
  292. template <class _Alloc>
  293. false_type
  294. __has_outer_allocator_test(const volatile _Alloc& __a);
  295. template <class _Alloc>
  296. struct __has_outer_allocator
  297. : public common_type
  298. <
  299. decltype(std::__has_outer_allocator_test(std::declval<_Alloc&>()))
  300. >::type
  301. {
  302. };
  303. template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
  304. struct __outermost
  305. {
  306. typedef _Alloc type;
  307. _LIBCPP_INLINE_VISIBILITY
  308. type& operator()(type& __a) const _NOEXCEPT {return __a;}
  309. };
  310. template <class _Alloc>
  311. struct __outermost<_Alloc, true>
  312. {
  313. typedef __libcpp_remove_reference_t
  314. <
  315. decltype(std::declval<_Alloc>().outer_allocator())
  316. > _OuterAlloc;
  317. typedef typename __outermost<_OuterAlloc>::type type;
  318. _LIBCPP_INLINE_VISIBILITY
  319. type& operator()(_Alloc& __a) const _NOEXCEPT
  320. {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
  321. };
  322. template <class _OuterAlloc, class... _InnerAllocs>
  323. class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
  324. : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
  325. {
  326. typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
  327. typedef allocator_traits<_OuterAlloc> _OuterTraits;
  328. public:
  329. typedef _OuterAlloc outer_allocator_type;
  330. typedef typename base::inner_allocator_type inner_allocator_type;
  331. typedef typename _OuterTraits::size_type size_type;
  332. typedef typename _OuterTraits::difference_type difference_type;
  333. typedef typename _OuterTraits::pointer pointer;
  334. typedef typename _OuterTraits::const_pointer const_pointer;
  335. typedef typename _OuterTraits::void_pointer void_pointer;
  336. typedef typename _OuterTraits::const_void_pointer const_void_pointer;
  337. typedef integral_constant
  338. <
  339. bool,
  340. __get_poc_copy_assignment<outer_allocator_type,
  341. _InnerAllocs...>::value
  342. > propagate_on_container_copy_assignment;
  343. typedef integral_constant
  344. <
  345. bool,
  346. __get_poc_move_assignment<outer_allocator_type,
  347. _InnerAllocs...>::value
  348. > propagate_on_container_move_assignment;
  349. typedef integral_constant
  350. <
  351. bool,
  352. __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
  353. > propagate_on_container_swap;
  354. typedef integral_constant
  355. <
  356. bool,
  357. __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
  358. > is_always_equal;
  359. template <class _Tp>
  360. struct rebind
  361. {
  362. typedef scoped_allocator_adaptor
  363. <
  364. typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
  365. > other;
  366. };
  367. _LIBCPP_INLINE_VISIBILITY
  368. scoped_allocator_adaptor() _NOEXCEPT {}
  369. template <class _OuterA2,
  370. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  371. _LIBCPP_INLINE_VISIBILITY
  372. scoped_allocator_adaptor(_OuterA2&& __outer_alloc,
  373. const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
  374. : base(_VSTD::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
  375. // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
  376. template <class _OuterA2,
  377. __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
  378. _LIBCPP_INLINE_VISIBILITY
  379. scoped_allocator_adaptor(
  380. const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  381. : base(__other) {}
  382. template <class _OuterA2,
  383. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  384. _LIBCPP_INLINE_VISIBILITY
  385. scoped_allocator_adaptor(
  386. scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  387. : base(_VSTD::move(__other)) {}
  388. // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
  389. // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
  390. // ~scoped_allocator_adaptor() = default;
  391. _LIBCPP_INLINE_VISIBILITY
  392. inner_allocator_type& inner_allocator() _NOEXCEPT
  393. {return base::inner_allocator();}
  394. _LIBCPP_INLINE_VISIBILITY
  395. const inner_allocator_type& inner_allocator() const _NOEXCEPT
  396. {return base::inner_allocator();}
  397. _LIBCPP_INLINE_VISIBILITY
  398. outer_allocator_type& outer_allocator() _NOEXCEPT
  399. {return base::outer_allocator();}
  400. _LIBCPP_INLINE_VISIBILITY
  401. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  402. {return base::outer_allocator();}
  403. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
  404. pointer allocate(size_type __n)
  405. {return allocator_traits<outer_allocator_type>::
  406. allocate(outer_allocator(), __n);}
  407. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
  408. pointer allocate(size_type __n, const_void_pointer __hint)
  409. {return allocator_traits<outer_allocator_type>::
  410. allocate(outer_allocator(), __n, __hint);}
  411. _LIBCPP_INLINE_VISIBILITY
  412. void deallocate(pointer __p, size_type __n) _NOEXCEPT
  413. {allocator_traits<outer_allocator_type>::
  414. deallocate(outer_allocator(), __p, __n);}
  415. _LIBCPP_INLINE_VISIBILITY
  416. size_type max_size() const
  417. {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
  418. #if _LIBCPP_STD_VER >= 20
  419. template <class _Type, class... _Args>
  420. _LIBCPP_HIDE_FROM_ABI void construct(_Type* __ptr, _Args&&... __args) {
  421. using _OM = __outermost<outer_allocator_type>;
  422. std::apply(
  423. [__ptr, this](auto&&... __newargs) {
  424. allocator_traits<typename _OM::type>::construct(
  425. _OM()(outer_allocator()), __ptr, std::forward<decltype(__newargs)>(__newargs)...);
  426. },
  427. std::uses_allocator_construction_args<_Type>(inner_allocator(), std::forward<_Args>(__args)...));
  428. }
  429. #else
  430. template <class _Tp, class... _Args>
  431. _LIBCPP_INLINE_VISIBILITY
  432. void construct(_Tp* __p, _Args&& ...__args)
  433. {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
  434. __p, _VSTD::forward<_Args>(__args)...);}
  435. template <class _T1, class _T2, class... _Args1, class... _Args2>
  436. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
  437. tuple<_Args1...> __x, tuple<_Args2...> __y)
  438. {
  439. typedef __outermost<outer_allocator_type> _OM;
  440. allocator_traits<typename _OM::type>::construct(
  441. _OM()(outer_allocator()), __p, piecewise_construct
  442. , __transform_tuple(
  443. typename __uses_alloc_ctor<
  444. _T1, inner_allocator_type&, _Args1...
  445. >::type()
  446. , _VSTD::move(__x)
  447. , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
  448. )
  449. , __transform_tuple(
  450. typename __uses_alloc_ctor<
  451. _T2, inner_allocator_type&, _Args2...
  452. >::type()
  453. , _VSTD::move(__y)
  454. , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
  455. )
  456. );
  457. }
  458. template <class _T1, class _T2>
  459. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p)
  460. { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
  461. template <class _T1, class _T2, class _Up, class _Vp>
  462. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
  463. construct(__p, piecewise_construct,
  464. _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
  465. _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
  466. }
  467. template <class _T1, class _T2, class _Up, class _Vp>
  468. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
  469. construct(__p, piecewise_construct,
  470. _VSTD::forward_as_tuple(__x.first),
  471. _VSTD::forward_as_tuple(__x.second));
  472. }
  473. template <class _T1, class _T2, class _Up, class _Vp>
  474. _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
  475. construct(__p, piecewise_construct,
  476. _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
  477. _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
  478. }
  479. #endif
  480. template <class _Tp>
  481. _LIBCPP_INLINE_VISIBILITY
  482. void destroy(_Tp* __p)
  483. {
  484. typedef __outermost<outer_allocator_type> _OM;
  485. allocator_traits<typename _OM::type>::
  486. destroy(_OM()(outer_allocator()), __p);
  487. }
  488. _LIBCPP_INLINE_VISIBILITY
  489. scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
  490. {return base::select_on_container_copy_construction();}
  491. private:
  492. template <class _OuterA2,
  493. __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
  494. _LIBCPP_INLINE_VISIBILITY
  495. scoped_allocator_adaptor(_OuterA2&& __o,
  496. const inner_allocator_type& __i) _NOEXCEPT
  497. : base(_VSTD::forward<_OuterA2>(__o), __i) {}
  498. template <class _Tp, class... _Args>
  499. _LIBCPP_INLINE_VISIBILITY
  500. void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
  501. {
  502. typedef __outermost<outer_allocator_type> _OM;
  503. allocator_traits<typename _OM::type>::construct
  504. (
  505. _OM()(outer_allocator()),
  506. __p,
  507. _VSTD::forward<_Args>(__args)...
  508. );
  509. }
  510. template <class _Tp, class... _Args>
  511. _LIBCPP_INLINE_VISIBILITY
  512. void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
  513. {
  514. typedef __outermost<outer_allocator_type> _OM;
  515. allocator_traits<typename _OM::type>::construct
  516. (
  517. _OM()(outer_allocator()),
  518. __p, allocator_arg, inner_allocator(),
  519. _VSTD::forward<_Args>(__args)...
  520. );
  521. }
  522. template <class _Tp, class... _Args>
  523. _LIBCPP_INLINE_VISIBILITY
  524. void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
  525. {
  526. typedef __outermost<outer_allocator_type> _OM;
  527. allocator_traits<typename _OM::type>::construct
  528. (
  529. _OM()(outer_allocator()),
  530. __p,
  531. _VSTD::forward<_Args>(__args)...,
  532. inner_allocator()
  533. );
  534. }
  535. template <class ..._Args, size_t ..._Idx>
  536. _LIBCPP_INLINE_VISIBILITY
  537. tuple<_Args&&...>
  538. __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
  539. __tuple_indices<_Idx...>)
  540. {
  541. return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
  542. }
  543. template <class ..._Args, size_t ..._Idx>
  544. _LIBCPP_INLINE_VISIBILITY
  545. tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
  546. __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
  547. __tuple_indices<_Idx...>)
  548. {
  549. using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
  550. return _Tup(allocator_arg, inner_allocator(),
  551. _VSTD::get<_Idx>(_VSTD::move(__t))...);
  552. }
  553. template <class ..._Args, size_t ..._Idx>
  554. _LIBCPP_INLINE_VISIBILITY
  555. tuple<_Args&&..., inner_allocator_type&>
  556. __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
  557. __tuple_indices<_Idx...>)
  558. {
  559. using _Tup = tuple<_Args&&..., inner_allocator_type&>;
  560. return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
  561. }
  562. template <class...> friend class __scoped_allocator_storage;
  563. };
  564. #if _LIBCPP_STD_VER >= 17
  565. template<class _OuterAlloc, class... _InnerAllocs>
  566. scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
  567. -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
  568. #endif
  569. template <class _OuterA1, class _OuterA2>
  570. inline _LIBCPP_INLINE_VISIBILITY
  571. bool
  572. operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
  573. const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
  574. {
  575. return __a.outer_allocator() == __b.outer_allocator();
  576. }
  577. template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
  578. inline _LIBCPP_INLINE_VISIBILITY
  579. bool
  580. operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
  581. const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
  582. {
  583. return __a.outer_allocator() == __b.outer_allocator() &&
  584. __a.inner_allocator() == __b.inner_allocator();
  585. }
  586. #if _LIBCPP_STD_VER <= 17
  587. template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
  588. inline _LIBCPP_INLINE_VISIBILITY
  589. bool
  590. operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
  591. const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
  592. {
  593. return !(__a == __b);
  594. }
  595. #endif // _LIBCPP_STD_VER <= 17
  596. #endif // !defined(_LIBCPP_CXX03_LANG)
  597. _LIBCPP_END_NAMESPACE_STD
  598. _LIBCPP_POP_MACROS
  599. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  600. # include <atomic>
  601. # include <climits>
  602. # include <concepts>
  603. # include <cstring>
  604. # include <ctime>
  605. # include <iterator>
  606. # include <memory>
  607. # include <ratio>
  608. # include <stdexcept>
  609. # include <type_traits>
  610. # include <variant>
  611. #endif
  612. #endif // _LIBCPP_SCOPED_ALLOCATOR