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