[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / libcxx / include / scoped_allocator
blob2b15655e2c0ad096b0f529b9affa54f4e56c1416
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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_SCOPED_ALLOCATOR
11 #define _LIBCPP_SCOPED_ALLOCATOR
14     scoped_allocator synopsis
16 namespace std
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
24 public:
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;
42     template <class Tp>
43         struct rebind
44         {
45             typedef scoped_allocator_adaptor<
46                 OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
47         };
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,
78                        tuple<Args2...> y);
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>
99     bool
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>
104     bool
105     operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
106                const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
108 }  // std
112 #include <__config>
113 #include <__utility/forward.h>
114 #include <memory>
115 #include <version>
117 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
118 #pragma GCC system_header
119 #endif
121 _LIBCPP_BEGIN_NAMESPACE_STD
123 #if !defined(_LIBCPP_CXX03_LANG)
125 // scoped_allocator_adaptor
127 template <class ..._Allocs>
128 class scoped_allocator_adaptor;
130 template <class ..._Allocs> struct __get_poc_copy_assignment;
132 template <class _A0>
133 struct __get_poc_copy_assignment<_A0>
135     static const bool value = allocator_traits<_A0>::
136                               propagate_on_container_copy_assignment::value;
139 template <class _A0, class ..._Allocs>
140 struct __get_poc_copy_assignment<_A0, _Allocs...>
142     static const bool value =
143         allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
144         __get_poc_copy_assignment<_Allocs...>::value;
147 template <class ..._Allocs> struct __get_poc_move_assignment;
149 template <class _A0>
150 struct __get_poc_move_assignment<_A0>
152     static const bool value = allocator_traits<_A0>::
153                               propagate_on_container_move_assignment::value;
156 template <class _A0, class ..._Allocs>
157 struct __get_poc_move_assignment<_A0, _Allocs...>
159     static const bool value =
160         allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
161         __get_poc_move_assignment<_Allocs...>::value;
164 template <class ..._Allocs> struct __get_poc_swap;
166 template <class _A0>
167 struct __get_poc_swap<_A0>
169     static const bool value = allocator_traits<_A0>::
170                               propagate_on_container_swap::value;
173 template <class _A0, class ..._Allocs>
174 struct __get_poc_swap<_A0, _Allocs...>
176     static const bool value =
177         allocator_traits<_A0>::propagate_on_container_swap::value ||
178         __get_poc_swap<_Allocs...>::value;
181 template <class ..._Allocs> struct __get_is_always_equal;
183 template <class _A0>
184 struct __get_is_always_equal<_A0>
186     static const bool value = allocator_traits<_A0>::is_always_equal::value;
189 template <class _A0, class ..._Allocs>
190 struct __get_is_always_equal<_A0, _Allocs...>
192     static const bool value =
193         allocator_traits<_A0>::is_always_equal::value &&
194         __get_is_always_equal<_Allocs...>::value;
197 template <class ..._Allocs>
198 class __scoped_allocator_storage;
200 template <class _OuterAlloc, class... _InnerAllocs>
201 class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
202     : public _OuterAlloc
204     typedef _OuterAlloc outer_allocator_type;
205 protected:
206     typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
208 private:
209     inner_allocator_type __inner_;
211 protected:
213     _LIBCPP_INLINE_VISIBILITY
214     __scoped_allocator_storage() _NOEXCEPT {}
216     template <class _OuterA2,
217               class = typename enable_if<
218                         is_constructible<outer_allocator_type, _OuterA2>::value
219                       >::type>
220         _LIBCPP_INLINE_VISIBILITY
221         __scoped_allocator_storage(_OuterA2&& __outerAlloc,
222                                    const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
223             : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
224               __inner_(__innerAllocs...) {}
226     template <class _OuterA2,
227               class = typename enable_if<
228                         is_constructible<outer_allocator_type, const _OuterA2&>::value
229                       >::type>
230         _LIBCPP_INLINE_VISIBILITY
231         __scoped_allocator_storage(
232             const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
233             : outer_allocator_type(__other.outer_allocator()),
234               __inner_(__other.inner_allocator()) {}
236     template <class _OuterA2,
237               class = typename enable_if<
238                         is_constructible<outer_allocator_type, _OuterA2>::value
239                       >::type>
240         _LIBCPP_INLINE_VISIBILITY
241         __scoped_allocator_storage(
242             __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
243             : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
244               __inner_(_VSTD::move(__other.inner_allocator())) {}
246     template <class _OuterA2,
247               class = typename enable_if<
248                         is_constructible<outer_allocator_type, _OuterA2>::value
249                       >::type>
250         _LIBCPP_INLINE_VISIBILITY
251         __scoped_allocator_storage(_OuterA2&& __o,
252                                    const inner_allocator_type& __i) _NOEXCEPT
253             : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
254               __inner_(__i)
255         {
256         }
258     _LIBCPP_INLINE_VISIBILITY
259     inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}
260     _LIBCPP_INLINE_VISIBILITY
261     const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
263     _LIBCPP_INLINE_VISIBILITY
264     outer_allocator_type& outer_allocator() _NOEXCEPT
265         {return static_cast<outer_allocator_type&>(*this);}
266     _LIBCPP_INLINE_VISIBILITY
267     const outer_allocator_type& outer_allocator() const _NOEXCEPT
268         {return static_cast<const outer_allocator_type&>(*this);}
270     scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
271     _LIBCPP_INLINE_VISIBILITY
272     select_on_container_copy_construction() const _NOEXCEPT
273         {
274             return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
275             (
276                 allocator_traits<outer_allocator_type>::
277                     select_on_container_copy_construction(outer_allocator()),
278                 allocator_traits<inner_allocator_type>::
279                     select_on_container_copy_construction(inner_allocator())
280             );
281         }
283     template <class...> friend class __scoped_allocator_storage;
286 template <class _OuterAlloc>
287 class __scoped_allocator_storage<_OuterAlloc>
288     : public _OuterAlloc
290     typedef _OuterAlloc outer_allocator_type;
291 protected:
292     typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
294     _LIBCPP_INLINE_VISIBILITY
295     __scoped_allocator_storage() _NOEXCEPT {}
297     template <class _OuterA2,
298               class = typename enable_if<
299                         is_constructible<outer_allocator_type, _OuterA2>::value
300                       >::type>
301         _LIBCPP_INLINE_VISIBILITY
302         __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
303             : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
305     template <class _OuterA2,
306               class = typename enable_if<
307                         is_constructible<outer_allocator_type, const _OuterA2&>::value
308                       >::type>
309         _LIBCPP_INLINE_VISIBILITY
310         __scoped_allocator_storage(
311             const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
312             : outer_allocator_type(__other.outer_allocator()) {}
314     template <class _OuterA2,
315               class = typename enable_if<
316                         is_constructible<outer_allocator_type, _OuterA2>::value
317                       >::type>
318         _LIBCPP_INLINE_VISIBILITY
319         __scoped_allocator_storage(
320             __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
321             : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
323     _LIBCPP_INLINE_VISIBILITY
324     inner_allocator_type& inner_allocator() _NOEXCEPT
325         {return static_cast<inner_allocator_type&>(*this);}
326     _LIBCPP_INLINE_VISIBILITY
327     const inner_allocator_type& inner_allocator() const _NOEXCEPT
328         {return static_cast<const inner_allocator_type&>(*this);}
330     _LIBCPP_INLINE_VISIBILITY
331     outer_allocator_type& outer_allocator() _NOEXCEPT
332         {return static_cast<outer_allocator_type&>(*this);}
333     _LIBCPP_INLINE_VISIBILITY
334     const outer_allocator_type& outer_allocator() const _NOEXCEPT
335         {return static_cast<const outer_allocator_type&>(*this);}
337     _LIBCPP_INLINE_VISIBILITY
338     scoped_allocator_adaptor<outer_allocator_type>
339     select_on_container_copy_construction() const _NOEXCEPT
340         {return scoped_allocator_adaptor<outer_allocator_type>(
341             allocator_traits<outer_allocator_type>::
342                 select_on_container_copy_construction(outer_allocator())
343         );}
345     __scoped_allocator_storage(const outer_allocator_type& __o,
346                                const inner_allocator_type& __i) _NOEXCEPT;
348     template <class...> friend class __scoped_allocator_storage;
351 // __outermost
353 template <class _Alloc>
354 decltype(declval<_Alloc>().outer_allocator(), true_type())
355 __has_outer_allocator_test(_Alloc&& __a);
357 template <class _Alloc>
358 false_type
359 __has_outer_allocator_test(const volatile _Alloc& __a);
361 template <class _Alloc>
362 struct __has_outer_allocator
363     : public common_type
364              <
365                  decltype(__has_outer_allocator_test(declval<_Alloc&>()))
366              >::type
370 template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
371 struct __outermost
373     typedef _Alloc type;
374     _LIBCPP_INLINE_VISIBILITY
375     type& operator()(type& __a) const _NOEXCEPT {return __a;}
378 template <class _Alloc>
379 struct __outermost<_Alloc, true>
381     typedef typename remove_reference
382                      <
383                         decltype(declval<_Alloc>().outer_allocator())
384                      >::type                                    _OuterAlloc;
385     typedef typename __outermost<_OuterAlloc>::type             type;
386     _LIBCPP_INLINE_VISIBILITY
387     type& operator()(_Alloc& __a) const _NOEXCEPT
388         {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
391 template <class _OuterAlloc, class... _InnerAllocs>
392 class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
393     : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
395     typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
396     typedef allocator_traits<_OuterAlloc>             _OuterTraits;
397 public:
398     typedef _OuterAlloc                               outer_allocator_type;
399     typedef typename base::inner_allocator_type       inner_allocator_type;
400     typedef typename _OuterTraits::size_type          size_type;
401     typedef typename _OuterTraits::difference_type    difference_type;
402     typedef typename _OuterTraits::pointer            pointer;
403     typedef typename _OuterTraits::const_pointer      const_pointer;
404     typedef typename _OuterTraits::void_pointer       void_pointer;
405     typedef typename _OuterTraits::const_void_pointer const_void_pointer;
407     typedef integral_constant
408             <
409                 bool,
410                 __get_poc_copy_assignment<outer_allocator_type,
411                                           _InnerAllocs...>::value
412             > propagate_on_container_copy_assignment;
413     typedef integral_constant
414             <
415                 bool,
416                 __get_poc_move_assignment<outer_allocator_type,
417                                           _InnerAllocs...>::value
418             > propagate_on_container_move_assignment;
419     typedef integral_constant
420             <
421                 bool,
422                 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
423             > propagate_on_container_swap;
424     typedef integral_constant
425             <
426                 bool,
427                 __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
428             > is_always_equal;
430     template <class _Tp>
431     struct rebind
432     {
433         typedef scoped_allocator_adaptor
434         <
435             typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
436         > other;
437     };
439     _LIBCPP_INLINE_VISIBILITY
440     scoped_allocator_adaptor() _NOEXCEPT {}
441     template <class _OuterA2,
442               class = typename enable_if<
443                         is_constructible<outer_allocator_type, _OuterA2>::value
444                       >::type>
445         _LIBCPP_INLINE_VISIBILITY
446         scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
447                                  const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
448             : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
449     // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
450     template <class _OuterA2,
451               class = typename enable_if<
452                         is_constructible<outer_allocator_type, const _OuterA2&>::value
453                       >::type>
454         _LIBCPP_INLINE_VISIBILITY
455         scoped_allocator_adaptor(
456             const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
457                 : base(__other) {}
458     template <class _OuterA2,
459               class = typename enable_if<
460                         is_constructible<outer_allocator_type, _OuterA2>::value
461                       >::type>
462         _LIBCPP_INLINE_VISIBILITY
463         scoped_allocator_adaptor(
464             scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
465                 : base(_VSTD::move(__other)) {}
467     // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
468     // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
469     // ~scoped_allocator_adaptor() = default;
471     _LIBCPP_INLINE_VISIBILITY
472     inner_allocator_type& inner_allocator() _NOEXCEPT
473         {return base::inner_allocator();}
474     _LIBCPP_INLINE_VISIBILITY
475     const inner_allocator_type& inner_allocator() const _NOEXCEPT
476         {return base::inner_allocator();}
478     _LIBCPP_INLINE_VISIBILITY
479     outer_allocator_type& outer_allocator() _NOEXCEPT
480         {return base::outer_allocator();}
481     _LIBCPP_INLINE_VISIBILITY
482     const outer_allocator_type& outer_allocator() const _NOEXCEPT
483         {return base::outer_allocator();}
485     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
486     pointer allocate(size_type __n)
487         {return allocator_traits<outer_allocator_type>::
488             allocate(outer_allocator(), __n);}
489     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
490     pointer allocate(size_type __n, const_void_pointer __hint)
491         {return allocator_traits<outer_allocator_type>::
492             allocate(outer_allocator(), __n, __hint);}
494     _LIBCPP_INLINE_VISIBILITY
495     void deallocate(pointer __p, size_type __n) _NOEXCEPT
496         {allocator_traits<outer_allocator_type>::
497             deallocate(outer_allocator(), __p, __n);}
499     _LIBCPP_INLINE_VISIBILITY
500     size_type max_size() const
501         {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
503     template <class _Tp, class... _Args>
504         _LIBCPP_INLINE_VISIBILITY
505         void construct(_Tp* __p, _Args&& ...__args)
506             {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
507                          __p, _VSTD::forward<_Args>(__args)...);}
509     template <class _T1, class _T2, class... _Args1, class... _Args2>
510     void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
511                        tuple<_Args1...> __x, tuple<_Args2...> __y)
512     {
513         typedef __outermost<outer_allocator_type> _OM;
514         allocator_traits<typename _OM::type>::construct(
515             _OM()(outer_allocator()), __p, piecewise_construct
516           , __transform_tuple(
517               typename __uses_alloc_ctor<
518                   _T1, inner_allocator_type&, _Args1...
519               >::type()
520             , _VSTD::move(__x)
521             , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
522           )
523           , __transform_tuple(
524               typename __uses_alloc_ctor<
525                   _T2, inner_allocator_type&, _Args2...
526               >::type()
527             , _VSTD::move(__y)
528             , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
529           )
530         );
531     }
533     template <class _T1, class _T2>
534     void construct(pair<_T1, _T2>* __p)
535     { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
537     template <class _T1, class _T2, class _Up, class _Vp>
538     void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
539         construct(__p, piecewise_construct,
540                   _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
541                   _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
542     }
544     template <class _T1, class _T2, class _Up, class _Vp>
545     void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
546         construct(__p, piecewise_construct,
547                   _VSTD::forward_as_tuple(__x.first),
548                   _VSTD::forward_as_tuple(__x.second));
549     }
551     template <class _T1, class _T2, class _Up, class _Vp>
552     void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
553         construct(__p, piecewise_construct,
554                   _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
555                   _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
556     }
558     template <class _Tp>
559         _LIBCPP_INLINE_VISIBILITY
560         void destroy(_Tp* __p)
561             {
562                 typedef __outermost<outer_allocator_type> _OM;
563                 allocator_traits<typename _OM::type>::
564                                          destroy(_OM()(outer_allocator()), __p);
565             }
567     _LIBCPP_INLINE_VISIBILITY
568     scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
569         {return base::select_on_container_copy_construction();}
571 private:
574     template <class _OuterA2,
575               class = typename enable_if<
576                         is_constructible<outer_allocator_type, _OuterA2>::value
577                       >::type>
578     _LIBCPP_INLINE_VISIBILITY
579     scoped_allocator_adaptor(_OuterA2&& __o,
580                              const inner_allocator_type& __i) _NOEXCEPT
581         : base(_VSTD::forward<_OuterA2>(__o), __i) {}
583     template <class _Tp, class... _Args>
584         _LIBCPP_INLINE_VISIBILITY
585         void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
586             {
587                 typedef __outermost<outer_allocator_type> _OM;
588                 allocator_traits<typename _OM::type>::construct
589                 (
590                     _OM()(outer_allocator()),
591                     __p,
592                     _VSTD::forward<_Args>(__args)...
593                 );
594             }
596     template <class _Tp, class... _Args>
597         _LIBCPP_INLINE_VISIBILITY
598         void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
599             {
600                 typedef __outermost<outer_allocator_type> _OM;
601                 allocator_traits<typename _OM::type>::construct
602                 (
603                     _OM()(outer_allocator()),
604                     __p, allocator_arg, inner_allocator(),
605                     _VSTD::forward<_Args>(__args)...
606                 );
607             }
609     template <class _Tp, class... _Args>
610         _LIBCPP_INLINE_VISIBILITY
611         void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
612             {
613                 typedef __outermost<outer_allocator_type> _OM;
614                 allocator_traits<typename _OM::type>::construct
615                 (
616                     _OM()(outer_allocator()),
617                     __p,
618                     _VSTD::forward<_Args>(__args)...,
619                     inner_allocator()
620                 );
621             }
623     template <class ..._Args, size_t ..._Idx>
624     _LIBCPP_INLINE_VISIBILITY
625     tuple<_Args&&...>
626     __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
627                       __tuple_indices<_Idx...>)
628     {
629         return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
630     }
632     template <class ..._Args, size_t ..._Idx>
633     _LIBCPP_INLINE_VISIBILITY
634     tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
635     __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
636                       __tuple_indices<_Idx...>)
637     {
638         using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
639         return _Tup(allocator_arg, inner_allocator(),
640                     _VSTD::get<_Idx>(_VSTD::move(__t))...);
641     }
643     template <class ..._Args, size_t ..._Idx>
644     _LIBCPP_INLINE_VISIBILITY
645     tuple<_Args&&..., inner_allocator_type&>
646     __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
647                       __tuple_indices<_Idx...>)
648     {
649         using _Tup = tuple<_Args&&..., inner_allocator_type&>;
650         return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
651     }
653     template <class...> friend class __scoped_allocator_storage;
656 #if _LIBCPP_STD_VER > 14
657 template<class _OuterAlloc, class... _InnerAllocs>
658     scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
659         -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
660 #endif
662 template <class _OuterA1, class _OuterA2>
663 inline _LIBCPP_INLINE_VISIBILITY
664 bool
665 operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
666            const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
668     return __a.outer_allocator() == __b.outer_allocator();
671 template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
672 inline _LIBCPP_INLINE_VISIBILITY
673 bool
674 operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
675            const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
677     return __a.outer_allocator() == __b.outer_allocator() &&
678            __a.inner_allocator() == __b.inner_allocator();
681 template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
682 inline _LIBCPP_INLINE_VISIBILITY
683 bool
684 operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
685            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
687     return !(__a == __b);
690 #endif // !defined(_LIBCPP_CXX03_LANG)
692 _LIBCPP_END_NAMESPACE_STD
694 #endif // _LIBCPP_SCOPED_ALLOCATOR