scoped_allocator revision 261272
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===-------------------------- scoped_allocator --------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_SCOPED_ALLOCATOR
12227825Stheraven#define _LIBCPP_SCOPED_ALLOCATOR
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    scoped_allocator synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheraventemplate <class OuterAlloc, class... InnerAllocs>
21227825Stheravenclass scoped_allocator_adaptor : public OuterAlloc
22227825Stheraven{
23227825Stheraven    typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
24227825Stheraven    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
25227825Stheravenpublic:
26227825Stheraven
27227825Stheraven    typedef OuterAlloc outer_allocator_type;
28227825Stheraven    typedef see below inner_allocator_type;
29227825Stheraven
30227825Stheraven    typedef typename OuterTraits::value_type value_type;
31227825Stheraven    typedef typename OuterTraits::size_type size_type;
32227825Stheraven    typedef typename OuterTraits::difference_type difference_type;
33227825Stheraven    typedef typename OuterTraits::pointer pointer;
34227825Stheraven    typedef typename OuterTraits::const_pointer const_pointer;
35227825Stheraven    typedef typename OuterTraits::void_pointer void_pointer;
36227825Stheraven    typedef typename OuterTraits::const_void_pointer const_void_pointer;
37227825Stheraven
38227825Stheraven    typedef see below propagate_on_container_copy_assignment;
39227825Stheraven    typedef see below propagate_on_container_move_assignment;
40227825Stheraven    typedef see below propagate_on_container_swap;
41227825Stheraven
42227825Stheraven    template <class Tp>
43227825Stheraven        struct rebind
44227825Stheraven        {
45227825Stheraven            typedef scoped_allocator_adaptor<
46227825Stheraven                OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
47227825Stheraven        };
48227825Stheraven
49227825Stheraven    scoped_allocator_adaptor();
50227825Stheraven    template <class OuterA2>
51227825Stheraven        scoped_allocator_adaptor(OuterA2&& outerAlloc,
52227825Stheraven                                 const InnerAllocs&... innerAllocs) noexcept;
53227825Stheraven    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
54227825Stheraven    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
55227825Stheraven    template <class OuterA2>
56227825Stheraven        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
57227825Stheraven    template <class OuterA2>
58227825Stheraven        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
59227825Stheraven
60227825Stheraven    ~scoped_allocator_adaptor();
61227825Stheraven
62227825Stheraven    inner_allocator_type& inner_allocator() noexcept;
63227825Stheraven    const inner_allocator_type& inner_allocator() const noexcept;
64227825Stheraven
65227825Stheraven    outer_allocator_type& outer_allocator() noexcept;
66227825Stheraven    const outer_allocator_type& outer_allocator() const noexcept;
67227825Stheraven
68227825Stheraven    pointer allocate(size_type n);
69227825Stheraven    pointer allocate(size_type n, const_void_pointer hint);
70227825Stheraven    void deallocate(pointer p, size_type n) noexcept;
71227825Stheraven
72227825Stheraven    size_type max_size() const;
73227825Stheraven    template <class T, class... Args> void construct(T* p, Args&& args);
74227825Stheraven    template <class T1, class T2, class... Args1, class... Args2>
75227825Stheraven        void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
76227825Stheraven                       tuple<Args2...> y);
77227825Stheraven    template <class T1, class T2>
78227825Stheraven        void construct(pair<T1, T2>* p);
79227825Stheraven    template <class T1, class T2, class U, class V>
80227825Stheraven        void construct(pair<T1, T2>* p, U&& x, V&& y);
81227825Stheraven    template <class T1, class T2, class U, class V>
82227825Stheraven        void construct(pair<T1, T2>* p, const pair<U, V>& x);
83227825Stheraven    template <class T1, class T2, class U, class V>
84227825Stheraven        void construct(pair<T1, T2>* p, pair<U, V>&& x);
85227825Stheraven    template <class T> void destroy(T* p);
86227825Stheraven
87227825Stheraven    template <class T> void destroy(T* p) noexcept;
88227825Stheraven
89227825Stheraven    scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
90227825Stheraven};
91227825Stheraven
92227825Stheraventemplate <class OuterA1, class OuterA2, class... InnerAllocs>
93227825Stheraven    bool
94227825Stheraven    operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
95227825Stheraven               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
96227825Stheraven
97227825Stheraventemplate <class OuterA1, class OuterA2, class... InnerAllocs>
98227825Stheraven    bool
99227825Stheraven    operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
100227825Stheraven               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
101227825Stheraven
102227825Stheraven}  // std
103227825Stheraven
104227825Stheraven*/
105227825Stheraven
106227825Stheraven#include <__config>
107227825Stheraven#include <memory>
108227825Stheraven
109227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
110227825Stheraven#pragma GCC system_header
111227825Stheraven#endif
112227825Stheraven
113227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
114227825Stheraven
115227825Stheraven#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
116227825Stheraven
117227825Stheraven// scoped_allocator_adaptor
118227825Stheraven
119227825Stheraventemplate <class ..._Allocs>
120227825Stheravenclass scoped_allocator_adaptor;
121227825Stheraven
122227825Stheraventemplate <class ..._Allocs> struct __get_poc_copy_assignment;
123227825Stheraven
124227825Stheraventemplate <class _A0>
125227825Stheravenstruct __get_poc_copy_assignment<_A0>
126227825Stheraven{
127227825Stheraven    static const bool value = allocator_traits<_A0>::
128227825Stheraven                              propagate_on_container_copy_assignment::value;
129227825Stheraven};
130227825Stheraven
131227825Stheraventemplate <class _A0, class ..._Allocs>
132227825Stheravenstruct __get_poc_copy_assignment<_A0, _Allocs...>
133227825Stheraven{
134227825Stheraven    static const bool value =
135227825Stheraven        allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
136227825Stheraven        __get_poc_copy_assignment<_Allocs...>::value;
137227825Stheraven};
138227825Stheraven
139227825Stheraventemplate <class ..._Allocs> struct __get_poc_move_assignment;
140227825Stheraven
141227825Stheraventemplate <class _A0>
142227825Stheravenstruct __get_poc_move_assignment<_A0>
143227825Stheraven{
144227825Stheraven    static const bool value = allocator_traits<_A0>::
145227825Stheraven                              propagate_on_container_move_assignment::value;
146227825Stheraven};
147227825Stheraven
148227825Stheraventemplate <class _A0, class ..._Allocs>
149227825Stheravenstruct __get_poc_move_assignment<_A0, _Allocs...>
150227825Stheraven{
151227825Stheraven    static const bool value =
152227825Stheraven        allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
153227825Stheraven        __get_poc_move_assignment<_Allocs...>::value;
154227825Stheraven};
155227825Stheraven
156227825Stheraventemplate <class ..._Allocs> struct __get_poc_swap;
157227825Stheraven
158227825Stheraventemplate <class _A0>
159227825Stheravenstruct __get_poc_swap<_A0>
160227825Stheraven{
161227825Stheraven    static const bool value = allocator_traits<_A0>::
162227825Stheraven                              propagate_on_container_swap::value;
163227825Stheraven};
164227825Stheraven
165227825Stheraventemplate <class _A0, class ..._Allocs>
166227825Stheravenstruct __get_poc_swap<_A0, _Allocs...>
167227825Stheraven{
168227825Stheraven    static const bool value =
169227825Stheraven        allocator_traits<_A0>::propagate_on_container_swap::value ||
170227825Stheraven        __get_poc_swap<_Allocs...>::value;
171227825Stheraven};
172227825Stheraven
173227825Stheraventemplate <class ..._Allocs>
174227825Stheravenclass __scoped_allocator_storage;
175227825Stheraven
176227825Stheraventemplate <class _OuterAlloc, class... _InnerAllocs>
177227825Stheravenclass __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
178227825Stheraven    : public _OuterAlloc
179227825Stheraven{
180227825Stheraven    typedef _OuterAlloc outer_allocator_type;
181227825Stheravenprotected:
182227825Stheraven    typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
183227825Stheraven
184227825Stheravenprivate:
185227825Stheraven    inner_allocator_type __inner_;
186227825Stheraven
187227825Stheravenprotected:
188227825Stheraven
189227825Stheraven    _LIBCPP_INLINE_VISIBILITY
190227825Stheraven    __scoped_allocator_storage() _NOEXCEPT {}
191227825Stheraven
192227825Stheraven    template <class _OuterA2,
193227825Stheraven              class = typename enable_if<
194227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
195227825Stheraven                      >::type>
196227825Stheraven        _LIBCPP_INLINE_VISIBILITY
197227825Stheraven        __scoped_allocator_storage(_OuterA2&& __outerAlloc,
198227825Stheraven                                   const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
199227825Stheraven            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
200227825Stheraven              __inner_(__innerAllocs...) {}
201227825Stheraven
202227825Stheraven    template <class _OuterA2,
203227825Stheraven              class = typename enable_if<
204227825Stheraven                        is_constructible<outer_allocator_type, const _OuterA2&>::value
205227825Stheraven                      >::type>
206227825Stheraven        _LIBCPP_INLINE_VISIBILITY
207227825Stheraven        __scoped_allocator_storage(
208227825Stheraven            const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
209227825Stheraven            : outer_allocator_type(__other.outer_allocator()),
210227825Stheraven              __inner_(__other.inner_allocator()) {}
211227825Stheraven
212227825Stheraven    template <class _OuterA2,
213227825Stheraven              class = typename enable_if<
214227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
215227825Stheraven                      >::type>
216227825Stheraven        _LIBCPP_INLINE_VISIBILITY
217227825Stheraven        __scoped_allocator_storage(
218227825Stheraven            __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
219227825Stheraven            : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
220227825Stheraven              __inner_(_VSTD::move(__other.inner_allocator())) {}
221227825Stheraven
222227825Stheraven    template <class _OuterA2,
223227825Stheraven              class = typename enable_if<
224227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
225227825Stheraven                      >::type>
226227825Stheraven        _LIBCPP_INLINE_VISIBILITY
227227825Stheraven        __scoped_allocator_storage(_OuterA2&& __o,
228227825Stheraven                                   const inner_allocator_type& __i) _NOEXCEPT
229227825Stheraven            : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
230227825Stheraven              __inner_(__i)
231227825Stheraven        {
232227825Stheraven        }
233227825Stheraven
234227825Stheraven    _LIBCPP_INLINE_VISIBILITY
235227825Stheraven    inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}
236227825Stheraven    _LIBCPP_INLINE_VISIBILITY
237227825Stheraven    const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
238227825Stheraven
239227825Stheraven    _LIBCPP_INLINE_VISIBILITY
240227825Stheraven    outer_allocator_type& outer_allocator() _NOEXCEPT
241227825Stheraven        {return static_cast<outer_allocator_type&>(*this);}
242227825Stheraven    _LIBCPP_INLINE_VISIBILITY
243227825Stheraven    const outer_allocator_type& outer_allocator() const _NOEXCEPT
244227825Stheraven        {return static_cast<const outer_allocator_type&>(*this);}
245227825Stheraven
246227825Stheraven    scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
247227825Stheraven    _LIBCPP_INLINE_VISIBILITY
248227825Stheraven    select_on_container_copy_construction() const _NOEXCEPT
249227825Stheraven        {
250227825Stheraven            return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
251227825Stheraven            (
252227825Stheraven                allocator_traits<outer_allocator_type>::
253227825Stheraven                    select_on_container_copy_construction(outer_allocator()),
254227825Stheraven                allocator_traits<inner_allocator_type>::
255227825Stheraven                    select_on_container_copy_construction(inner_allocator())
256227825Stheraven            );
257227825Stheraven        }
258227825Stheraven
259227825Stheraven    template <class...> friend class __scoped_allocator_storage;
260227825Stheraven};
261227825Stheraven
262227825Stheraventemplate <class _OuterAlloc>
263227825Stheravenclass __scoped_allocator_storage<_OuterAlloc>
264227825Stheraven    : public _OuterAlloc
265227825Stheraven{
266227825Stheraven    typedef _OuterAlloc outer_allocator_type;
267227825Stheravenprotected:
268227825Stheraven    typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
269227825Stheraven
270227825Stheraven    _LIBCPP_INLINE_VISIBILITY
271227825Stheraven    __scoped_allocator_storage() _NOEXCEPT {}
272227825Stheraven
273227825Stheraven    template <class _OuterA2,
274227825Stheraven              class = typename enable_if<
275227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
276227825Stheraven                      >::type>
277227825Stheraven        _LIBCPP_INLINE_VISIBILITY
278227825Stheraven        __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
279227825Stheraven            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
280227825Stheraven
281227825Stheraven    template <class _OuterA2,
282227825Stheraven              class = typename enable_if<
283227825Stheraven                        is_constructible<outer_allocator_type, const _OuterA2&>::value
284227825Stheraven                      >::type>
285227825Stheraven        _LIBCPP_INLINE_VISIBILITY
286227825Stheraven        __scoped_allocator_storage(
287227825Stheraven            const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
288227825Stheraven            : outer_allocator_type(__other.outer_allocator()) {}
289227825Stheraven
290227825Stheraven    template <class _OuterA2,
291227825Stheraven              class = typename enable_if<
292227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
293227825Stheraven                      >::type>
294227825Stheraven        _LIBCPP_INLINE_VISIBILITY
295227825Stheraven        __scoped_allocator_storage(
296227825Stheraven            __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
297227825Stheraven            : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
298227825Stheraven
299227825Stheraven    _LIBCPP_INLINE_VISIBILITY
300227825Stheraven    inner_allocator_type& inner_allocator() _NOEXCEPT
301227825Stheraven        {return static_cast<inner_allocator_type&>(*this);}
302227825Stheraven    _LIBCPP_INLINE_VISIBILITY
303227825Stheraven    const inner_allocator_type& inner_allocator() const _NOEXCEPT
304227825Stheraven        {return static_cast<const inner_allocator_type&>(*this);}
305227825Stheraven
306227825Stheraven    _LIBCPP_INLINE_VISIBILITY
307227825Stheraven    outer_allocator_type& outer_allocator() _NOEXCEPT
308227825Stheraven        {return static_cast<outer_allocator_type&>(*this);}
309227825Stheraven    _LIBCPP_INLINE_VISIBILITY
310227825Stheraven    const outer_allocator_type& outer_allocator() const _NOEXCEPT
311227825Stheraven        {return static_cast<const outer_allocator_type&>(*this);}
312227825Stheraven
313227825Stheraven    _LIBCPP_INLINE_VISIBILITY
314227825Stheraven    scoped_allocator_adaptor<outer_allocator_type>
315227825Stheraven    select_on_container_copy_construction() const _NOEXCEPT
316227825Stheraven        {return scoped_allocator_adaptor<outer_allocator_type>(
317227825Stheraven            allocator_traits<outer_allocator_type>::
318227825Stheraven                select_on_container_copy_construction(outer_allocator())
319227825Stheraven        );}
320227825Stheraven
321227825Stheraven    __scoped_allocator_storage(const outer_allocator_type& __o,
322227825Stheraven                               const inner_allocator_type& __i) _NOEXCEPT;
323227825Stheraven
324227825Stheraven    template <class...> friend class __scoped_allocator_storage;
325227825Stheraven};
326227825Stheraven
327227825Stheraven// __outermost
328227825Stheraven
329227825Stheraventemplate <class _Alloc>
330227825Stheravendecltype(declval<_Alloc>().outer_allocator(), true_type())
331227825Stheraven__has_outer_allocator_test(_Alloc&& __a);
332227825Stheraven
333227825Stheraventemplate <class _Alloc>
334227825Stheravenfalse_type
335227825Stheraven__has_outer_allocator_test(const volatile _Alloc& __a);
336227825Stheraven
337227825Stheraventemplate <class _Alloc>
338227825Stheravenstruct __has_outer_allocator
339227825Stheraven    : public common_type
340227825Stheraven             <
341227825Stheraven                 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
342227825Stheraven             >::type
343227825Stheraven{
344227825Stheraven};
345227825Stheraven
346227825Stheraventemplate <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
347227825Stheravenstruct __outermost
348227825Stheraven{
349227825Stheraven    typedef _Alloc type;
350227825Stheraven    _LIBCPP_INLINE_VISIBILITY
351227825Stheraven    type& operator()(type& __a) const _NOEXCEPT {return __a;}
352227825Stheraven};
353227825Stheraven
354227825Stheraventemplate <class _Alloc>
355227825Stheravenstruct __outermost<_Alloc, true>
356227825Stheraven{
357227825Stheraven    typedef typename remove_reference
358227825Stheraven                     <
359227825Stheraven                        decltype(_VSTD::declval<_Alloc>().outer_allocator())
360227825Stheraven                     >::type                                    _OuterAlloc;
361227825Stheraven    typedef typename __outermost<_OuterAlloc>::type             type;
362227825Stheraven    _LIBCPP_INLINE_VISIBILITY
363227825Stheraven    type& operator()(_Alloc& __a) const _NOEXCEPT
364227825Stheraven        {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
365227825Stheraven};
366227825Stheraven
367227825Stheraventemplate <class _OuterAlloc, class... _InnerAllocs>
368261272Sdimclass _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
369227825Stheraven    : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
370227825Stheraven{
371227825Stheraven    typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
372227825Stheraven    typedef allocator_traits<_OuterAlloc>             _OuterTraits;
373227825Stheravenpublic:
374227825Stheraven    typedef _OuterAlloc                               outer_allocator_type;
375227825Stheraven    typedef typename base::inner_allocator_type       inner_allocator_type;
376227825Stheraven    typedef typename _OuterTraits::size_type          size_type;
377227825Stheraven    typedef typename _OuterTraits::difference_type    difference_type;
378227825Stheraven    typedef typename _OuterTraits::pointer            pointer;
379227825Stheraven    typedef typename _OuterTraits::const_pointer      const_pointer;
380227825Stheraven    typedef typename _OuterTraits::void_pointer       void_pointer;
381227825Stheraven    typedef typename _OuterTraits::const_void_pointer const_void_pointer;
382227825Stheraven
383227825Stheraven    typedef integral_constant
384227825Stheraven            <
385227825Stheraven                bool,
386227825Stheraven                __get_poc_copy_assignment<outer_allocator_type,
387227825Stheraven                                          _InnerAllocs...>::value
388227825Stheraven            > propagate_on_container_copy_assignment;
389227825Stheraven    typedef integral_constant
390227825Stheraven            <
391227825Stheraven                bool,
392227825Stheraven                __get_poc_move_assignment<outer_allocator_type,
393227825Stheraven                                          _InnerAllocs...>::value
394227825Stheraven            > propagate_on_container_move_assignment;
395227825Stheraven    typedef integral_constant
396227825Stheraven            <
397227825Stheraven                bool,
398227825Stheraven                __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
399227825Stheraven            > propagate_on_container_swap;
400227825Stheraven
401227825Stheraven    template <class _Tp>
402227825Stheraven    struct rebind
403227825Stheraven    {
404227825Stheraven        typedef scoped_allocator_adaptor
405227825Stheraven        <
406227825Stheraven            typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
407227825Stheraven        > other;
408227825Stheraven    };
409227825Stheraven
410227825Stheraven    _LIBCPP_INLINE_VISIBILITY
411227825Stheraven    scoped_allocator_adaptor() _NOEXCEPT {}
412227825Stheraven    template <class _OuterA2,
413227825Stheraven              class = typename enable_if<
414227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
415227825Stheraven                      >::type>
416227825Stheraven        _LIBCPP_INLINE_VISIBILITY
417227825Stheraven        scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
418227825Stheraven                                 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
419227825Stheraven            : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
420227825Stheraven    // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
421227825Stheraven    template <class _OuterA2,
422227825Stheraven              class = typename enable_if<
423227825Stheraven                        is_constructible<outer_allocator_type, const _OuterA2&>::value
424227825Stheraven                      >::type>
425227825Stheraven        _LIBCPP_INLINE_VISIBILITY
426227825Stheraven        scoped_allocator_adaptor(
427227825Stheraven            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
428227825Stheraven                : base(__other) {}
429227825Stheraven    template <class _OuterA2,
430227825Stheraven              class = typename enable_if<
431227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
432227825Stheraven                      >::type>
433227825Stheraven        _LIBCPP_INLINE_VISIBILITY
434227825Stheraven        scoped_allocator_adaptor(
435227825Stheraven            scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
436227825Stheraven                : base(_VSTD::move(__other)) {}
437227825Stheraven
438227825Stheraven    // ~scoped_allocator_adaptor() = default;
439227825Stheraven
440227825Stheraven    _LIBCPP_INLINE_VISIBILITY
441227825Stheraven    inner_allocator_type& inner_allocator() _NOEXCEPT
442227825Stheraven        {return base::inner_allocator();}
443227825Stheraven    _LIBCPP_INLINE_VISIBILITY
444227825Stheraven    const inner_allocator_type& inner_allocator() const _NOEXCEPT
445227825Stheraven        {return base::inner_allocator();}
446227825Stheraven
447227825Stheraven    _LIBCPP_INLINE_VISIBILITY
448227825Stheraven    outer_allocator_type& outer_allocator() _NOEXCEPT
449227825Stheraven        {return base::outer_allocator();}
450227825Stheraven    _LIBCPP_INLINE_VISIBILITY
451227825Stheraven    const outer_allocator_type& outer_allocator() const _NOEXCEPT
452227825Stheraven        {return base::outer_allocator();}
453227825Stheraven
454227825Stheraven    _LIBCPP_INLINE_VISIBILITY
455227825Stheraven    pointer allocate(size_type __n)
456227825Stheraven        {return allocator_traits<outer_allocator_type>::
457227825Stheraven            allocate(outer_allocator(), __n);}
458227825Stheraven    _LIBCPP_INLINE_VISIBILITY
459227825Stheraven    pointer allocate(size_type __n, const_void_pointer __hint)
460227825Stheraven        {return allocator_traits<outer_allocator_type>::
461227825Stheraven            allocate(outer_allocator(), __n, __hint);}
462227825Stheraven
463227825Stheraven    _LIBCPP_INLINE_VISIBILITY
464227825Stheraven    void deallocate(pointer __p, size_type __n) _NOEXCEPT
465227825Stheraven        {allocator_traits<outer_allocator_type>::
466227825Stheraven            deallocate(outer_allocator(), __p, __n);}
467227825Stheraven
468227825Stheraven    _LIBCPP_INLINE_VISIBILITY
469227825Stheraven    size_type max_size() const
470227825Stheraven        {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
471227825Stheraven
472227825Stheraven    template <class _Tp, class... _Args>
473227825Stheraven        _LIBCPP_INLINE_VISIBILITY
474227825Stheraven        void construct(_Tp* __p, _Args&& ...__args)
475227825Stheraven            {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
476227825Stheraven                         __p, _VSTD::forward<_Args>(__args)...);}
477227825Stheraven    template <class _Tp>
478227825Stheraven        _LIBCPP_INLINE_VISIBILITY
479227825Stheraven        void destroy(_Tp* __p)
480227825Stheraven            {
481227825Stheraven                typedef __outermost<outer_allocator_type> _OM;
482227825Stheraven                allocator_traits<typename _OM::type>::
483227825Stheraven                                         destroy(_OM()(outer_allocator()), __p);
484227825Stheraven            }
485227825Stheraven
486227825Stheraven    _LIBCPP_INLINE_VISIBILITY
487227825Stheraven    scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
488227825Stheraven        {return base::select_on_container_copy_construction();}
489227825Stheraven
490227825Stheravenprivate:
491227825Stheraven
492227825Stheraven    template <class _OuterA2,
493227825Stheraven              class = typename enable_if<
494227825Stheraven                        is_constructible<outer_allocator_type, _OuterA2>::value
495227825Stheraven                      >::type>
496227825Stheraven    _LIBCPP_INLINE_VISIBILITY
497227825Stheraven    scoped_allocator_adaptor(_OuterA2&& __o,
498227825Stheraven                             const inner_allocator_type& __i) _NOEXCEPT
499227825Stheraven        : base(_VSTD::forward<_OuterA2>(__o), __i) {}
500227825Stheraven
501227825Stheraven    template <class _Tp, class... _Args>
502227825Stheraven        _LIBCPP_INLINE_VISIBILITY
503227825Stheraven        void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
504227825Stheraven            {
505227825Stheraven                typedef __outermost<outer_allocator_type> _OM;
506227825Stheraven                allocator_traits<typename _OM::type>::construct
507227825Stheraven                (
508227825Stheraven                    _OM()(outer_allocator()),
509227825Stheraven                    __p,
510227825Stheraven                    _VSTD::forward<_Args>(__args)...
511227825Stheraven                );
512227825Stheraven            }
513227825Stheraven
514227825Stheraven    template <class _Tp, class... _Args>
515227825Stheraven        _LIBCPP_INLINE_VISIBILITY
516227825Stheraven        void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
517227825Stheraven            {
518227825Stheraven                typedef __outermost<outer_allocator_type> _OM;
519227825Stheraven                allocator_traits<typename _OM::type>::construct
520227825Stheraven                (
521227825Stheraven                    _OM()(outer_allocator()),
522227825Stheraven                    __p,
523227825Stheraven                    allocator_arg,
524227825Stheraven                    inner_allocator(),
525227825Stheraven                    _VSTD::forward<_Args>(__args)...
526227825Stheraven                );
527227825Stheraven            }
528227825Stheraven
529227825Stheraven    template <class _Tp, class... _Args>
530227825Stheraven        _LIBCPP_INLINE_VISIBILITY
531227825Stheraven        void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
532227825Stheraven            {
533227825Stheraven                typedef __outermost<outer_allocator_type> _OM;
534227825Stheraven                allocator_traits<typename _OM::type>::construct
535227825Stheraven                (
536227825Stheraven                    _OM()(outer_allocator()),
537227825Stheraven                    __p,
538227825Stheraven                    _VSTD::forward<_Args>(__args)...,
539227825Stheraven                    inner_allocator()
540227825Stheraven                );
541227825Stheraven            }
542227825Stheraven
543227825Stheraven    template <class...> friend class __scoped_allocator_storage;
544227825Stheraven};
545227825Stheraven
546227825Stheraventemplate <class _OuterA1, class _OuterA2>
547227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
548227825Stheravenbool
549227825Stheravenoperator==(const scoped_allocator_adaptor<_OuterA1>& __a,
550227825Stheraven           const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
551227825Stheraven{
552227825Stheraven    return __a.outer_allocator() == __b.outer_allocator();
553227825Stheraven}
554227825Stheraven
555227825Stheraventemplate <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
556227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
557227825Stheravenbool
558227825Stheravenoperator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
559227825Stheraven           const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
560227825Stheraven{
561227825Stheraven    return __a.outer_allocator() == __b.outer_allocator() &&
562227825Stheraven           __a.inner_allocator() == __b.inner_allocator();
563227825Stheraven}
564227825Stheraven
565227825Stheraventemplate <class _OuterA1, class _OuterA2, class... _InnerAllocs>
566227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
567227825Stheravenbool
568227825Stheravenoperator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
569227825Stheraven           const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
570227825Stheraven{
571227825Stheraven    return !(__a == __b);
572227825Stheraven}
573227825Stheraven
574227825Stheraven#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
575227825Stheraven
576227825Stheraven_LIBCPP_END_NAMESPACE_STD
577227825Stheraven
578227825Stheraven#endif  // _LIBCPP_SCOPED_ALLOCATOR
579