scoped_allocator 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  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;
  88. } // std
  89. */
  90. #include <__config>
  91. #include <__utility/forward.h>
  92. #include <memory>
  93. #include <version>
  94. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  95. # pragma GCC system_header
  96. #endif
  97. _LIBCPP_BEGIN_NAMESPACE_STD
  98. #if !defined(_LIBCPP_CXX03_LANG)
  99. // scoped_allocator_adaptor
  100. template <class ..._Allocs>
  101. class scoped_allocator_adaptor;
  102. template <class ..._Allocs> struct __get_poc_copy_assignment;
  103. template <class _A0>
  104. struct __get_poc_copy_assignment<_A0>
  105. {
  106. static const bool value = allocator_traits<_A0>::
  107. propagate_on_container_copy_assignment::value;
  108. };
  109. template <class _A0, class ..._Allocs>
  110. struct __get_poc_copy_assignment<_A0, _Allocs...>
  111. {
  112. static const bool value =
  113. allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
  114. __get_poc_copy_assignment<_Allocs...>::value;
  115. };
  116. template <class ..._Allocs> struct __get_poc_move_assignment;
  117. template <class _A0>
  118. struct __get_poc_move_assignment<_A0>
  119. {
  120. static const bool value = allocator_traits<_A0>::
  121. propagate_on_container_move_assignment::value;
  122. };
  123. template <class _A0, class ..._Allocs>
  124. struct __get_poc_move_assignment<_A0, _Allocs...>
  125. {
  126. static const bool value =
  127. allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
  128. __get_poc_move_assignment<_Allocs...>::value;
  129. };
  130. template <class ..._Allocs> struct __get_poc_swap;
  131. template <class _A0>
  132. struct __get_poc_swap<_A0>
  133. {
  134. static const bool value = allocator_traits<_A0>::
  135. propagate_on_container_swap::value;
  136. };
  137. template <class _A0, class ..._Allocs>
  138. struct __get_poc_swap<_A0, _Allocs...>
  139. {
  140. static const bool value =
  141. allocator_traits<_A0>::propagate_on_container_swap::value ||
  142. __get_poc_swap<_Allocs...>::value;
  143. };
  144. template <class ..._Allocs> struct __get_is_always_equal;
  145. template <class _A0>
  146. struct __get_is_always_equal<_A0>
  147. {
  148. static const bool value = allocator_traits<_A0>::is_always_equal::value;
  149. };
  150. template <class _A0, class ..._Allocs>
  151. struct __get_is_always_equal<_A0, _Allocs...>
  152. {
  153. static const bool value =
  154. allocator_traits<_A0>::is_always_equal::value &&
  155. __get_is_always_equal<_Allocs...>::value;
  156. };
  157. template <class ..._Allocs>
  158. class __scoped_allocator_storage;
  159. template <class _OuterAlloc, class... _InnerAllocs>
  160. class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
  161. : public _OuterAlloc
  162. {
  163. typedef _OuterAlloc outer_allocator_type;
  164. protected:
  165. typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
  166. private:
  167. inner_allocator_type __inner_;
  168. protected:
  169. _LIBCPP_INLINE_VISIBILITY
  170. __scoped_allocator_storage() _NOEXCEPT {}
  171. template <class _OuterA2,
  172. class = typename enable_if<
  173. is_constructible<outer_allocator_type, _OuterA2>::value
  174. >::type>
  175. _LIBCPP_INLINE_VISIBILITY
  176. __scoped_allocator_storage(_OuterA2&& __outerAlloc,
  177. const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
  178. : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
  179. __inner_(__innerAllocs...) {}
  180. template <class _OuterA2,
  181. class = typename enable_if<
  182. is_constructible<outer_allocator_type, const _OuterA2&>::value
  183. >::type>
  184. _LIBCPP_INLINE_VISIBILITY
  185. __scoped_allocator_storage(
  186. const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  187. : outer_allocator_type(__other.outer_allocator()),
  188. __inner_(__other.inner_allocator()) {}
  189. template <class _OuterA2,
  190. class = typename enable_if<
  191. is_constructible<outer_allocator_type, _OuterA2>::value
  192. >::type>
  193. _LIBCPP_INLINE_VISIBILITY
  194. __scoped_allocator_storage(
  195. __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  196. : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
  197. __inner_(_VSTD::move(__other.inner_allocator())) {}
  198. template <class _OuterA2,
  199. class = typename enable_if<
  200. is_constructible<outer_allocator_type, _OuterA2>::value
  201. >::type>
  202. _LIBCPP_INLINE_VISIBILITY
  203. __scoped_allocator_storage(_OuterA2&& __o,
  204. const inner_allocator_type& __i) _NOEXCEPT
  205. : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
  206. __inner_(__i)
  207. {
  208. }
  209. _LIBCPP_INLINE_VISIBILITY
  210. inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
  211. _LIBCPP_INLINE_VISIBILITY
  212. const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
  213. _LIBCPP_INLINE_VISIBILITY
  214. outer_allocator_type& outer_allocator() _NOEXCEPT
  215. {return static_cast<outer_allocator_type&>(*this);}
  216. _LIBCPP_INLINE_VISIBILITY
  217. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  218. {return static_cast<const outer_allocator_type&>(*this);}
  219. scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
  220. _LIBCPP_INLINE_VISIBILITY
  221. select_on_container_copy_construction() const _NOEXCEPT
  222. {
  223. return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
  224. (
  225. allocator_traits<outer_allocator_type>::
  226. select_on_container_copy_construction(outer_allocator()),
  227. allocator_traits<inner_allocator_type>::
  228. select_on_container_copy_construction(inner_allocator())
  229. );
  230. }
  231. template <class...> friend class __scoped_allocator_storage;
  232. };
  233. template <class _OuterAlloc>
  234. class __scoped_allocator_storage<_OuterAlloc>
  235. : public _OuterAlloc
  236. {
  237. typedef _OuterAlloc outer_allocator_type;
  238. protected:
  239. typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
  240. _LIBCPP_INLINE_VISIBILITY
  241. __scoped_allocator_storage() _NOEXCEPT {}
  242. template <class _OuterA2,
  243. class = typename enable_if<
  244. is_constructible<outer_allocator_type, _OuterA2>::value
  245. >::type>
  246. _LIBCPP_INLINE_VISIBILITY
  247. __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
  248. : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
  249. template <class _OuterA2,
  250. class = typename enable_if<
  251. is_constructible<outer_allocator_type, const _OuterA2&>::value
  252. >::type>
  253. _LIBCPP_INLINE_VISIBILITY
  254. __scoped_allocator_storage(
  255. const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
  256. : outer_allocator_type(__other.outer_allocator()) {}
  257. template <class _OuterA2,
  258. class = typename enable_if<
  259. is_constructible<outer_allocator_type, _OuterA2>::value
  260. >::type>
  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(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(__has_outer_allocator_test(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 typename remove_reference
  314. <
  315. decltype(declval<_Alloc>().outer_allocator())
  316. >::type _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. class = typename enable_if<
  371. is_constructible<outer_allocator_type, _OuterA2>::value
  372. >::type>
  373. _LIBCPP_INLINE_VISIBILITY
  374. scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
  375. const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
  376. : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
  377. // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
  378. template <class _OuterA2,
  379. class = typename enable_if<
  380. is_constructible<outer_allocator_type, const _OuterA2&>::value
  381. >::type>
  382. _LIBCPP_INLINE_VISIBILITY
  383. scoped_allocator_adaptor(
  384. const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  385. : base(__other) {}
  386. template <class _OuterA2,
  387. class = typename enable_if<
  388. is_constructible<outer_allocator_type, _OuterA2>::value
  389. >::type>
  390. _LIBCPP_INLINE_VISIBILITY
  391. scoped_allocator_adaptor(
  392. scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  393. : base(_VSTD::move(__other)) {}
  394. // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
  395. // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
  396. // ~scoped_allocator_adaptor() = default;
  397. _LIBCPP_INLINE_VISIBILITY
  398. inner_allocator_type& inner_allocator() _NOEXCEPT
  399. {return base::inner_allocator();}
  400. _LIBCPP_INLINE_VISIBILITY
  401. const inner_allocator_type& inner_allocator() const _NOEXCEPT
  402. {return base::inner_allocator();}
  403. _LIBCPP_INLINE_VISIBILITY
  404. outer_allocator_type& outer_allocator() _NOEXCEPT
  405. {return base::outer_allocator();}
  406. _LIBCPP_INLINE_VISIBILITY
  407. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  408. {return base::outer_allocator();}
  409. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
  410. pointer allocate(size_type __n)
  411. {return allocator_traits<outer_allocator_type>::
  412. allocate(outer_allocator(), __n);}
  413. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
  414. pointer allocate(size_type __n, const_void_pointer __hint)
  415. {return allocator_traits<outer_allocator_type>::
  416. allocate(outer_allocator(), __n, __hint);}
  417. _LIBCPP_INLINE_VISIBILITY
  418. void deallocate(pointer __p, size_type __n) _NOEXCEPT
  419. {allocator_traits<outer_allocator_type>::
  420. deallocate(outer_allocator(), __p, __n);}
  421. _LIBCPP_INLINE_VISIBILITY
  422. size_type max_size() const
  423. {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
  424. template <class _Tp, class... _Args>
  425. _LIBCPP_INLINE_VISIBILITY
  426. void construct(_Tp* __p, _Args&& ...__args)
  427. {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
  428. __p, _VSTD::forward<_Args>(__args)...);}
  429. template <class _T1, class _T2, class... _Args1, class... _Args2>
  430. void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
  431. tuple<_Args1...> __x, tuple<_Args2...> __y)
  432. {
  433. typedef __outermost<outer_allocator_type> _OM;
  434. allocator_traits<typename _OM::type>::construct(
  435. _OM()(outer_allocator()), __p, piecewise_construct
  436. , __transform_tuple(
  437. typename __uses_alloc_ctor<
  438. _T1, inner_allocator_type&, _Args1...
  439. >::type()
  440. , _VSTD::move(__x)
  441. , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
  442. )
  443. , __transform_tuple(
  444. typename __uses_alloc_ctor<
  445. _T2, inner_allocator_type&, _Args2...
  446. >::type()
  447. , _VSTD::move(__y)
  448. , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
  449. )
  450. );
  451. }
  452. template <class _T1, class _T2>
  453. void construct(pair<_T1, _T2>* __p)
  454. { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
  455. template <class _T1, class _T2, class _Up, class _Vp>
  456. void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
  457. construct(__p, piecewise_construct,
  458. _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
  459. _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
  460. }
  461. template <class _T1, class _T2, class _Up, class _Vp>
  462. void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
  463. construct(__p, piecewise_construct,
  464. _VSTD::forward_as_tuple(__x.first),
  465. _VSTD::forward_as_tuple(__x.second));
  466. }
  467. template <class _T1, class _T2, class _Up, class _Vp>
  468. void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
  469. construct(__p, piecewise_construct,
  470. _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
  471. _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
  472. }
  473. template <class _Tp>
  474. _LIBCPP_INLINE_VISIBILITY
  475. void destroy(_Tp* __p)
  476. {
  477. typedef __outermost<outer_allocator_type> _OM;
  478. allocator_traits<typename _OM::type>::
  479. destroy(_OM()(outer_allocator()), __p);
  480. }
  481. _LIBCPP_INLINE_VISIBILITY
  482. scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
  483. {return base::select_on_container_copy_construction();}
  484. private:
  485. template <class _OuterA2,
  486. class = typename enable_if<
  487. is_constructible<outer_allocator_type, _OuterA2>::value
  488. >::type>
  489. _LIBCPP_INLINE_VISIBILITY
  490. scoped_allocator_adaptor(_OuterA2&& __o,
  491. const inner_allocator_type& __i) _NOEXCEPT
  492. : base(_VSTD::forward<_OuterA2>(__o), __i) {}
  493. template <class _Tp, class... _Args>
  494. _LIBCPP_INLINE_VISIBILITY
  495. void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
  496. {
  497. typedef __outermost<outer_allocator_type> _OM;
  498. allocator_traits<typename _OM::type>::construct
  499. (
  500. _OM()(outer_allocator()),
  501. __p,
  502. _VSTD::forward<_Args>(__args)...
  503. );
  504. }
  505. template <class _Tp, class... _Args>
  506. _LIBCPP_INLINE_VISIBILITY
  507. void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
  508. {
  509. typedef __outermost<outer_allocator_type> _OM;
  510. allocator_traits<typename _OM::type>::construct
  511. (
  512. _OM()(outer_allocator()),
  513. __p, allocator_arg, inner_allocator(),
  514. _VSTD::forward<_Args>(__args)...
  515. );
  516. }
  517. template <class _Tp, class... _Args>
  518. _LIBCPP_INLINE_VISIBILITY
  519. void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
  520. {
  521. typedef __outermost<outer_allocator_type> _OM;
  522. allocator_traits<typename _OM::type>::construct
  523. (
  524. _OM()(outer_allocator()),
  525. __p,
  526. _VSTD::forward<_Args>(__args)...,
  527. inner_allocator()
  528. );
  529. }
  530. template <class ..._Args, size_t ..._Idx>
  531. _LIBCPP_INLINE_VISIBILITY
  532. tuple<_Args&&...>
  533. __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
  534. __tuple_indices<_Idx...>)
  535. {
  536. return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
  537. }
  538. template <class ..._Args, size_t ..._Idx>
  539. _LIBCPP_INLINE_VISIBILITY
  540. tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
  541. __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
  542. __tuple_indices<_Idx...>)
  543. {
  544. using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
  545. return _Tup(allocator_arg, inner_allocator(),
  546. _VSTD::get<_Idx>(_VSTD::move(__t))...);
  547. }
  548. template <class ..._Args, size_t ..._Idx>
  549. _LIBCPP_INLINE_VISIBILITY
  550. tuple<_Args&&..., inner_allocator_type&>
  551. __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
  552. __tuple_indices<_Idx...>)
  553. {
  554. using _Tup = tuple<_Args&&..., inner_allocator_type&>;
  555. return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
  556. }
  557. template <class...> friend class __scoped_allocator_storage;
  558. };
  559. #if _LIBCPP_STD_VER > 14
  560. template<class _OuterAlloc, class... _InnerAllocs>
  561. scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
  562. -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
  563. #endif
  564. template <class _OuterA1, class _OuterA2>
  565. inline _LIBCPP_INLINE_VISIBILITY
  566. bool
  567. operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
  568. const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
  569. {
  570. return __a.outer_allocator() == __b.outer_allocator();
  571. }
  572. template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
  573. inline _LIBCPP_INLINE_VISIBILITY
  574. bool
  575. operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
  576. const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
  577. {
  578. return __a.outer_allocator() == __b.outer_allocator() &&
  579. __a.inner_allocator() == __b.inner_allocator();
  580. }
  581. template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
  582. inline _LIBCPP_INLINE_VISIBILITY
  583. bool
  584. operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
  585. const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
  586. {
  587. return !(__a == __b);
  588. }
  589. #endif // !defined(_LIBCPP_CXX03_LANG)
  590. _LIBCPP_END_NAMESPACE_STD
  591. #endif // _LIBCPP_SCOPED_ALLOCATOR