xref: /freebsd/contrib/llvm-project/libcxx/include/scoped_allocator (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===-------------------------- scoped_allocator --------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_SCOPED_ALLOCATOR
11*0b57cec5SDimitry Andric#define _LIBCPP_SCOPED_ALLOCATOR
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric    scoped_allocator synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std
17*0b57cec5SDimitry Andric{
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andrictemplate <class OuterAlloc, class... InnerAllocs>
20*0b57cec5SDimitry Andricclass scoped_allocator_adaptor : public OuterAlloc
21*0b57cec5SDimitry Andric{
22*0b57cec5SDimitry Andric    typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
23*0b57cec5SDimitry Andric    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
24*0b57cec5SDimitry Andricpublic:
25*0b57cec5SDimitry Andric
26*0b57cec5SDimitry Andric    typedef OuterAlloc outer_allocator_type;
27*0b57cec5SDimitry Andric    typedef see below inner_allocator_type;
28*0b57cec5SDimitry Andric
29*0b57cec5SDimitry Andric    typedef typename OuterTraits::value_type value_type;
30*0b57cec5SDimitry Andric    typedef typename OuterTraits::size_type size_type;
31*0b57cec5SDimitry Andric    typedef typename OuterTraits::difference_type difference_type;
32*0b57cec5SDimitry Andric    typedef typename OuterTraits::pointer pointer;
33*0b57cec5SDimitry Andric    typedef typename OuterTraits::const_pointer const_pointer;
34*0b57cec5SDimitry Andric    typedef typename OuterTraits::void_pointer void_pointer;
35*0b57cec5SDimitry Andric    typedef typename OuterTraits::const_void_pointer const_void_pointer;
36*0b57cec5SDimitry Andric
37*0b57cec5SDimitry Andric    typedef see below propagate_on_container_copy_assignment;
38*0b57cec5SDimitry Andric    typedef see below propagate_on_container_move_assignment;
39*0b57cec5SDimitry Andric    typedef see below propagate_on_container_swap;
40*0b57cec5SDimitry Andric    typedef see below is_always_equal;
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andric    template <class Tp>
43*0b57cec5SDimitry Andric        struct rebind
44*0b57cec5SDimitry Andric        {
45*0b57cec5SDimitry Andric            typedef scoped_allocator_adaptor<
46*0b57cec5SDimitry Andric                OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
47*0b57cec5SDimitry Andric        };
48*0b57cec5SDimitry Andric
49*0b57cec5SDimitry Andric    scoped_allocator_adaptor();
50*0b57cec5SDimitry Andric    template <class OuterA2>
51*0b57cec5SDimitry Andric        scoped_allocator_adaptor(OuterA2&& outerAlloc,
52*0b57cec5SDimitry Andric                                 const InnerAllocs&... innerAllocs) noexcept;
53*0b57cec5SDimitry Andric    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
54*0b57cec5SDimitry Andric    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
55*0b57cec5SDimitry Andric    template <class OuterA2>
56*0b57cec5SDimitry Andric        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
57*0b57cec5SDimitry Andric    template <class OuterA2>
58*0b57cec5SDimitry Andric        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
59*0b57cec5SDimitry Andric
60*0b57cec5SDimitry Andric    scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
61*0b57cec5SDimitry Andric    scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
62*0b57cec5SDimitry Andric    ~scoped_allocator_adaptor();
63*0b57cec5SDimitry Andric
64*0b57cec5SDimitry Andric    inner_allocator_type& inner_allocator() noexcept;
65*0b57cec5SDimitry Andric    const inner_allocator_type& inner_allocator() const noexcept;
66*0b57cec5SDimitry Andric
67*0b57cec5SDimitry Andric    outer_allocator_type& outer_allocator() noexcept;
68*0b57cec5SDimitry Andric    const outer_allocator_type& outer_allocator() const noexcept;
69*0b57cec5SDimitry Andric
70*0b57cec5SDimitry Andric    pointer allocate(size_type n);                           // [[nodiscard]] in C++20
71*0b57cec5SDimitry Andric    pointer allocate(size_type n, const_void_pointer hint);  // [[nodiscard]] in C++20
72*0b57cec5SDimitry Andric    void deallocate(pointer p, size_type n) noexcept;
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andric    size_type max_size() const;
75*0b57cec5SDimitry Andric    template <class T, class... Args> void construct(T* p, Args&& args);
76*0b57cec5SDimitry Andric    template <class T1, class T2, class... Args1, class... Args2>
77*0b57cec5SDimitry Andric        void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
78*0b57cec5SDimitry Andric                       tuple<Args2...> y);
79*0b57cec5SDimitry Andric    template <class T1, class T2>
80*0b57cec5SDimitry Andric        void construct(pair<T1, T2>* p);
81*0b57cec5SDimitry Andric    template <class T1, class T2, class U, class V>
82*0b57cec5SDimitry Andric        void construct(pair<T1, T2>* p, U&& x, V&& y);
83*0b57cec5SDimitry Andric    template <class T1, class T2, class U, class V>
84*0b57cec5SDimitry Andric        void construct(pair<T1, T2>* p, const pair<U, V>& x);
85*0b57cec5SDimitry Andric    template <class T1, class T2, class U, class V>
86*0b57cec5SDimitry Andric        void construct(pair<T1, T2>* p, pair<U, V>&& x);
87*0b57cec5SDimitry Andric    template <class T> void destroy(T* p);
88*0b57cec5SDimitry Andric
89*0b57cec5SDimitry Andric    template <class T> void destroy(T* p) noexcept;
90*0b57cec5SDimitry Andric
91*0b57cec5SDimitry Andric    scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
92*0b57cec5SDimitry Andric};
93*0b57cec5SDimitry Andric
94*0b57cec5SDimitry Andrictemplate <class OuterA1, class OuterA2, class... InnerAllocs>
95*0b57cec5SDimitry Andric    bool
96*0b57cec5SDimitry Andric    operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
97*0b57cec5SDimitry Andric               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
98*0b57cec5SDimitry Andric
99*0b57cec5SDimitry Andrictemplate <class OuterA1, class OuterA2, class... InnerAllocs>
100*0b57cec5SDimitry Andric    bool
101*0b57cec5SDimitry Andric    operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
102*0b57cec5SDimitry Andric               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
103*0b57cec5SDimitry Andric
104*0b57cec5SDimitry Andric}  // std
105*0b57cec5SDimitry Andric
106*0b57cec5SDimitry Andric*/
107*0b57cec5SDimitry Andric
108*0b57cec5SDimitry Andric#include <__config>
109*0b57cec5SDimitry Andric#include <memory>
110*0b57cec5SDimitry Andric#include <version>
111*0b57cec5SDimitry Andric
112*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
113*0b57cec5SDimitry Andric#pragma GCC system_header
114*0b57cec5SDimitry Andric#endif
115*0b57cec5SDimitry Andric
116*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
117*0b57cec5SDimitry Andric
118*0b57cec5SDimitry Andric#if !defined(_LIBCPP_CXX03_LANG)
119*0b57cec5SDimitry Andric
120*0b57cec5SDimitry Andric// scoped_allocator_adaptor
121*0b57cec5SDimitry Andric
122*0b57cec5SDimitry Andrictemplate <class ..._Allocs>
123*0b57cec5SDimitry Andricclass scoped_allocator_adaptor;
124*0b57cec5SDimitry Andric
125*0b57cec5SDimitry Andrictemplate <class ..._Allocs> struct __get_poc_copy_assignment;
126*0b57cec5SDimitry Andric
127*0b57cec5SDimitry Andrictemplate <class _A0>
128*0b57cec5SDimitry Andricstruct __get_poc_copy_assignment<_A0>
129*0b57cec5SDimitry Andric{
130*0b57cec5SDimitry Andric    static const bool value = allocator_traits<_A0>::
131*0b57cec5SDimitry Andric                              propagate_on_container_copy_assignment::value;
132*0b57cec5SDimitry Andric};
133*0b57cec5SDimitry Andric
134*0b57cec5SDimitry Andrictemplate <class _A0, class ..._Allocs>
135*0b57cec5SDimitry Andricstruct __get_poc_copy_assignment<_A0, _Allocs...>
136*0b57cec5SDimitry Andric{
137*0b57cec5SDimitry Andric    static const bool value =
138*0b57cec5SDimitry Andric        allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
139*0b57cec5SDimitry Andric        __get_poc_copy_assignment<_Allocs...>::value;
140*0b57cec5SDimitry Andric};
141*0b57cec5SDimitry Andric
142*0b57cec5SDimitry Andrictemplate <class ..._Allocs> struct __get_poc_move_assignment;
143*0b57cec5SDimitry Andric
144*0b57cec5SDimitry Andrictemplate <class _A0>
145*0b57cec5SDimitry Andricstruct __get_poc_move_assignment<_A0>
146*0b57cec5SDimitry Andric{
147*0b57cec5SDimitry Andric    static const bool value = allocator_traits<_A0>::
148*0b57cec5SDimitry Andric                              propagate_on_container_move_assignment::value;
149*0b57cec5SDimitry Andric};
150*0b57cec5SDimitry Andric
151*0b57cec5SDimitry Andrictemplate <class _A0, class ..._Allocs>
152*0b57cec5SDimitry Andricstruct __get_poc_move_assignment<_A0, _Allocs...>
153*0b57cec5SDimitry Andric{
154*0b57cec5SDimitry Andric    static const bool value =
155*0b57cec5SDimitry Andric        allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
156*0b57cec5SDimitry Andric        __get_poc_move_assignment<_Allocs...>::value;
157*0b57cec5SDimitry Andric};
158*0b57cec5SDimitry Andric
159*0b57cec5SDimitry Andrictemplate <class ..._Allocs> struct __get_poc_swap;
160*0b57cec5SDimitry Andric
161*0b57cec5SDimitry Andrictemplate <class _A0>
162*0b57cec5SDimitry Andricstruct __get_poc_swap<_A0>
163*0b57cec5SDimitry Andric{
164*0b57cec5SDimitry Andric    static const bool value = allocator_traits<_A0>::
165*0b57cec5SDimitry Andric                              propagate_on_container_swap::value;
166*0b57cec5SDimitry Andric};
167*0b57cec5SDimitry Andric
168*0b57cec5SDimitry Andrictemplate <class _A0, class ..._Allocs>
169*0b57cec5SDimitry Andricstruct __get_poc_swap<_A0, _Allocs...>
170*0b57cec5SDimitry Andric{
171*0b57cec5SDimitry Andric    static const bool value =
172*0b57cec5SDimitry Andric        allocator_traits<_A0>::propagate_on_container_swap::value ||
173*0b57cec5SDimitry Andric        __get_poc_swap<_Allocs...>::value;
174*0b57cec5SDimitry Andric};
175*0b57cec5SDimitry Andric
176*0b57cec5SDimitry Andrictemplate <class ..._Allocs> struct __get_is_always_equal;
177*0b57cec5SDimitry Andric
178*0b57cec5SDimitry Andrictemplate <class _A0>
179*0b57cec5SDimitry Andricstruct __get_is_always_equal<_A0>
180*0b57cec5SDimitry Andric{
181*0b57cec5SDimitry Andric    static const bool value = allocator_traits<_A0>::is_always_equal::value;
182*0b57cec5SDimitry Andric};
183*0b57cec5SDimitry Andric
184*0b57cec5SDimitry Andrictemplate <class _A0, class ..._Allocs>
185*0b57cec5SDimitry Andricstruct __get_is_always_equal<_A0, _Allocs...>
186*0b57cec5SDimitry Andric{
187*0b57cec5SDimitry Andric    static const bool value =
188*0b57cec5SDimitry Andric        allocator_traits<_A0>::is_always_equal::value &&
189*0b57cec5SDimitry Andric        __get_is_always_equal<_Allocs...>::value;
190*0b57cec5SDimitry Andric};
191*0b57cec5SDimitry Andric
192*0b57cec5SDimitry Andrictemplate <class ..._Allocs>
193*0b57cec5SDimitry Andricclass __scoped_allocator_storage;
194*0b57cec5SDimitry Andric
195*0b57cec5SDimitry Andrictemplate <class _OuterAlloc, class... _InnerAllocs>
196*0b57cec5SDimitry Andricclass __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
197*0b57cec5SDimitry Andric    : public _OuterAlloc
198*0b57cec5SDimitry Andric{
199*0b57cec5SDimitry Andric    typedef _OuterAlloc outer_allocator_type;
200*0b57cec5SDimitry Andricprotected:
201*0b57cec5SDimitry Andric    typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
202*0b57cec5SDimitry Andric
203*0b57cec5SDimitry Andricprivate:
204*0b57cec5SDimitry Andric    inner_allocator_type __inner_;
205*0b57cec5SDimitry Andric
206*0b57cec5SDimitry Andricprotected:
207*0b57cec5SDimitry Andric
208*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
209*0b57cec5SDimitry Andric    __scoped_allocator_storage() _NOEXCEPT {}
210*0b57cec5SDimitry Andric
211*0b57cec5SDimitry Andric    template <class _OuterA2,
212*0b57cec5SDimitry Andric              class = typename enable_if<
213*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
214*0b57cec5SDimitry Andric                      >::type>
215*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
216*0b57cec5SDimitry Andric        __scoped_allocator_storage(_OuterA2&& __outerAlloc,
217*0b57cec5SDimitry Andric                                   const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
218*0b57cec5SDimitry Andric            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
219*0b57cec5SDimitry Andric              __inner_(__innerAllocs...) {}
220*0b57cec5SDimitry Andric
221*0b57cec5SDimitry Andric    template <class _OuterA2,
222*0b57cec5SDimitry Andric              class = typename enable_if<
223*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, const _OuterA2&>::value
224*0b57cec5SDimitry Andric                      >::type>
225*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
226*0b57cec5SDimitry Andric        __scoped_allocator_storage(
227*0b57cec5SDimitry Andric            const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
228*0b57cec5SDimitry Andric            : outer_allocator_type(__other.outer_allocator()),
229*0b57cec5SDimitry Andric              __inner_(__other.inner_allocator()) {}
230*0b57cec5SDimitry Andric
231*0b57cec5SDimitry Andric    template <class _OuterA2,
232*0b57cec5SDimitry Andric              class = typename enable_if<
233*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
234*0b57cec5SDimitry Andric                      >::type>
235*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
236*0b57cec5SDimitry Andric        __scoped_allocator_storage(
237*0b57cec5SDimitry Andric            __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
238*0b57cec5SDimitry Andric            : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
239*0b57cec5SDimitry Andric              __inner_(_VSTD::move(__other.inner_allocator())) {}
240*0b57cec5SDimitry Andric
241*0b57cec5SDimitry Andric    template <class _OuterA2,
242*0b57cec5SDimitry Andric              class = typename enable_if<
243*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
244*0b57cec5SDimitry Andric                      >::type>
245*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
246*0b57cec5SDimitry Andric        __scoped_allocator_storage(_OuterA2&& __o,
247*0b57cec5SDimitry Andric                                   const inner_allocator_type& __i) _NOEXCEPT
248*0b57cec5SDimitry Andric            : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
249*0b57cec5SDimitry Andric              __inner_(__i)
250*0b57cec5SDimitry Andric        {
251*0b57cec5SDimitry Andric        }
252*0b57cec5SDimitry Andric
253*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
254*0b57cec5SDimitry Andric    inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}
255*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
256*0b57cec5SDimitry Andric    const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
257*0b57cec5SDimitry Andric
258*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
259*0b57cec5SDimitry Andric    outer_allocator_type& outer_allocator() _NOEXCEPT
260*0b57cec5SDimitry Andric        {return static_cast<outer_allocator_type&>(*this);}
261*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
262*0b57cec5SDimitry Andric    const outer_allocator_type& outer_allocator() const _NOEXCEPT
263*0b57cec5SDimitry Andric        {return static_cast<const outer_allocator_type&>(*this);}
264*0b57cec5SDimitry Andric
265*0b57cec5SDimitry Andric    scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
266*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
267*0b57cec5SDimitry Andric    select_on_container_copy_construction() const _NOEXCEPT
268*0b57cec5SDimitry Andric        {
269*0b57cec5SDimitry Andric            return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
270*0b57cec5SDimitry Andric            (
271*0b57cec5SDimitry Andric                allocator_traits<outer_allocator_type>::
272*0b57cec5SDimitry Andric                    select_on_container_copy_construction(outer_allocator()),
273*0b57cec5SDimitry Andric                allocator_traits<inner_allocator_type>::
274*0b57cec5SDimitry Andric                    select_on_container_copy_construction(inner_allocator())
275*0b57cec5SDimitry Andric            );
276*0b57cec5SDimitry Andric        }
277*0b57cec5SDimitry Andric
278*0b57cec5SDimitry Andric    template <class...> friend class __scoped_allocator_storage;
279*0b57cec5SDimitry Andric};
280*0b57cec5SDimitry Andric
281*0b57cec5SDimitry Andrictemplate <class _OuterAlloc>
282*0b57cec5SDimitry Andricclass __scoped_allocator_storage<_OuterAlloc>
283*0b57cec5SDimitry Andric    : public _OuterAlloc
284*0b57cec5SDimitry Andric{
285*0b57cec5SDimitry Andric    typedef _OuterAlloc outer_allocator_type;
286*0b57cec5SDimitry Andricprotected:
287*0b57cec5SDimitry Andric    typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
288*0b57cec5SDimitry Andric
289*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
290*0b57cec5SDimitry Andric    __scoped_allocator_storage() _NOEXCEPT {}
291*0b57cec5SDimitry Andric
292*0b57cec5SDimitry Andric    template <class _OuterA2,
293*0b57cec5SDimitry Andric              class = typename enable_if<
294*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
295*0b57cec5SDimitry Andric                      >::type>
296*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
297*0b57cec5SDimitry Andric        __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
298*0b57cec5SDimitry Andric            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
299*0b57cec5SDimitry Andric
300*0b57cec5SDimitry Andric    template <class _OuterA2,
301*0b57cec5SDimitry Andric              class = typename enable_if<
302*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, const _OuterA2&>::value
303*0b57cec5SDimitry Andric                      >::type>
304*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
305*0b57cec5SDimitry Andric        __scoped_allocator_storage(
306*0b57cec5SDimitry Andric            const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
307*0b57cec5SDimitry Andric            : outer_allocator_type(__other.outer_allocator()) {}
308*0b57cec5SDimitry Andric
309*0b57cec5SDimitry Andric    template <class _OuterA2,
310*0b57cec5SDimitry Andric              class = typename enable_if<
311*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
312*0b57cec5SDimitry Andric                      >::type>
313*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
314*0b57cec5SDimitry Andric        __scoped_allocator_storage(
315*0b57cec5SDimitry Andric            __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
316*0b57cec5SDimitry Andric            : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
317*0b57cec5SDimitry Andric
318*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
319*0b57cec5SDimitry Andric    inner_allocator_type& inner_allocator() _NOEXCEPT
320*0b57cec5SDimitry Andric        {return static_cast<inner_allocator_type&>(*this);}
321*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
322*0b57cec5SDimitry Andric    const inner_allocator_type& inner_allocator() const _NOEXCEPT
323*0b57cec5SDimitry Andric        {return static_cast<const inner_allocator_type&>(*this);}
324*0b57cec5SDimitry Andric
325*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
326*0b57cec5SDimitry Andric    outer_allocator_type& outer_allocator() _NOEXCEPT
327*0b57cec5SDimitry Andric        {return static_cast<outer_allocator_type&>(*this);}
328*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
329*0b57cec5SDimitry Andric    const outer_allocator_type& outer_allocator() const _NOEXCEPT
330*0b57cec5SDimitry Andric        {return static_cast<const outer_allocator_type&>(*this);}
331*0b57cec5SDimitry Andric
332*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
333*0b57cec5SDimitry Andric    scoped_allocator_adaptor<outer_allocator_type>
334*0b57cec5SDimitry Andric    select_on_container_copy_construction() const _NOEXCEPT
335*0b57cec5SDimitry Andric        {return scoped_allocator_adaptor<outer_allocator_type>(
336*0b57cec5SDimitry Andric            allocator_traits<outer_allocator_type>::
337*0b57cec5SDimitry Andric                select_on_container_copy_construction(outer_allocator())
338*0b57cec5SDimitry Andric        );}
339*0b57cec5SDimitry Andric
340*0b57cec5SDimitry Andric    __scoped_allocator_storage(const outer_allocator_type& __o,
341*0b57cec5SDimitry Andric                               const inner_allocator_type& __i) _NOEXCEPT;
342*0b57cec5SDimitry Andric
343*0b57cec5SDimitry Andric    template <class...> friend class __scoped_allocator_storage;
344*0b57cec5SDimitry Andric};
345*0b57cec5SDimitry Andric
346*0b57cec5SDimitry Andric// __outermost
347*0b57cec5SDimitry Andric
348*0b57cec5SDimitry Andrictemplate <class _Alloc>
349*0b57cec5SDimitry Andricdecltype(declval<_Alloc>().outer_allocator(), true_type())
350*0b57cec5SDimitry Andric__has_outer_allocator_test(_Alloc&& __a);
351*0b57cec5SDimitry Andric
352*0b57cec5SDimitry Andrictemplate <class _Alloc>
353*0b57cec5SDimitry Andricfalse_type
354*0b57cec5SDimitry Andric__has_outer_allocator_test(const volatile _Alloc& __a);
355*0b57cec5SDimitry Andric
356*0b57cec5SDimitry Andrictemplate <class _Alloc>
357*0b57cec5SDimitry Andricstruct __has_outer_allocator
358*0b57cec5SDimitry Andric    : public common_type
359*0b57cec5SDimitry Andric             <
360*0b57cec5SDimitry Andric                 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
361*0b57cec5SDimitry Andric             >::type
362*0b57cec5SDimitry Andric{
363*0b57cec5SDimitry Andric};
364*0b57cec5SDimitry Andric
365*0b57cec5SDimitry Andrictemplate <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
366*0b57cec5SDimitry Andricstruct __outermost
367*0b57cec5SDimitry Andric{
368*0b57cec5SDimitry Andric    typedef _Alloc type;
369*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
370*0b57cec5SDimitry Andric    type& operator()(type& __a) const _NOEXCEPT {return __a;}
371*0b57cec5SDimitry Andric};
372*0b57cec5SDimitry Andric
373*0b57cec5SDimitry Andrictemplate <class _Alloc>
374*0b57cec5SDimitry Andricstruct __outermost<_Alloc, true>
375*0b57cec5SDimitry Andric{
376*0b57cec5SDimitry Andric    typedef typename remove_reference
377*0b57cec5SDimitry Andric                     <
378*0b57cec5SDimitry Andric                        decltype(_VSTD::declval<_Alloc>().outer_allocator())
379*0b57cec5SDimitry Andric                     >::type                                    _OuterAlloc;
380*0b57cec5SDimitry Andric    typedef typename __outermost<_OuterAlloc>::type             type;
381*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
382*0b57cec5SDimitry Andric    type& operator()(_Alloc& __a) const _NOEXCEPT
383*0b57cec5SDimitry Andric        {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
384*0b57cec5SDimitry Andric};
385*0b57cec5SDimitry Andric
386*0b57cec5SDimitry Andrictemplate <class _OuterAlloc, class... _InnerAllocs>
387*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
388*0b57cec5SDimitry Andric    : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
389*0b57cec5SDimitry Andric{
390*0b57cec5SDimitry Andric    typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
391*0b57cec5SDimitry Andric    typedef allocator_traits<_OuterAlloc>             _OuterTraits;
392*0b57cec5SDimitry Andricpublic:
393*0b57cec5SDimitry Andric    typedef _OuterAlloc                               outer_allocator_type;
394*0b57cec5SDimitry Andric    typedef typename base::inner_allocator_type       inner_allocator_type;
395*0b57cec5SDimitry Andric    typedef typename _OuterTraits::size_type          size_type;
396*0b57cec5SDimitry Andric    typedef typename _OuterTraits::difference_type    difference_type;
397*0b57cec5SDimitry Andric    typedef typename _OuterTraits::pointer            pointer;
398*0b57cec5SDimitry Andric    typedef typename _OuterTraits::const_pointer      const_pointer;
399*0b57cec5SDimitry Andric    typedef typename _OuterTraits::void_pointer       void_pointer;
400*0b57cec5SDimitry Andric    typedef typename _OuterTraits::const_void_pointer const_void_pointer;
401*0b57cec5SDimitry Andric
402*0b57cec5SDimitry Andric    typedef integral_constant
403*0b57cec5SDimitry Andric            <
404*0b57cec5SDimitry Andric                bool,
405*0b57cec5SDimitry Andric                __get_poc_copy_assignment<outer_allocator_type,
406*0b57cec5SDimitry Andric                                          _InnerAllocs...>::value
407*0b57cec5SDimitry Andric            > propagate_on_container_copy_assignment;
408*0b57cec5SDimitry Andric    typedef integral_constant
409*0b57cec5SDimitry Andric            <
410*0b57cec5SDimitry Andric                bool,
411*0b57cec5SDimitry Andric                __get_poc_move_assignment<outer_allocator_type,
412*0b57cec5SDimitry Andric                                          _InnerAllocs...>::value
413*0b57cec5SDimitry Andric            > propagate_on_container_move_assignment;
414*0b57cec5SDimitry Andric    typedef integral_constant
415*0b57cec5SDimitry Andric            <
416*0b57cec5SDimitry Andric                bool,
417*0b57cec5SDimitry Andric                __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
418*0b57cec5SDimitry Andric            > propagate_on_container_swap;
419*0b57cec5SDimitry Andric    typedef integral_constant
420*0b57cec5SDimitry Andric            <
421*0b57cec5SDimitry Andric                bool,
422*0b57cec5SDimitry Andric                __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
423*0b57cec5SDimitry Andric            > is_always_equal;
424*0b57cec5SDimitry Andric
425*0b57cec5SDimitry Andric    template <class _Tp>
426*0b57cec5SDimitry Andric    struct rebind
427*0b57cec5SDimitry Andric    {
428*0b57cec5SDimitry Andric        typedef scoped_allocator_adaptor
429*0b57cec5SDimitry Andric        <
430*0b57cec5SDimitry Andric            typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
431*0b57cec5SDimitry Andric        > other;
432*0b57cec5SDimitry Andric    };
433*0b57cec5SDimitry Andric
434*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
435*0b57cec5SDimitry Andric    scoped_allocator_adaptor() _NOEXCEPT {}
436*0b57cec5SDimitry Andric    template <class _OuterA2,
437*0b57cec5SDimitry Andric              class = typename enable_if<
438*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
439*0b57cec5SDimitry Andric                      >::type>
440*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
441*0b57cec5SDimitry Andric        scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
442*0b57cec5SDimitry Andric                                 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
443*0b57cec5SDimitry Andric            : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
444*0b57cec5SDimitry Andric    // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
445*0b57cec5SDimitry Andric    template <class _OuterA2,
446*0b57cec5SDimitry Andric              class = typename enable_if<
447*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, const _OuterA2&>::value
448*0b57cec5SDimitry Andric                      >::type>
449*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
450*0b57cec5SDimitry Andric        scoped_allocator_adaptor(
451*0b57cec5SDimitry Andric            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
452*0b57cec5SDimitry Andric                : base(__other) {}
453*0b57cec5SDimitry Andric    template <class _OuterA2,
454*0b57cec5SDimitry Andric              class = typename enable_if<
455*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
456*0b57cec5SDimitry Andric                      >::type>
457*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
458*0b57cec5SDimitry Andric        scoped_allocator_adaptor(
459*0b57cec5SDimitry Andric            scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
460*0b57cec5SDimitry Andric                : base(_VSTD::move(__other)) {}
461*0b57cec5SDimitry Andric
462*0b57cec5SDimitry Andric    // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
463*0b57cec5SDimitry Andric    // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
464*0b57cec5SDimitry Andric    // ~scoped_allocator_adaptor() = default;
465*0b57cec5SDimitry Andric
466*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
467*0b57cec5SDimitry Andric    inner_allocator_type& inner_allocator() _NOEXCEPT
468*0b57cec5SDimitry Andric        {return base::inner_allocator();}
469*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
470*0b57cec5SDimitry Andric    const inner_allocator_type& inner_allocator() const _NOEXCEPT
471*0b57cec5SDimitry Andric        {return base::inner_allocator();}
472*0b57cec5SDimitry Andric
473*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
474*0b57cec5SDimitry Andric    outer_allocator_type& outer_allocator() _NOEXCEPT
475*0b57cec5SDimitry Andric        {return base::outer_allocator();}
476*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
477*0b57cec5SDimitry Andric    const outer_allocator_type& outer_allocator() const _NOEXCEPT
478*0b57cec5SDimitry Andric        {return base::outer_allocator();}
479*0b57cec5SDimitry Andric
480*0b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
481*0b57cec5SDimitry Andric    pointer allocate(size_type __n)
482*0b57cec5SDimitry Andric        {return allocator_traits<outer_allocator_type>::
483*0b57cec5SDimitry Andric            allocate(outer_allocator(), __n);}
484*0b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
485*0b57cec5SDimitry Andric    pointer allocate(size_type __n, const_void_pointer __hint)
486*0b57cec5SDimitry Andric        {return allocator_traits<outer_allocator_type>::
487*0b57cec5SDimitry Andric            allocate(outer_allocator(), __n, __hint);}
488*0b57cec5SDimitry Andric
489*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
490*0b57cec5SDimitry Andric    void deallocate(pointer __p, size_type __n) _NOEXCEPT
491*0b57cec5SDimitry Andric        {allocator_traits<outer_allocator_type>::
492*0b57cec5SDimitry Andric            deallocate(outer_allocator(), __p, __n);}
493*0b57cec5SDimitry Andric
494*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
495*0b57cec5SDimitry Andric    size_type max_size() const
496*0b57cec5SDimitry Andric        {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
497*0b57cec5SDimitry Andric
498*0b57cec5SDimitry Andric    template <class _Tp, class... _Args>
499*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
500*0b57cec5SDimitry Andric        void construct(_Tp* __p, _Args&& ...__args)
501*0b57cec5SDimitry Andric            {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
502*0b57cec5SDimitry Andric                         __p, _VSTD::forward<_Args>(__args)...);}
503*0b57cec5SDimitry Andric
504*0b57cec5SDimitry Andric    template <class _T1, class _T2, class... _Args1, class... _Args2>
505*0b57cec5SDimitry Andric    void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
506*0b57cec5SDimitry Andric                       tuple<_Args1...> __x, tuple<_Args2...> __y)
507*0b57cec5SDimitry Andric    {
508*0b57cec5SDimitry Andric        typedef __outermost<outer_allocator_type> _OM;
509*0b57cec5SDimitry Andric        allocator_traits<typename _OM::type>::construct(
510*0b57cec5SDimitry Andric            _OM()(outer_allocator()), __p, piecewise_construct
511*0b57cec5SDimitry Andric          , __transform_tuple(
512*0b57cec5SDimitry Andric              typename __uses_alloc_ctor<
513*0b57cec5SDimitry Andric                  _T1, inner_allocator_type&, _Args1...
514*0b57cec5SDimitry Andric              >::type()
515*0b57cec5SDimitry Andric            , _VSTD::move(__x)
516*0b57cec5SDimitry Andric            , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
517*0b57cec5SDimitry Andric          )
518*0b57cec5SDimitry Andric          , __transform_tuple(
519*0b57cec5SDimitry Andric              typename __uses_alloc_ctor<
520*0b57cec5SDimitry Andric                  _T2, inner_allocator_type&, _Args2...
521*0b57cec5SDimitry Andric              >::type()
522*0b57cec5SDimitry Andric            , _VSTD::move(__y)
523*0b57cec5SDimitry Andric            , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
524*0b57cec5SDimitry Andric          )
525*0b57cec5SDimitry Andric        );
526*0b57cec5SDimitry Andric    }
527*0b57cec5SDimitry Andric
528*0b57cec5SDimitry Andric    template <class _T1, class _T2>
529*0b57cec5SDimitry Andric    void construct(pair<_T1, _T2>* __p)
530*0b57cec5SDimitry Andric    { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
531*0b57cec5SDimitry Andric
532*0b57cec5SDimitry Andric    template <class _T1, class _T2, class _Up, class _Vp>
533*0b57cec5SDimitry Andric    void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
534*0b57cec5SDimitry Andric        construct(__p, piecewise_construct,
535*0b57cec5SDimitry Andric                  _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
536*0b57cec5SDimitry Andric                  _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
537*0b57cec5SDimitry Andric    }
538*0b57cec5SDimitry Andric
539*0b57cec5SDimitry Andric    template <class _T1, class _T2, class _Up, class _Vp>
540*0b57cec5SDimitry Andric    void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
541*0b57cec5SDimitry Andric        construct(__p, piecewise_construct,
542*0b57cec5SDimitry Andric                  _VSTD::forward_as_tuple(__x.first),
543*0b57cec5SDimitry Andric                  _VSTD::forward_as_tuple(__x.second));
544*0b57cec5SDimitry Andric    }
545*0b57cec5SDimitry Andric
546*0b57cec5SDimitry Andric    template <class _T1, class _T2, class _Up, class _Vp>
547*0b57cec5SDimitry Andric    void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
548*0b57cec5SDimitry Andric        construct(__p, piecewise_construct,
549*0b57cec5SDimitry Andric                  _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
550*0b57cec5SDimitry Andric                  _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
551*0b57cec5SDimitry Andric    }
552*0b57cec5SDimitry Andric
553*0b57cec5SDimitry Andric    template <class _Tp>
554*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
555*0b57cec5SDimitry Andric        void destroy(_Tp* __p)
556*0b57cec5SDimitry Andric            {
557*0b57cec5SDimitry Andric                typedef __outermost<outer_allocator_type> _OM;
558*0b57cec5SDimitry Andric                allocator_traits<typename _OM::type>::
559*0b57cec5SDimitry Andric                                         destroy(_OM()(outer_allocator()), __p);
560*0b57cec5SDimitry Andric            }
561*0b57cec5SDimitry Andric
562*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
563*0b57cec5SDimitry Andric    scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
564*0b57cec5SDimitry Andric        {return base::select_on_container_copy_construction();}
565*0b57cec5SDimitry Andric
566*0b57cec5SDimitry Andricprivate:
567*0b57cec5SDimitry Andric
568*0b57cec5SDimitry Andric
569*0b57cec5SDimitry Andric    template <class _OuterA2,
570*0b57cec5SDimitry Andric              class = typename enable_if<
571*0b57cec5SDimitry Andric                        is_constructible<outer_allocator_type, _OuterA2>::value
572*0b57cec5SDimitry Andric                      >::type>
573*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
574*0b57cec5SDimitry Andric    scoped_allocator_adaptor(_OuterA2&& __o,
575*0b57cec5SDimitry Andric                             const inner_allocator_type& __i) _NOEXCEPT
576*0b57cec5SDimitry Andric        : base(_VSTD::forward<_OuterA2>(__o), __i) {}
577*0b57cec5SDimitry Andric
578*0b57cec5SDimitry Andric    template <class _Tp, class... _Args>
579*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
580*0b57cec5SDimitry Andric        void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
581*0b57cec5SDimitry Andric            {
582*0b57cec5SDimitry Andric                typedef __outermost<outer_allocator_type> _OM;
583*0b57cec5SDimitry Andric                allocator_traits<typename _OM::type>::construct
584*0b57cec5SDimitry Andric                (
585*0b57cec5SDimitry Andric                    _OM()(outer_allocator()),
586*0b57cec5SDimitry Andric                    __p,
587*0b57cec5SDimitry Andric                    _VSTD::forward<_Args>(__args)...
588*0b57cec5SDimitry Andric                );
589*0b57cec5SDimitry Andric            }
590*0b57cec5SDimitry Andric
591*0b57cec5SDimitry Andric    template <class _Tp, class... _Args>
592*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
593*0b57cec5SDimitry Andric        void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
594*0b57cec5SDimitry Andric            {
595*0b57cec5SDimitry Andric                typedef __outermost<outer_allocator_type> _OM;
596*0b57cec5SDimitry Andric                allocator_traits<typename _OM::type>::construct
597*0b57cec5SDimitry Andric                (
598*0b57cec5SDimitry Andric                    _OM()(outer_allocator()),
599*0b57cec5SDimitry Andric                    __p, allocator_arg, inner_allocator(),
600*0b57cec5SDimitry Andric                    _VSTD::forward<_Args>(__args)...
601*0b57cec5SDimitry Andric                );
602*0b57cec5SDimitry Andric            }
603*0b57cec5SDimitry Andric
604*0b57cec5SDimitry Andric    template <class _Tp, class... _Args>
605*0b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
606*0b57cec5SDimitry Andric        void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
607*0b57cec5SDimitry Andric            {
608*0b57cec5SDimitry Andric                typedef __outermost<outer_allocator_type> _OM;
609*0b57cec5SDimitry Andric                allocator_traits<typename _OM::type>::construct
610*0b57cec5SDimitry Andric                (
611*0b57cec5SDimitry Andric                    _OM()(outer_allocator()),
612*0b57cec5SDimitry Andric                    __p,
613*0b57cec5SDimitry Andric                    _VSTD::forward<_Args>(__args)...,
614*0b57cec5SDimitry Andric                    inner_allocator()
615*0b57cec5SDimitry Andric                );
616*0b57cec5SDimitry Andric            }
617*0b57cec5SDimitry Andric
618*0b57cec5SDimitry Andric    template <class ..._Args, size_t ..._Idx>
619*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
620*0b57cec5SDimitry Andric    tuple<_Args&&...>
621*0b57cec5SDimitry Andric    __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
622*0b57cec5SDimitry Andric                      __tuple_indices<_Idx...>)
623*0b57cec5SDimitry Andric    {
624*0b57cec5SDimitry Andric        return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
625*0b57cec5SDimitry Andric    }
626*0b57cec5SDimitry Andric
627*0b57cec5SDimitry Andric    template <class ..._Args, size_t ..._Idx>
628*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
629*0b57cec5SDimitry Andric    tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
630*0b57cec5SDimitry Andric    __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
631*0b57cec5SDimitry Andric                      __tuple_indices<_Idx...>)
632*0b57cec5SDimitry Andric    {
633*0b57cec5SDimitry Andric        using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
634*0b57cec5SDimitry Andric        return _Tup(allocator_arg, inner_allocator(),
635*0b57cec5SDimitry Andric                    _VSTD::get<_Idx>(_VSTD::move(__t))...);
636*0b57cec5SDimitry Andric    }
637*0b57cec5SDimitry Andric
638*0b57cec5SDimitry Andric    template <class ..._Args, size_t ..._Idx>
639*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
640*0b57cec5SDimitry Andric    tuple<_Args&&..., inner_allocator_type&>
641*0b57cec5SDimitry Andric    __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
642*0b57cec5SDimitry Andric                      __tuple_indices<_Idx...>)
643*0b57cec5SDimitry Andric    {
644*0b57cec5SDimitry Andric        using _Tup = tuple<_Args&&..., inner_allocator_type&>;
645*0b57cec5SDimitry Andric        return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
646*0b57cec5SDimitry Andric    }
647*0b57cec5SDimitry Andric
648*0b57cec5SDimitry Andric    template <class...> friend class __scoped_allocator_storage;
649*0b57cec5SDimitry Andric};
650*0b57cec5SDimitry Andric
651*0b57cec5SDimitry Andrictemplate <class _OuterA1, class _OuterA2>
652*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
653*0b57cec5SDimitry Andricbool
654*0b57cec5SDimitry Andricoperator==(const scoped_allocator_adaptor<_OuterA1>& __a,
655*0b57cec5SDimitry Andric           const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
656*0b57cec5SDimitry Andric{
657*0b57cec5SDimitry Andric    return __a.outer_allocator() == __b.outer_allocator();
658*0b57cec5SDimitry Andric}
659*0b57cec5SDimitry Andric
660*0b57cec5SDimitry Andrictemplate <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
661*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
662*0b57cec5SDimitry Andricbool
663*0b57cec5SDimitry Andricoperator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
664*0b57cec5SDimitry Andric           const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
665*0b57cec5SDimitry Andric{
666*0b57cec5SDimitry Andric    return __a.outer_allocator() == __b.outer_allocator() &&
667*0b57cec5SDimitry Andric           __a.inner_allocator() == __b.inner_allocator();
668*0b57cec5SDimitry Andric}
669*0b57cec5SDimitry Andric
670*0b57cec5SDimitry Andrictemplate <class _OuterA1, class _OuterA2, class... _InnerAllocs>
671*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
672*0b57cec5SDimitry Andricbool
673*0b57cec5SDimitry Andricoperator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
674*0b57cec5SDimitry Andric           const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
675*0b57cec5SDimitry Andric{
676*0b57cec5SDimitry Andric    return !(__a == __b);
677*0b57cec5SDimitry Andric}
678*0b57cec5SDimitry Andric
679*0b57cec5SDimitry Andric#endif  // !defined(_LIBCPP_CXX03_LANG)
680*0b57cec5SDimitry Andric
681*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
682*0b57cec5SDimitry Andric
683*0b57cec5SDimitry Andric#endif  // _LIBCPP_SCOPED_ALLOCATOR
684