2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_SCOPED_ALLOCATOR
11 #define _LIBCPP_SCOPED_ALLOCATOR
14 scoped_allocator synopsis
19 template <class OuterAlloc, class... InnerAllocs>
20 class scoped_allocator_adaptor : public OuterAlloc
22 typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
23 scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
26 typedef OuterAlloc outer_allocator_type;
27 typedef see below inner_allocator_type;
29 typedef typename OuterTraits::value_type value_type;
30 typedef typename OuterTraits::size_type size_type;
31 typedef typename OuterTraits::difference_type difference_type;
32 typedef typename OuterTraits::pointer pointer;
33 typedef typename OuterTraits::const_pointer const_pointer;
34 typedef typename OuterTraits::void_pointer void_pointer;
35 typedef typename OuterTraits::const_void_pointer const_void_pointer;
37 typedef see below propagate_on_container_copy_assignment;
38 typedef see below propagate_on_container_move_assignment;
39 typedef see below propagate_on_container_swap;
40 typedef see below is_always_equal;
45 typedef scoped_allocator_adaptor<
46 OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
49 scoped_allocator_adaptor();
50 template <class OuterA2>
51 scoped_allocator_adaptor(OuterA2&& outerAlloc,
52 const InnerAllocs&... innerAllocs) noexcept;
53 scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
54 scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
55 template <class OuterA2>
56 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
57 template <class OuterA2>
58 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
60 scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
61 scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
62 ~scoped_allocator_adaptor();
64 inner_allocator_type& inner_allocator() noexcept;
65 const inner_allocator_type& inner_allocator() const noexcept;
67 outer_allocator_type& outer_allocator() noexcept;
68 const outer_allocator_type& outer_allocator() const noexcept;
70 pointer allocate(size_type n); // [[nodiscard]] in C++20
71 pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20
72 void deallocate(pointer p, size_type n) noexcept;
74 size_type max_size() const;
75 template <class T, class... Args> void construct(T* p, Args&& args);
76 template <class T1, class T2, class... Args1, class... Args2>
77 void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
79 template <class T1, class T2>
80 void construct(pair<T1, T2>* p);
81 template <class T1, class T2, class U, class V>
82 void construct(pair<T1, T2>* p, U&& x, V&& y);
83 template <class T1, class T2, class U, class V>
84 void construct(pair<T1, T2>* p, const pair<U, V>& x);
85 template <class T1, class T2, class U, class V>
86 void construct(pair<T1, T2>* p, pair<U, V>&& x);
87 template <class T> void destroy(T* p);
89 template <class T> void destroy(T* p) noexcept;
91 scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
94 template<class OuterAlloc, class... InnerAllocs>
95 scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
96 -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
98 template <class OuterA1, class OuterA2, class... InnerAllocs>
100 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
101 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
103 template <class OuterA1, class OuterA2, class... InnerAllocs>
105 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
106 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; // removed in C++20
112 #include <__assert> // all public C++ headers provide the assertion handler
114 #include <__memory/allocator_traits.h>
115 #include <__memory/uses_allocator_construction.h>
116 #include <__type_traits/common_type.h>
117 #include <__type_traits/enable_if.h>
118 #include <__type_traits/integral_constant.h>
119 #include <__type_traits/is_constructible.h>
120 #include <__type_traits/remove_reference.h>
121 #include <__utility/declval.h>
122 #include <__utility/forward.h>
123 #include <__utility/move.h>
124 #include <__utility/pair.h>
125 #include <__utility/piecewise_construct.h>
129 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
130 # pragma GCC system_header
134 #include <__undef_macros>
136 _LIBCPP_BEGIN_NAMESPACE_STD
138 #if !defined(_LIBCPP_CXX03_LANG)
140 // scoped_allocator_adaptor
142 template <class ..._Allocs>
143 class scoped_allocator_adaptor;
145 template <class ..._Allocs> struct __get_poc_copy_assignment;
148 struct __get_poc_copy_assignment<_A0>
150 static const bool value = allocator_traits<_A0>::
151 propagate_on_container_copy_assignment::value;
154 template <class _A0, class ..._Allocs>
155 struct __get_poc_copy_assignment<_A0, _Allocs...>
157 static const bool value =
158 allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
159 __get_poc_copy_assignment<_Allocs...>::value;
162 template <class ..._Allocs> struct __get_poc_move_assignment;
165 struct __get_poc_move_assignment<_A0>
167 static const bool value = allocator_traits<_A0>::
168 propagate_on_container_move_assignment::value;
171 template <class _A0, class ..._Allocs>
172 struct __get_poc_move_assignment<_A0, _Allocs...>
174 static const bool value =
175 allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
176 __get_poc_move_assignment<_Allocs...>::value;
179 template <class ..._Allocs> struct __get_poc_swap;
182 struct __get_poc_swap<_A0>
184 static const bool value = allocator_traits<_A0>::
185 propagate_on_container_swap::value;
188 template <class _A0, class ..._Allocs>
189 struct __get_poc_swap<_A0, _Allocs...>
191 static const bool value =
192 allocator_traits<_A0>::propagate_on_container_swap::value ||
193 __get_poc_swap<_Allocs...>::value;
196 template <class ..._Allocs> struct __get_is_always_equal;
199 struct __get_is_always_equal<_A0>
201 static const bool value = allocator_traits<_A0>::is_always_equal::value;
204 template <class _A0, class ..._Allocs>
205 struct __get_is_always_equal<_A0, _Allocs...>
207 static const bool value =
208 allocator_traits<_A0>::is_always_equal::value &&
209 __get_is_always_equal<_Allocs...>::value;
212 template <class ..._Allocs>
213 class __scoped_allocator_storage;
215 template <class _OuterAlloc, class... _InnerAllocs>
216 class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
219 typedef _OuterAlloc outer_allocator_type;
221 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
224 inner_allocator_type __inner_;
228 _LIBCPP_INLINE_VISIBILITY
229 __scoped_allocator_storage() _NOEXCEPT {}
231 template <class _OuterA2,
232 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
233 _LIBCPP_INLINE_VISIBILITY
234 __scoped_allocator_storage(_OuterA2&& __outer_alloc,
235 const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
236 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)),
237 __inner_(__inner_allocs...) {}
239 template <class _OuterA2,
240 __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
241 _LIBCPP_INLINE_VISIBILITY
242 __scoped_allocator_storage(
243 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
244 : outer_allocator_type(__other.outer_allocator()),
245 __inner_(__other.inner_allocator()) {}
247 template <class _OuterA2,
248 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
249 _LIBCPP_INLINE_VISIBILITY
250 __scoped_allocator_storage(
251 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
252 : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
253 __inner_(_VSTD::move(__other.inner_allocator())) {}
255 template <class _OuterA2,
256 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
257 _LIBCPP_INLINE_VISIBILITY
258 __scoped_allocator_storage(_OuterA2&& __o,
259 const inner_allocator_type& __i) _NOEXCEPT
260 : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
265 _LIBCPP_INLINE_VISIBILITY
266 inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
267 _LIBCPP_INLINE_VISIBILITY
268 const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
270 _LIBCPP_INLINE_VISIBILITY
271 outer_allocator_type& outer_allocator() _NOEXCEPT
272 {return static_cast<outer_allocator_type&>(*this);}
273 _LIBCPP_INLINE_VISIBILITY
274 const outer_allocator_type& outer_allocator() const _NOEXCEPT
275 {return static_cast<const outer_allocator_type&>(*this);}
277 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
278 _LIBCPP_INLINE_VISIBILITY
279 select_on_container_copy_construction() const _NOEXCEPT
281 return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
283 allocator_traits<outer_allocator_type>::
284 select_on_container_copy_construction(outer_allocator()),
285 allocator_traits<inner_allocator_type>::
286 select_on_container_copy_construction(inner_allocator())
290 template <class...> friend class __scoped_allocator_storage;
293 template <class _OuterAlloc>
294 class __scoped_allocator_storage<_OuterAlloc>
297 typedef _OuterAlloc outer_allocator_type;
299 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
301 _LIBCPP_INLINE_VISIBILITY
302 __scoped_allocator_storage() _NOEXCEPT {}
304 template <class _OuterA2,
305 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
306 _LIBCPP_INLINE_VISIBILITY
307 __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT
308 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)) {}
310 template <class _OuterA2,
311 __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
312 _LIBCPP_INLINE_VISIBILITY
313 __scoped_allocator_storage(
314 const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
315 : outer_allocator_type(__other.outer_allocator()) {}
317 template <class _OuterA2,
318 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
319 _LIBCPP_INLINE_VISIBILITY
320 __scoped_allocator_storage(
321 __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
322 : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
324 _LIBCPP_INLINE_VISIBILITY
325 inner_allocator_type& inner_allocator() _NOEXCEPT
326 {return static_cast<inner_allocator_type&>(*this);}
327 _LIBCPP_INLINE_VISIBILITY
328 const inner_allocator_type& inner_allocator() const _NOEXCEPT
329 {return static_cast<const inner_allocator_type&>(*this);}
331 _LIBCPP_INLINE_VISIBILITY
332 outer_allocator_type& outer_allocator() _NOEXCEPT
333 {return static_cast<outer_allocator_type&>(*this);}
334 _LIBCPP_INLINE_VISIBILITY
335 const outer_allocator_type& outer_allocator() const _NOEXCEPT
336 {return static_cast<const outer_allocator_type&>(*this);}
338 _LIBCPP_INLINE_VISIBILITY
339 scoped_allocator_adaptor<outer_allocator_type>
340 select_on_container_copy_construction() const _NOEXCEPT
341 {return scoped_allocator_adaptor<outer_allocator_type>(
342 allocator_traits<outer_allocator_type>::
343 select_on_container_copy_construction(outer_allocator())
346 __scoped_allocator_storage(const outer_allocator_type& __o,
347 const inner_allocator_type& __i) _NOEXCEPT;
349 template <class...> friend class __scoped_allocator_storage;
354 template <class _Alloc>
355 decltype(std::declval<_Alloc>().outer_allocator(), true_type())
356 __has_outer_allocator_test(_Alloc&& __a);
358 template <class _Alloc>
360 __has_outer_allocator_test(const volatile _Alloc& __a);
362 template <class _Alloc>
363 struct __has_outer_allocator
366 decltype(std::__has_outer_allocator_test(std::declval<_Alloc&>()))
371 template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
375 _LIBCPP_INLINE_VISIBILITY
376 type& operator()(type& __a) const _NOEXCEPT {return __a;}
379 template <class _Alloc>
380 struct __outermost<_Alloc, true>
382 typedef __libcpp_remove_reference_t
384 decltype(std::declval<_Alloc>().outer_allocator())
386 typedef typename __outermost<_OuterAlloc>::type type;
387 _LIBCPP_INLINE_VISIBILITY
388 type& operator()(_Alloc& __a) const _NOEXCEPT
389 {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
392 template <class _OuterAlloc, class... _InnerAllocs>
393 class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
394 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
396 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
397 typedef allocator_traits<_OuterAlloc> _OuterTraits;
399 typedef _OuterAlloc outer_allocator_type;
400 typedef typename base::inner_allocator_type inner_allocator_type;
401 typedef typename _OuterTraits::size_type size_type;
402 typedef typename _OuterTraits::difference_type difference_type;
403 typedef typename _OuterTraits::pointer pointer;
404 typedef typename _OuterTraits::const_pointer const_pointer;
405 typedef typename _OuterTraits::void_pointer void_pointer;
406 typedef typename _OuterTraits::const_void_pointer const_void_pointer;
408 typedef integral_constant
411 __get_poc_copy_assignment<outer_allocator_type,
412 _InnerAllocs...>::value
413 > propagate_on_container_copy_assignment;
414 typedef integral_constant
417 __get_poc_move_assignment<outer_allocator_type,
418 _InnerAllocs...>::value
419 > propagate_on_container_move_assignment;
420 typedef integral_constant
423 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
424 > propagate_on_container_swap;
425 typedef integral_constant
428 __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
434 typedef scoped_allocator_adaptor
436 typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
440 _LIBCPP_INLINE_VISIBILITY
441 scoped_allocator_adaptor() _NOEXCEPT {}
442 template <class _OuterA2,
443 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
444 _LIBCPP_INLINE_VISIBILITY
445 scoped_allocator_adaptor(_OuterA2&& __outer_alloc,
446 const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
447 : base(_VSTD::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
448 // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
449 template <class _OuterA2,
450 __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0>
451 _LIBCPP_INLINE_VISIBILITY
452 scoped_allocator_adaptor(
453 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
455 template <class _OuterA2,
456 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
457 _LIBCPP_INLINE_VISIBILITY
458 scoped_allocator_adaptor(
459 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
460 : base(_VSTD::move(__other)) {}
462 // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
463 // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
464 // ~scoped_allocator_adaptor() = default;
466 _LIBCPP_INLINE_VISIBILITY
467 inner_allocator_type& inner_allocator() _NOEXCEPT
468 {return base::inner_allocator();}
469 _LIBCPP_INLINE_VISIBILITY
470 const inner_allocator_type& inner_allocator() const _NOEXCEPT
471 {return base::inner_allocator();}
473 _LIBCPP_INLINE_VISIBILITY
474 outer_allocator_type& outer_allocator() _NOEXCEPT
475 {return base::outer_allocator();}
476 _LIBCPP_INLINE_VISIBILITY
477 const outer_allocator_type& outer_allocator() const _NOEXCEPT
478 {return base::outer_allocator();}
480 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
481 pointer allocate(size_type __n)
482 {return allocator_traits<outer_allocator_type>::
483 allocate(outer_allocator(), __n);}
484 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
485 pointer allocate(size_type __n, const_void_pointer __hint)
486 {return allocator_traits<outer_allocator_type>::
487 allocate(outer_allocator(), __n, __hint);}
489 _LIBCPP_INLINE_VISIBILITY
490 void deallocate(pointer __p, size_type __n) _NOEXCEPT
491 {allocator_traits<outer_allocator_type>::
492 deallocate(outer_allocator(), __p, __n);}
494 _LIBCPP_INLINE_VISIBILITY
495 size_type max_size() const
496 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
498 #if _LIBCPP_STD_VER >= 20
499 template <class _Type, class... _Args>
500 _LIBCPP_HIDE_FROM_ABI void construct(_Type* __ptr, _Args&&... __args) {
501 using _OM = __outermost<outer_allocator_type>;
503 [__ptr, this](auto&&... __newargs) {
504 allocator_traits<typename _OM::type>::construct(
505 _OM()(outer_allocator()), __ptr, std::forward<decltype(__newargs)>(__newargs)...);
507 std::uses_allocator_construction_args<_Type>(inner_allocator(), std::forward<_Args>(__args)...));
510 template <class _Tp, class... _Args>
511 _LIBCPP_INLINE_VISIBILITY
512 void construct(_Tp* __p, _Args&& ...__args)
513 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
514 __p, _VSTD::forward<_Args>(__args)...);}
516 template <class _T1, class _T2, class... _Args1, class... _Args2>
517 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
518 tuple<_Args1...> __x, tuple<_Args2...> __y)
520 typedef __outermost<outer_allocator_type> _OM;
521 allocator_traits<typename _OM::type>::construct(
522 _OM()(outer_allocator()), __p, piecewise_construct
524 typename __uses_alloc_ctor<
525 _T1, inner_allocator_type&, _Args1...
528 , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
531 typename __uses_alloc_ctor<
532 _T2, inner_allocator_type&, _Args2...
535 , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
540 template <class _T1, class _T2>
541 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p)
542 { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
544 template <class _T1, class _T2, class _Up, class _Vp>
545 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
546 construct(__p, piecewise_construct,
547 _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
548 _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
551 template <class _T1, class _T2, class _Up, class _Vp>
552 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
553 construct(__p, piecewise_construct,
554 _VSTD::forward_as_tuple(__x.first),
555 _VSTD::forward_as_tuple(__x.second));
558 template <class _T1, class _T2, class _Up, class _Vp>
559 _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
560 construct(__p, piecewise_construct,
561 _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
562 _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
567 _LIBCPP_INLINE_VISIBILITY
568 void destroy(_Tp* __p)
570 typedef __outermost<outer_allocator_type> _OM;
571 allocator_traits<typename _OM::type>::
572 destroy(_OM()(outer_allocator()), __p);
575 _LIBCPP_INLINE_VISIBILITY
576 scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
577 {return base::select_on_container_copy_construction();}
582 template <class _OuterA2,
583 __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0>
584 _LIBCPP_INLINE_VISIBILITY
585 scoped_allocator_adaptor(_OuterA2&& __o,
586 const inner_allocator_type& __i) _NOEXCEPT
587 : base(_VSTD::forward<_OuterA2>(__o), __i) {}
589 template <class _Tp, class... _Args>
590 _LIBCPP_INLINE_VISIBILITY
591 void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
593 typedef __outermost<outer_allocator_type> _OM;
594 allocator_traits<typename _OM::type>::construct
596 _OM()(outer_allocator()),
598 _VSTD::forward<_Args>(__args)...
602 template <class _Tp, class... _Args>
603 _LIBCPP_INLINE_VISIBILITY
604 void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
606 typedef __outermost<outer_allocator_type> _OM;
607 allocator_traits<typename _OM::type>::construct
609 _OM()(outer_allocator()),
610 __p, allocator_arg, inner_allocator(),
611 _VSTD::forward<_Args>(__args)...
615 template <class _Tp, class... _Args>
616 _LIBCPP_INLINE_VISIBILITY
617 void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
619 typedef __outermost<outer_allocator_type> _OM;
620 allocator_traits<typename _OM::type>::construct
622 _OM()(outer_allocator()),
624 _VSTD::forward<_Args>(__args)...,
629 template <class ..._Args, size_t ..._Idx>
630 _LIBCPP_INLINE_VISIBILITY
632 __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
633 __tuple_indices<_Idx...>)
635 return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
638 template <class ..._Args, size_t ..._Idx>
639 _LIBCPP_INLINE_VISIBILITY
640 tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
641 __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
642 __tuple_indices<_Idx...>)
644 using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
645 return _Tup(allocator_arg, inner_allocator(),
646 _VSTD::get<_Idx>(_VSTD::move(__t))...);
649 template <class ..._Args, size_t ..._Idx>
650 _LIBCPP_INLINE_VISIBILITY
651 tuple<_Args&&..., inner_allocator_type&>
652 __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
653 __tuple_indices<_Idx...>)
655 using _Tup = tuple<_Args&&..., inner_allocator_type&>;
656 return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
659 template <class...> friend class __scoped_allocator_storage;
662 #if _LIBCPP_STD_VER >= 17
663 template<class _OuterAlloc, class... _InnerAllocs>
664 scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
665 -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
668 template <class _OuterA1, class _OuterA2>
669 inline _LIBCPP_INLINE_VISIBILITY
671 operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
672 const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
674 return __a.outer_allocator() == __b.outer_allocator();
677 template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
678 inline _LIBCPP_INLINE_VISIBILITY
680 operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
681 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
683 return __a.outer_allocator() == __b.outer_allocator() &&
684 __a.inner_allocator() == __b.inner_allocator();
687 #if _LIBCPP_STD_VER <= 17
689 template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
690 inline _LIBCPP_INLINE_VISIBILITY
692 operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
693 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
695 return !(__a == __b);
698 #endif // _LIBCPP_STD_VER <= 17
700 #endif // !defined(_LIBCPP_CXX03_LANG)
702 _LIBCPP_END_NAMESPACE_STD
706 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
715 # include <stdexcept>
716 # include <type_traits>
720 #endif // _LIBCPP_SCOPED_ALLOCATOR