scoped_allocator 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. // -*- C++ -*-
  2. //===-------------------------- scoped_allocator --------------------------===//
  3. //
  4. // The LLVM Compiler Infrastructure
  5. //
  6. // This file is dual licensed under the MIT and the University of Illinois Open
  7. // Source Licenses. See LICENSE.TXT for details.
  8. //
  9. //===----------------------------------------------------------------------===//
  10. #ifndef _LIBCPP_SCOPED_ALLOCATOR
  11. #define _LIBCPP_SCOPED_ALLOCATOR
  12. /*
  13. scoped_allocator synopsis
  14. namespace std
  15. {
  16. template <class OuterAlloc, class... InnerAllocs>
  17. class scoped_allocator_adaptor : public OuterAlloc
  18. {
  19. typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
  20. scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
  21. public:
  22. typedef OuterAlloc outer_allocator_type;
  23. typedef see below inner_allocator_type;
  24. typedef typename OuterTraits::value_type value_type;
  25. typedef typename OuterTraits::size_type size_type;
  26. typedef typename OuterTraits::difference_type difference_type;
  27. typedef typename OuterTraits::pointer pointer;
  28. typedef typename OuterTraits::const_pointer const_pointer;
  29. typedef typename OuterTraits::void_pointer void_pointer;
  30. typedef typename OuterTraits::const_void_pointer const_void_pointer;
  31. typedef see below propagate_on_container_copy_assignment;
  32. typedef see below propagate_on_container_move_assignment;
  33. typedef see below propagate_on_container_swap;
  34. typedef see below is_always_equal;
  35. template <class Tp>
  36. struct rebind
  37. {
  38. typedef scoped_allocator_adaptor<
  39. OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
  40. };
  41. scoped_allocator_adaptor();
  42. template <class OuterA2>
  43. scoped_allocator_adaptor(OuterA2&& outerAlloc,
  44. const InnerAllocs&... innerAllocs) noexcept;
  45. scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
  46. scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
  47. template <class OuterA2>
  48. scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
  49. template <class OuterA2>
  50. scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
  51. scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
  52. scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
  53. ~scoped_allocator_adaptor();
  54. inner_allocator_type& inner_allocator() noexcept;
  55. const inner_allocator_type& inner_allocator() const noexcept;
  56. outer_allocator_type& outer_allocator() noexcept;
  57. const outer_allocator_type& outer_allocator() const noexcept;
  58. pointer allocate(size_type n);
  59. pointer allocate(size_type n, const_void_pointer hint);
  60. void deallocate(pointer p, size_type n) noexcept;
  61. size_type max_size() const;
  62. template <class T, class... Args> void construct(T* p, Args&& args);
  63. template <class T1, class T2, class... Args1, class... Args2>
  64. void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
  65. tuple<Args2...> y);
  66. template <class T1, class T2>
  67. void construct(pair<T1, T2>* p);
  68. template <class T1, class T2, class U, class V>
  69. void construct(pair<T1, T2>* p, U&& x, V&& y);
  70. template <class T1, class T2, class U, class V>
  71. void construct(pair<T1, T2>* p, const pair<U, V>& x);
  72. template <class T1, class T2, class U, class V>
  73. void construct(pair<T1, T2>* p, pair<U, V>&& x);
  74. template <class T> void destroy(T* p);
  75. template <class T> void destroy(T* p) noexcept;
  76. scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
  77. };
  78. template <class OuterA1, class OuterA2, class... InnerAllocs>
  79. bool
  80. operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
  81. const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  82. template <class OuterA1, class OuterA2, class... InnerAllocs>
  83. bool
  84. operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
  85. const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
  86. } // std
  87. */
  88. #include <__config>
  89. #include <memory>
  90. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  91. #pragma GCC system_header
  92. #endif
  93. _LIBCPP_BEGIN_NAMESPACE_STD
  94. #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
  95. // scoped_allocator_adaptor
  96. template <class ..._Allocs>
  97. class scoped_allocator_adaptor;
  98. template <class ..._Allocs> struct __get_poc_copy_assignment;
  99. template <class _A0>
  100. struct __get_poc_copy_assignment<_A0>
  101. {
  102. static const bool value = allocator_traits<_A0>::
  103. propagate_on_container_copy_assignment::value;
  104. };
  105. template <class _A0, class ..._Allocs>
  106. struct __get_poc_copy_assignment<_A0, _Allocs...>
  107. {
  108. static const bool value =
  109. allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
  110. __get_poc_copy_assignment<_Allocs...>::value;
  111. };
  112. template <class ..._Allocs> struct __get_poc_move_assignment;
  113. template <class _A0>
  114. struct __get_poc_move_assignment<_A0>
  115. {
  116. static const bool value = allocator_traits<_A0>::
  117. propagate_on_container_move_assignment::value;
  118. };
  119. template <class _A0, class ..._Allocs>
  120. struct __get_poc_move_assignment<_A0, _Allocs...>
  121. {
  122. static const bool value =
  123. allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
  124. __get_poc_move_assignment<_Allocs...>::value;
  125. };
  126. template <class ..._Allocs> struct __get_poc_swap;
  127. template <class _A0>
  128. struct __get_poc_swap<_A0>
  129. {
  130. static const bool value = allocator_traits<_A0>::
  131. propagate_on_container_swap::value;
  132. };
  133. template <class _A0, class ..._Allocs>
  134. struct __get_poc_swap<_A0, _Allocs...>
  135. {
  136. static const bool value =
  137. allocator_traits<_A0>::propagate_on_container_swap::value ||
  138. __get_poc_swap<_Allocs...>::value;
  139. };
  140. template <class ..._Allocs> struct __get_is_always_equal;
  141. template <class _A0>
  142. struct __get_is_always_equal<_A0>
  143. {
  144. static const bool value = allocator_traits<_A0>::is_always_equal::value;
  145. };
  146. template <class _A0, class ..._Allocs>
  147. struct __get_is_always_equal<_A0, _Allocs...>
  148. {
  149. static const bool value =
  150. allocator_traits<_A0>::is_always_equal::value &&
  151. __get_is_always_equal<_Allocs...>::value;
  152. };
  153. template <class ..._Allocs>
  154. class __scoped_allocator_storage;
  155. template <class _OuterAlloc, class... _InnerAllocs>
  156. class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
  157. : public _OuterAlloc
  158. {
  159. typedef _OuterAlloc outer_allocator_type;
  160. protected:
  161. typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
  162. private:
  163. inner_allocator_type __inner_;
  164. protected:
  165. _LIBCPP_INLINE_VISIBILITY
  166. __scoped_allocator_storage() _NOEXCEPT {}
  167. template <class _OuterA2,
  168. class = typename enable_if<
  169. is_constructible<outer_allocator_type, _OuterA2>::value
  170. >::type>
  171. _LIBCPP_INLINE_VISIBILITY
  172. __scoped_allocator_storage(_OuterA2&& __outerAlloc,
  173. const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
  174. : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
  175. __inner_(__innerAllocs...) {}
  176. template <class _OuterA2,
  177. class = typename enable_if<
  178. is_constructible<outer_allocator_type, const _OuterA2&>::value
  179. >::type>
  180. _LIBCPP_INLINE_VISIBILITY
  181. __scoped_allocator_storage(
  182. const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
  183. : outer_allocator_type(__other.outer_allocator()),
  184. __inner_(__other.inner_allocator()) {}
  185. template <class _OuterA2,
  186. class = typename enable_if<
  187. is_constructible<outer_allocator_type, _OuterA2>::value
  188. >::type>
  189. _LIBCPP_INLINE_VISIBILITY
  190. __scoped_allocator_storage(
  191. __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  192. : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
  193. __inner_(_VSTD::move(__other.inner_allocator())) {}
  194. template <class _OuterA2,
  195. class = typename enable_if<
  196. is_constructible<outer_allocator_type, _OuterA2>::value
  197. >::type>
  198. _LIBCPP_INLINE_VISIBILITY
  199. __scoped_allocator_storage(_OuterA2&& __o,
  200. const inner_allocator_type& __i) _NOEXCEPT
  201. : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
  202. __inner_(__i)
  203. {
  204. }
  205. _LIBCPP_INLINE_VISIBILITY
  206. inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
  207. _LIBCPP_INLINE_VISIBILITY
  208. const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
  209. _LIBCPP_INLINE_VISIBILITY
  210. outer_allocator_type& outer_allocator() _NOEXCEPT
  211. {return static_cast<outer_allocator_type&>(*this);}
  212. _LIBCPP_INLINE_VISIBILITY
  213. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  214. {return static_cast<const outer_allocator_type&>(*this);}
  215. scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
  216. _LIBCPP_INLINE_VISIBILITY
  217. select_on_container_copy_construction() const _NOEXCEPT
  218. {
  219. return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
  220. (
  221. allocator_traits<outer_allocator_type>::
  222. select_on_container_copy_construction(outer_allocator()),
  223. allocator_traits<inner_allocator_type>::
  224. select_on_container_copy_construction(inner_allocator())
  225. );
  226. }
  227. template <class...> friend class __scoped_allocator_storage;
  228. };
  229. template <class _OuterAlloc>
  230. class __scoped_allocator_storage<_OuterAlloc>
  231. : public _OuterAlloc
  232. {
  233. typedef _OuterAlloc outer_allocator_type;
  234. protected:
  235. typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
  236. _LIBCPP_INLINE_VISIBILITY
  237. __scoped_allocator_storage() _NOEXCEPT {}
  238. template <class _OuterA2,
  239. class = typename enable_if<
  240. is_constructible<outer_allocator_type, _OuterA2>::value
  241. >::type>
  242. _LIBCPP_INLINE_VISIBILITY
  243. __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
  244. : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
  245. template <class _OuterA2,
  246. class = typename enable_if<
  247. is_constructible<outer_allocator_type, const _OuterA2&>::value
  248. >::type>
  249. _LIBCPP_INLINE_VISIBILITY
  250. __scoped_allocator_storage(
  251. const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
  252. : outer_allocator_type(__other.outer_allocator()) {}
  253. template <class _OuterA2,
  254. class = typename enable_if<
  255. is_constructible<outer_allocator_type, _OuterA2>::value
  256. >::type>
  257. _LIBCPP_INLINE_VISIBILITY
  258. __scoped_allocator_storage(
  259. __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
  260. : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
  261. _LIBCPP_INLINE_VISIBILITY
  262. inner_allocator_type& inner_allocator() _NOEXCEPT
  263. {return static_cast<inner_allocator_type&>(*this);}
  264. _LIBCPP_INLINE_VISIBILITY
  265. const inner_allocator_type& inner_allocator() const _NOEXCEPT
  266. {return static_cast<const inner_allocator_type&>(*this);}
  267. _LIBCPP_INLINE_VISIBILITY
  268. outer_allocator_type& outer_allocator() _NOEXCEPT
  269. {return static_cast<outer_allocator_type&>(*this);}
  270. _LIBCPP_INLINE_VISIBILITY
  271. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  272. {return static_cast<const outer_allocator_type&>(*this);}
  273. _LIBCPP_INLINE_VISIBILITY
  274. scoped_allocator_adaptor<outer_allocator_type>
  275. select_on_container_copy_construction() const _NOEXCEPT
  276. {return scoped_allocator_adaptor<outer_allocator_type>(
  277. allocator_traits<outer_allocator_type>::
  278. select_on_container_copy_construction(outer_allocator())
  279. );}
  280. __scoped_allocator_storage(const outer_allocator_type& __o,
  281. const inner_allocator_type& __i) _NOEXCEPT;
  282. template <class...> friend class __scoped_allocator_storage;
  283. };
  284. // __outermost
  285. template <class _Alloc>
  286. decltype(declval<_Alloc>().outer_allocator(), true_type())
  287. __has_outer_allocator_test(_Alloc&& __a);
  288. template <class _Alloc>
  289. false_type
  290. __has_outer_allocator_test(const volatile _Alloc& __a);
  291. template <class _Alloc>
  292. struct __has_outer_allocator
  293. : public common_type
  294. <
  295. decltype(__has_outer_allocator_test(declval<_Alloc&>()))
  296. >::type
  297. {
  298. };
  299. template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
  300. struct __outermost
  301. {
  302. typedef _Alloc type;
  303. _LIBCPP_INLINE_VISIBILITY
  304. type& operator()(type& __a) const _NOEXCEPT {return __a;}
  305. };
  306. template <class _Alloc>
  307. struct __outermost<_Alloc, true>
  308. {
  309. typedef typename remove_reference
  310. <
  311. decltype(_VSTD::declval<_Alloc>().outer_allocator())
  312. >::type _OuterAlloc;
  313. typedef typename __outermost<_OuterAlloc>::type type;
  314. _LIBCPP_INLINE_VISIBILITY
  315. type& operator()(_Alloc& __a) const _NOEXCEPT
  316. {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
  317. };
  318. template <class _OuterAlloc, class... _InnerAllocs>
  319. class _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
  320. : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
  321. {
  322. typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
  323. typedef allocator_traits<_OuterAlloc> _OuterTraits;
  324. public:
  325. typedef _OuterAlloc outer_allocator_type;
  326. typedef typename base::inner_allocator_type inner_allocator_type;
  327. typedef typename _OuterTraits::size_type size_type;
  328. typedef typename _OuterTraits::difference_type difference_type;
  329. typedef typename _OuterTraits::pointer pointer;
  330. typedef typename _OuterTraits::const_pointer const_pointer;
  331. typedef typename _OuterTraits::void_pointer void_pointer;
  332. typedef typename _OuterTraits::const_void_pointer const_void_pointer;
  333. typedef integral_constant
  334. <
  335. bool,
  336. __get_poc_copy_assignment<outer_allocator_type,
  337. _InnerAllocs...>::value
  338. > propagate_on_container_copy_assignment;
  339. typedef integral_constant
  340. <
  341. bool,
  342. __get_poc_move_assignment<outer_allocator_type,
  343. _InnerAllocs...>::value
  344. > propagate_on_container_move_assignment;
  345. typedef integral_constant
  346. <
  347. bool,
  348. __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
  349. > propagate_on_container_swap;
  350. typedef integral_constant
  351. <
  352. bool,
  353. __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
  354. > is_always_equal;
  355. template <class _Tp>
  356. struct rebind
  357. {
  358. typedef scoped_allocator_adaptor
  359. <
  360. typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
  361. > other;
  362. };
  363. _LIBCPP_INLINE_VISIBILITY
  364. scoped_allocator_adaptor() _NOEXCEPT {}
  365. template <class _OuterA2,
  366. class = typename enable_if<
  367. is_constructible<outer_allocator_type, _OuterA2>::value
  368. >::type>
  369. _LIBCPP_INLINE_VISIBILITY
  370. scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
  371. const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
  372. : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
  373. // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
  374. template <class _OuterA2,
  375. class = typename enable_if<
  376. is_constructible<outer_allocator_type, const _OuterA2&>::value
  377. >::type>
  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. class = typename enable_if<
  384. is_constructible<outer_allocator_type, _OuterA2>::value
  385. >::type>
  386. _LIBCPP_INLINE_VISIBILITY
  387. scoped_allocator_adaptor(
  388. scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
  389. : base(_VSTD::move(__other)) {}
  390. // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
  391. // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
  392. // ~scoped_allocator_adaptor() = default;
  393. _LIBCPP_INLINE_VISIBILITY
  394. inner_allocator_type& inner_allocator() _NOEXCEPT
  395. {return base::inner_allocator();}
  396. _LIBCPP_INLINE_VISIBILITY
  397. const inner_allocator_type& inner_allocator() const _NOEXCEPT
  398. {return base::inner_allocator();}
  399. _LIBCPP_INLINE_VISIBILITY
  400. outer_allocator_type& outer_allocator() _NOEXCEPT
  401. {return base::outer_allocator();}
  402. _LIBCPP_INLINE_VISIBILITY
  403. const outer_allocator_type& outer_allocator() const _NOEXCEPT
  404. {return base::outer_allocator();}
  405. _LIBCPP_INLINE_VISIBILITY
  406. pointer allocate(size_type __n)
  407. {return allocator_traits<outer_allocator_type>::
  408. allocate(outer_allocator(), __n);}
  409. _LIBCPP_INLINE_VISIBILITY
  410. pointer allocate(size_type __n, const_void_pointer __hint)
  411. {return allocator_traits<outer_allocator_type>::
  412. allocate(outer_allocator(), __n, __hint);}
  413. _LIBCPP_INLINE_VISIBILITY
  414. void deallocate(pointer __p, size_type __n) _NOEXCEPT
  415. {allocator_traits<outer_allocator_type>::
  416. deallocate(outer_allocator(), __p, __n);}
  417. _LIBCPP_INLINE_VISIBILITY
  418. size_type max_size() const
  419. {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
  420. template <class _Tp, class... _Args>
  421. _LIBCPP_INLINE_VISIBILITY
  422. void construct(_Tp* __p, _Args&& ...__args)
  423. {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
  424. __p, _VSTD::forward<_Args>(__args)...);}
  425. template <class _Tp>
  426. _LIBCPP_INLINE_VISIBILITY
  427. void destroy(_Tp* __p)
  428. {
  429. typedef __outermost<outer_allocator_type> _OM;
  430. allocator_traits<typename _OM::type>::
  431. destroy(_OM()(outer_allocator()), __p);
  432. }
  433. _LIBCPP_INLINE_VISIBILITY
  434. scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
  435. {return base::select_on_container_copy_construction();}
  436. private:
  437. template <class _OuterA2,
  438. class = typename enable_if<
  439. is_constructible<outer_allocator_type, _OuterA2>::value
  440. >::type>
  441. _LIBCPP_INLINE_VISIBILITY
  442. scoped_allocator_adaptor(_OuterA2&& __o,
  443. const inner_allocator_type& __i) _NOEXCEPT
  444. : base(_VSTD::forward<_OuterA2>(__o), __i) {}
  445. template <class _Tp, class... _Args>
  446. _LIBCPP_INLINE_VISIBILITY
  447. void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
  448. {
  449. typedef __outermost<outer_allocator_type> _OM;
  450. allocator_traits<typename _OM::type>::construct
  451. (
  452. _OM()(outer_allocator()),
  453. __p,
  454. _VSTD::forward<_Args>(__args)...
  455. );
  456. }
  457. template <class _Tp, class... _Args>
  458. _LIBCPP_INLINE_VISIBILITY
  459. void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
  460. {
  461. typedef __outermost<outer_allocator_type> _OM;
  462. allocator_traits<typename _OM::type>::construct
  463. (
  464. _OM()(outer_allocator()),
  465. __p,
  466. allocator_arg,
  467. inner_allocator(),
  468. _VSTD::forward<_Args>(__args)...
  469. );
  470. }
  471. template <class _Tp, class... _Args>
  472. _LIBCPP_INLINE_VISIBILITY
  473. void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
  474. {
  475. typedef __outermost<outer_allocator_type> _OM;
  476. allocator_traits<typename _OM::type>::construct
  477. (
  478. _OM()(outer_allocator()),
  479. __p,
  480. _VSTD::forward<_Args>(__args)...,
  481. inner_allocator()
  482. );
  483. }
  484. template <class...> friend class __scoped_allocator_storage;
  485. };
  486. template <class _OuterA1, class _OuterA2>
  487. inline _LIBCPP_INLINE_VISIBILITY
  488. bool
  489. operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
  490. const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
  491. {
  492. return __a.outer_allocator() == __b.outer_allocator();
  493. }
  494. template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
  495. inline _LIBCPP_INLINE_VISIBILITY
  496. bool
  497. operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
  498. const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
  499. {
  500. return __a.outer_allocator() == __b.outer_allocator() &&
  501. __a.inner_allocator() == __b.inner_allocator();
  502. }
  503. template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
  504. inline _LIBCPP_INLINE_VISIBILITY
  505. bool
  506. operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
  507. const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
  508. {
  509. return !(__a == __b);
  510. }
  511. #endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
  512. _LIBCPP_END_NAMESPACE_STD
  513. #endif // _LIBCPP_SCOPED_ALLOCATOR