120cc2a42SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
320cc2a42SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
720cc2a42SHoward Hinnant//
820cc2a42SHoward Hinnant//===----------------------------------------------------------------------===//
920cc2a42SHoward Hinnant
1020cc2a42SHoward Hinnant#ifndef _LIBCPP_SCOPED_ALLOCATOR
1120cc2a42SHoward Hinnant#define _LIBCPP_SCOPED_ALLOCATOR
1220cc2a42SHoward Hinnant
1320cc2a42SHoward Hinnant/*
1420cc2a42SHoward Hinnant    scoped_allocator synopsis
1520cc2a42SHoward Hinnant
1620cc2a42SHoward Hinnantnamespace std
1720cc2a42SHoward Hinnant{
1820cc2a42SHoward Hinnant
1920cc2a42SHoward Hinnanttemplate <class OuterAlloc, class... InnerAllocs>
2020cc2a42SHoward Hinnantclass scoped_allocator_adaptor : public OuterAlloc
2120cc2a42SHoward Hinnant{
2220cc2a42SHoward Hinnant    typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
2320cc2a42SHoward Hinnant    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
2420cc2a42SHoward Hinnantpublic:
2520cc2a42SHoward Hinnant
2620cc2a42SHoward Hinnant    typedef OuterAlloc outer_allocator_type;
2720cc2a42SHoward Hinnant    typedef see below inner_allocator_type;
2820cc2a42SHoward Hinnant
2920cc2a42SHoward Hinnant    typedef typename OuterTraits::value_type value_type;
3020cc2a42SHoward Hinnant    typedef typename OuterTraits::size_type size_type;
3120cc2a42SHoward Hinnant    typedef typename OuterTraits::difference_type difference_type;
3220cc2a42SHoward Hinnant    typedef typename OuterTraits::pointer pointer;
3320cc2a42SHoward Hinnant    typedef typename OuterTraits::const_pointer const_pointer;
3420cc2a42SHoward Hinnant    typedef typename OuterTraits::void_pointer void_pointer;
3520cc2a42SHoward Hinnant    typedef typename OuterTraits::const_void_pointer const_void_pointer;
3620cc2a42SHoward Hinnant
3720cc2a42SHoward Hinnant    typedef see below propagate_on_container_copy_assignment;
3820cc2a42SHoward Hinnant    typedef see below propagate_on_container_move_assignment;
3920cc2a42SHoward Hinnant    typedef see below propagate_on_container_swap;
4031a47313SMarshall Clow    typedef see below is_always_equal;
4120cc2a42SHoward Hinnant
4220cc2a42SHoward Hinnant    template <class Tp>
4320cc2a42SHoward Hinnant        struct rebind
4420cc2a42SHoward Hinnant        {
4520cc2a42SHoward Hinnant            typedef scoped_allocator_adaptor<
4620cc2a42SHoward Hinnant                OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
4720cc2a42SHoward Hinnant        };
4820cc2a42SHoward Hinnant
4920cc2a42SHoward Hinnant    scoped_allocator_adaptor();
5020cc2a42SHoward Hinnant    template <class OuterA2>
5120cc2a42SHoward Hinnant        scoped_allocator_adaptor(OuterA2&& outerAlloc,
52cfd52789SHoward Hinnant                                 const InnerAllocs&... innerAllocs) noexcept;
53cfd52789SHoward Hinnant    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
54cfd52789SHoward Hinnant    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
5520cc2a42SHoward Hinnant    template <class OuterA2>
56cfd52789SHoward Hinnant        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
5720cc2a42SHoward Hinnant    template <class OuterA2>
58cfd52789SHoward Hinnant        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
5920cc2a42SHoward Hinnant
60cd5215d8SMarshall Clow    scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
61cd5215d8SMarshall Clow    scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
6220cc2a42SHoward Hinnant    ~scoped_allocator_adaptor();
6320cc2a42SHoward Hinnant
64cfd52789SHoward Hinnant    inner_allocator_type& inner_allocator() noexcept;
65cfd52789SHoward Hinnant    const inner_allocator_type& inner_allocator() const noexcept;
6620cc2a42SHoward Hinnant
67cfd52789SHoward Hinnant    outer_allocator_type& outer_allocator() noexcept;
68cfd52789SHoward Hinnant    const outer_allocator_type& outer_allocator() const noexcept;
6920cc2a42SHoward Hinnant
703fddff51SMarshall Clow    pointer allocate(size_type n);                           // [[nodiscard]] in C++20
713fddff51SMarshall Clow    pointer allocate(size_type n, const_void_pointer hint);  // [[nodiscard]] in C++20
72cfd52789SHoward Hinnant    void deallocate(pointer p, size_type n) noexcept;
7320cc2a42SHoward Hinnant
7420cc2a42SHoward Hinnant    size_type max_size() const;
7520cc2a42SHoward Hinnant    template <class T, class... Args> void construct(T* p, Args&& args);
7620cc2a42SHoward Hinnant    template <class T1, class T2, class... Args1, class... Args2>
7720cc2a42SHoward Hinnant        void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
7820cc2a42SHoward Hinnant                       tuple<Args2...> y);
7920cc2a42SHoward Hinnant    template <class T1, class T2>
8020cc2a42SHoward Hinnant        void construct(pair<T1, T2>* p);
8120cc2a42SHoward Hinnant    template <class T1, class T2, class U, class V>
8220cc2a42SHoward Hinnant        void construct(pair<T1, T2>* p, U&& x, V&& y);
8320cc2a42SHoward Hinnant    template <class T1, class T2, class U, class V>
8420cc2a42SHoward Hinnant        void construct(pair<T1, T2>* p, const pair<U, V>& x);
8520cc2a42SHoward Hinnant    template <class T1, class T2, class U, class V>
8620cc2a42SHoward Hinnant        void construct(pair<T1, T2>* p, pair<U, V>&& x);
8720cc2a42SHoward Hinnant    template <class T> void destroy(T* p);
8820cc2a42SHoward Hinnant
89cfd52789SHoward Hinnant    template <class T> void destroy(T* p) noexcept;
90cfd52789SHoward Hinnant
91cfd52789SHoward Hinnant    scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
9220cc2a42SHoward Hinnant};
9320cc2a42SHoward Hinnant
94f9f97caeSKonstantin Varlamovtemplate<class OuterAlloc, class... InnerAllocs>
95f9f97caeSKonstantin Varlamov    scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
96f9f97caeSKonstantin Varlamov        -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
97f9f97caeSKonstantin Varlamov
9820cc2a42SHoward Hinnanttemplate <class OuterA1, class OuterA2, class... InnerAllocs>
9920cc2a42SHoward Hinnant    bool
10020cc2a42SHoward Hinnant    operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
101cfd52789SHoward Hinnant               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
10220cc2a42SHoward Hinnant
10320cc2a42SHoward Hinnanttemplate <class OuterA1, class OuterA2, class... InnerAllocs>
10420cc2a42SHoward Hinnant    bool
10520cc2a42SHoward Hinnant    operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
106cfd52789SHoward Hinnant               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
10720cc2a42SHoward Hinnant
10820cc2a42SHoward Hinnant}  // std
10920cc2a42SHoward Hinnant
11020cc2a42SHoward Hinnant*/
11120cc2a42SHoward Hinnant
112385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
11320cc2a42SHoward Hinnant#include <__config>
1146adbc83eSChristopher Di Bella#include <__utility/forward.h>
11520cc2a42SHoward Hinnant#include <memory>
116f56972e2SMarshall Clow#include <version>
11720cc2a42SHoward Hinnant
118073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
11920cc2a42SHoward Hinnant#  pragma GCC system_header
120073458b1SHoward Hinnant#endif
12120cc2a42SHoward Hinnant
12220cc2a42SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
12320cc2a42SHoward Hinnant
12454613ab4SEric Fiselier#if !defined(_LIBCPP_CXX03_LANG)
12520cc2a42SHoward Hinnant
12620cc2a42SHoward Hinnant// scoped_allocator_adaptor
12720cc2a42SHoward Hinnant
12820cc2a42SHoward Hinnanttemplate <class ..._Allocs>
12920cc2a42SHoward Hinnantclass scoped_allocator_adaptor;
13020cc2a42SHoward Hinnant
13120cc2a42SHoward Hinnanttemplate <class ..._Allocs> struct __get_poc_copy_assignment;
13220cc2a42SHoward Hinnant
13320cc2a42SHoward Hinnanttemplate <class _A0>
13420cc2a42SHoward Hinnantstruct __get_poc_copy_assignment<_A0>
13520cc2a42SHoward Hinnant{
13620cc2a42SHoward Hinnant    static const bool value = allocator_traits<_A0>::
13720cc2a42SHoward Hinnant                              propagate_on_container_copy_assignment::value;
13820cc2a42SHoward Hinnant};
13920cc2a42SHoward Hinnant
14020cc2a42SHoward Hinnanttemplate <class _A0, class ..._Allocs>
14120cc2a42SHoward Hinnantstruct __get_poc_copy_assignment<_A0, _Allocs...>
14220cc2a42SHoward Hinnant{
14320cc2a42SHoward Hinnant    static const bool value =
14420cc2a42SHoward Hinnant        allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
14520cc2a42SHoward Hinnant        __get_poc_copy_assignment<_Allocs...>::value;
14620cc2a42SHoward Hinnant};
14720cc2a42SHoward Hinnant
14820cc2a42SHoward Hinnanttemplate <class ..._Allocs> struct __get_poc_move_assignment;
14920cc2a42SHoward Hinnant
15020cc2a42SHoward Hinnanttemplate <class _A0>
15120cc2a42SHoward Hinnantstruct __get_poc_move_assignment<_A0>
15220cc2a42SHoward Hinnant{
15320cc2a42SHoward Hinnant    static const bool value = allocator_traits<_A0>::
15420cc2a42SHoward Hinnant                              propagate_on_container_move_assignment::value;
15520cc2a42SHoward Hinnant};
15620cc2a42SHoward Hinnant
15720cc2a42SHoward Hinnanttemplate <class _A0, class ..._Allocs>
15820cc2a42SHoward Hinnantstruct __get_poc_move_assignment<_A0, _Allocs...>
15920cc2a42SHoward Hinnant{
16020cc2a42SHoward Hinnant    static const bool value =
16120cc2a42SHoward Hinnant        allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
16220cc2a42SHoward Hinnant        __get_poc_move_assignment<_Allocs...>::value;
16320cc2a42SHoward Hinnant};
16420cc2a42SHoward Hinnant
16520cc2a42SHoward Hinnanttemplate <class ..._Allocs> struct __get_poc_swap;
16620cc2a42SHoward Hinnant
16720cc2a42SHoward Hinnanttemplate <class _A0>
16820cc2a42SHoward Hinnantstruct __get_poc_swap<_A0>
16920cc2a42SHoward Hinnant{
17020cc2a42SHoward Hinnant    static const bool value = allocator_traits<_A0>::
17120cc2a42SHoward Hinnant                              propagate_on_container_swap::value;
17220cc2a42SHoward Hinnant};
17320cc2a42SHoward Hinnant
17420cc2a42SHoward Hinnanttemplate <class _A0, class ..._Allocs>
17520cc2a42SHoward Hinnantstruct __get_poc_swap<_A0, _Allocs...>
17620cc2a42SHoward Hinnant{
17720cc2a42SHoward Hinnant    static const bool value =
17820cc2a42SHoward Hinnant        allocator_traits<_A0>::propagate_on_container_swap::value ||
17920cc2a42SHoward Hinnant        __get_poc_swap<_Allocs...>::value;
18020cc2a42SHoward Hinnant};
18120cc2a42SHoward Hinnant
1828880c208SMarshall Clowtemplate <class ..._Allocs> struct __get_is_always_equal;
1838880c208SMarshall Clow
1848880c208SMarshall Clowtemplate <class _A0>
1858880c208SMarshall Clowstruct __get_is_always_equal<_A0>
1868880c208SMarshall Clow{
1878880c208SMarshall Clow    static const bool value = allocator_traits<_A0>::is_always_equal::value;
1888880c208SMarshall Clow};
1898880c208SMarshall Clow
19031a47313SMarshall Clowtemplate <class _A0, class ..._Allocs>
1918880c208SMarshall Clowstruct __get_is_always_equal<_A0, _Allocs...>
19231a47313SMarshall Clow{
19331a47313SMarshall Clow    static const bool value =
1942abfcd56SMarshall Clow        allocator_traits<_A0>::is_always_equal::value &&
1958880c208SMarshall Clow        __get_is_always_equal<_Allocs...>::value;
19631a47313SMarshall Clow};
19731a47313SMarshall Clow
19820cc2a42SHoward Hinnanttemplate <class ..._Allocs>
19920cc2a42SHoward Hinnantclass __scoped_allocator_storage;
20020cc2a42SHoward Hinnant
20120cc2a42SHoward Hinnanttemplate <class _OuterAlloc, class... _InnerAllocs>
20220cc2a42SHoward Hinnantclass __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
20320cc2a42SHoward Hinnant    : public _OuterAlloc
20420cc2a42SHoward Hinnant{
20520cc2a42SHoward Hinnant    typedef _OuterAlloc outer_allocator_type;
20620cc2a42SHoward Hinnantprotected:
20720cc2a42SHoward Hinnant    typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
20820cc2a42SHoward Hinnant
20920cc2a42SHoward Hinnantprivate:
21020cc2a42SHoward Hinnant    inner_allocator_type __inner_;
21120cc2a42SHoward Hinnant
21220cc2a42SHoward Hinnantprotected:
21320cc2a42SHoward Hinnant
21453ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
215cfd52789SHoward Hinnant    __scoped_allocator_storage() _NOEXCEPT {}
21620cc2a42SHoward Hinnant
21720cc2a42SHoward Hinnant    template <class _OuterA2,
21820cc2a42SHoward Hinnant              class = typename enable_if<
21920cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
22020cc2a42SHoward Hinnant                      >::type>
22153ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
222*b48c5010SNikolas Klauser        __scoped_allocator_storage(_OuterA2&& __outer_alloc,
223*b48c5010SNikolas Klauser                                   const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
224*b48c5010SNikolas Klauser            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)),
225*b48c5010SNikolas Klauser              __inner_(__inner_allocs...) {}
22620cc2a42SHoward Hinnant
22720cc2a42SHoward Hinnant    template <class _OuterA2,
22820cc2a42SHoward Hinnant              class = typename enable_if<
22920cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, const _OuterA2&>::value
23020cc2a42SHoward Hinnant                      >::type>
23153ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
23220cc2a42SHoward Hinnant        __scoped_allocator_storage(
233cfd52789SHoward Hinnant            const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
23420cc2a42SHoward Hinnant            : outer_allocator_type(__other.outer_allocator()),
23520cc2a42SHoward Hinnant              __inner_(__other.inner_allocator()) {}
23620cc2a42SHoward Hinnant
23720cc2a42SHoward Hinnant    template <class _OuterA2,
23820cc2a42SHoward Hinnant              class = typename enable_if<
23920cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
24020cc2a42SHoward Hinnant                      >::type>
24153ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
24220cc2a42SHoward Hinnant        __scoped_allocator_storage(
243cfd52789SHoward Hinnant            __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
244ce48a113SHoward Hinnant            : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
245ce48a113SHoward Hinnant              __inner_(_VSTD::move(__other.inner_allocator())) {}
24620cc2a42SHoward Hinnant
24720cc2a42SHoward Hinnant    template <class _OuterA2,
24820cc2a42SHoward Hinnant              class = typename enable_if<
24920cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
25020cc2a42SHoward Hinnant                      >::type>
25153ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
25220cc2a42SHoward Hinnant        __scoped_allocator_storage(_OuterA2&& __o,
253cfd52789SHoward Hinnant                                   const inner_allocator_type& __i) _NOEXCEPT
254ce48a113SHoward Hinnant            : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
25520cc2a42SHoward Hinnant              __inner_(__i)
25620cc2a42SHoward Hinnant        {
25720cc2a42SHoward Hinnant        }
25820cc2a42SHoward Hinnant
25953ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
260cfd52789SHoward Hinnant    inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}
26153ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
262cfd52789SHoward Hinnant    const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
26320cc2a42SHoward Hinnant
26453ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
265cfd52789SHoward Hinnant    outer_allocator_type& outer_allocator() _NOEXCEPT
26620cc2a42SHoward Hinnant        {return static_cast<outer_allocator_type&>(*this);}
26753ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
268cfd52789SHoward Hinnant    const outer_allocator_type& outer_allocator() const _NOEXCEPT
26920cc2a42SHoward Hinnant        {return static_cast<const outer_allocator_type&>(*this);}
27020cc2a42SHoward Hinnant
27120cc2a42SHoward Hinnant    scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
27253ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
273cfd52789SHoward Hinnant    select_on_container_copy_construction() const _NOEXCEPT
27420cc2a42SHoward Hinnant        {
27520cc2a42SHoward Hinnant            return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
27620cc2a42SHoward Hinnant            (
27720cc2a42SHoward Hinnant                allocator_traits<outer_allocator_type>::
27820cc2a42SHoward Hinnant                    select_on_container_copy_construction(outer_allocator()),
27920cc2a42SHoward Hinnant                allocator_traits<inner_allocator_type>::
28020cc2a42SHoward Hinnant                    select_on_container_copy_construction(inner_allocator())
28120cc2a42SHoward Hinnant            );
28220cc2a42SHoward Hinnant        }
28320cc2a42SHoward Hinnant
28420cc2a42SHoward Hinnant    template <class...> friend class __scoped_allocator_storage;
28520cc2a42SHoward Hinnant};
28620cc2a42SHoward Hinnant
28720cc2a42SHoward Hinnanttemplate <class _OuterAlloc>
28820cc2a42SHoward Hinnantclass __scoped_allocator_storage<_OuterAlloc>
28920cc2a42SHoward Hinnant    : public _OuterAlloc
29020cc2a42SHoward Hinnant{
29120cc2a42SHoward Hinnant    typedef _OuterAlloc outer_allocator_type;
29220cc2a42SHoward Hinnantprotected:
29320cc2a42SHoward Hinnant    typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
29420cc2a42SHoward Hinnant
29553ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
296cfd52789SHoward Hinnant    __scoped_allocator_storage() _NOEXCEPT {}
29720cc2a42SHoward Hinnant
29820cc2a42SHoward Hinnant    template <class _OuterA2,
29920cc2a42SHoward Hinnant              class = typename enable_if<
30020cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
30120cc2a42SHoward Hinnant                      >::type>
30253ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
303*b48c5010SNikolas Klauser        __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT
304*b48c5010SNikolas Klauser            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)) {}
30520cc2a42SHoward Hinnant
30620cc2a42SHoward Hinnant    template <class _OuterA2,
30720cc2a42SHoward Hinnant              class = typename enable_if<
30820cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, const _OuterA2&>::value
30920cc2a42SHoward Hinnant                      >::type>
31053ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
31120cc2a42SHoward Hinnant        __scoped_allocator_storage(
312cfd52789SHoward Hinnant            const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
31320cc2a42SHoward Hinnant            : outer_allocator_type(__other.outer_allocator()) {}
31420cc2a42SHoward Hinnant
31520cc2a42SHoward Hinnant    template <class _OuterA2,
31620cc2a42SHoward Hinnant              class = typename enable_if<
31720cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
31820cc2a42SHoward Hinnant                      >::type>
31953ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
32020cc2a42SHoward Hinnant        __scoped_allocator_storage(
321cfd52789SHoward Hinnant            __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
322ce48a113SHoward Hinnant            : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
32320cc2a42SHoward Hinnant
32453ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
325cfd52789SHoward Hinnant    inner_allocator_type& inner_allocator() _NOEXCEPT
32620cc2a42SHoward Hinnant        {return static_cast<inner_allocator_type&>(*this);}
32753ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
328cfd52789SHoward Hinnant    const inner_allocator_type& inner_allocator() const _NOEXCEPT
32920cc2a42SHoward Hinnant        {return static_cast<const inner_allocator_type&>(*this);}
33020cc2a42SHoward Hinnant
33153ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
332cfd52789SHoward Hinnant    outer_allocator_type& outer_allocator() _NOEXCEPT
33320cc2a42SHoward Hinnant        {return static_cast<outer_allocator_type&>(*this);}
33453ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
335cfd52789SHoward Hinnant    const outer_allocator_type& outer_allocator() const _NOEXCEPT
33620cc2a42SHoward Hinnant        {return static_cast<const outer_allocator_type&>(*this);}
33720cc2a42SHoward Hinnant
33853ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
33920cc2a42SHoward Hinnant    scoped_allocator_adaptor<outer_allocator_type>
340cfd52789SHoward Hinnant    select_on_container_copy_construction() const _NOEXCEPT
34120cc2a42SHoward Hinnant        {return scoped_allocator_adaptor<outer_allocator_type>(
34220cc2a42SHoward Hinnant            allocator_traits<outer_allocator_type>::
34320cc2a42SHoward Hinnant                select_on_container_copy_construction(outer_allocator())
34420cc2a42SHoward Hinnant        );}
34520cc2a42SHoward Hinnant
34620cc2a42SHoward Hinnant    __scoped_allocator_storage(const outer_allocator_type& __o,
347cfd52789SHoward Hinnant                               const inner_allocator_type& __i) _NOEXCEPT;
34820cc2a42SHoward Hinnant
34920cc2a42SHoward Hinnant    template <class...> friend class __scoped_allocator_storage;
35020cc2a42SHoward Hinnant};
35120cc2a42SHoward Hinnant
35220cc2a42SHoward Hinnant// __outermost
35320cc2a42SHoward Hinnant
35420cc2a42SHoward Hinnanttemplate <class _Alloc>
35520cc2a42SHoward Hinnantdecltype(declval<_Alloc>().outer_allocator(), true_type())
35620cc2a42SHoward Hinnant__has_outer_allocator_test(_Alloc&& __a);
35720cc2a42SHoward Hinnant
35820cc2a42SHoward Hinnanttemplate <class _Alloc>
35920cc2a42SHoward Hinnantfalse_type
36020cc2a42SHoward Hinnant__has_outer_allocator_test(const volatile _Alloc& __a);
36120cc2a42SHoward Hinnant
36220cc2a42SHoward Hinnanttemplate <class _Alloc>
36320cc2a42SHoward Hinnantstruct __has_outer_allocator
36420cc2a42SHoward Hinnant    : public common_type
36520cc2a42SHoward Hinnant             <
36620cc2a42SHoward Hinnant                 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
36720cc2a42SHoward Hinnant             >::type
36820cc2a42SHoward Hinnant{
36920cc2a42SHoward Hinnant};
37020cc2a42SHoward Hinnant
37120cc2a42SHoward Hinnanttemplate <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
37220cc2a42SHoward Hinnantstruct __outermost
37320cc2a42SHoward Hinnant{
37420cc2a42SHoward Hinnant    typedef _Alloc type;
37553ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
376cfd52789SHoward Hinnant    type& operator()(type& __a) const _NOEXCEPT {return __a;}
37720cc2a42SHoward Hinnant};
37820cc2a42SHoward Hinnant
37920cc2a42SHoward Hinnanttemplate <class _Alloc>
38020cc2a42SHoward Hinnantstruct __outermost<_Alloc, true>
38120cc2a42SHoward Hinnant{
38220cc2a42SHoward Hinnant    typedef typename remove_reference
38320cc2a42SHoward Hinnant                     <
384ab3fcc50SArthur O'Dwyer                        decltype(declval<_Alloc>().outer_allocator())
38520cc2a42SHoward Hinnant                     >::type                                    _OuterAlloc;
38620cc2a42SHoward Hinnant    typedef typename __outermost<_OuterAlloc>::type             type;
38753ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
388cfd52789SHoward Hinnant    type& operator()(_Alloc& __a) const _NOEXCEPT
38920cc2a42SHoward Hinnant        {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
39020cc2a42SHoward Hinnant};
39120cc2a42SHoward Hinnant
39220cc2a42SHoward Hinnanttemplate <class _OuterAlloc, class... _InnerAllocs>
393e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
39420cc2a42SHoward Hinnant    : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
39520cc2a42SHoward Hinnant{
39620cc2a42SHoward Hinnant    typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
39720cc2a42SHoward Hinnant    typedef allocator_traits<_OuterAlloc>             _OuterTraits;
39820cc2a42SHoward Hinnantpublic:
39920cc2a42SHoward Hinnant    typedef _OuterAlloc                               outer_allocator_type;
40020cc2a42SHoward Hinnant    typedef typename base::inner_allocator_type       inner_allocator_type;
40120cc2a42SHoward Hinnant    typedef typename _OuterTraits::size_type          size_type;
40220cc2a42SHoward Hinnant    typedef typename _OuterTraits::difference_type    difference_type;
40320cc2a42SHoward Hinnant    typedef typename _OuterTraits::pointer            pointer;
40420cc2a42SHoward Hinnant    typedef typename _OuterTraits::const_pointer      const_pointer;
40520cc2a42SHoward Hinnant    typedef typename _OuterTraits::void_pointer       void_pointer;
40620cc2a42SHoward Hinnant    typedef typename _OuterTraits::const_void_pointer const_void_pointer;
40720cc2a42SHoward Hinnant
40820cc2a42SHoward Hinnant    typedef integral_constant
40920cc2a42SHoward Hinnant            <
41020cc2a42SHoward Hinnant                bool,
41120cc2a42SHoward Hinnant                __get_poc_copy_assignment<outer_allocator_type,
41220cc2a42SHoward Hinnant                                          _InnerAllocs...>::value
41320cc2a42SHoward Hinnant            > propagate_on_container_copy_assignment;
41420cc2a42SHoward Hinnant    typedef integral_constant
41520cc2a42SHoward Hinnant            <
41620cc2a42SHoward Hinnant                bool,
41720cc2a42SHoward Hinnant                __get_poc_move_assignment<outer_allocator_type,
41820cc2a42SHoward Hinnant                                          _InnerAllocs...>::value
41920cc2a42SHoward Hinnant            > propagate_on_container_move_assignment;
42020cc2a42SHoward Hinnant    typedef integral_constant
42120cc2a42SHoward Hinnant            <
42220cc2a42SHoward Hinnant                bool,
42320cc2a42SHoward Hinnant                __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
42420cc2a42SHoward Hinnant            > propagate_on_container_swap;
42531a47313SMarshall Clow    typedef integral_constant
42631a47313SMarshall Clow            <
42731a47313SMarshall Clow                bool,
4288880c208SMarshall Clow                __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
42931a47313SMarshall Clow            > is_always_equal;
43020cc2a42SHoward Hinnant
43120cc2a42SHoward Hinnant    template <class _Tp>
43220cc2a42SHoward Hinnant    struct rebind
43320cc2a42SHoward Hinnant    {
43420cc2a42SHoward Hinnant        typedef scoped_allocator_adaptor
43520cc2a42SHoward Hinnant        <
43620cc2a42SHoward Hinnant            typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
43720cc2a42SHoward Hinnant        > other;
43820cc2a42SHoward Hinnant    };
43920cc2a42SHoward Hinnant
44053ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
441cfd52789SHoward Hinnant    scoped_allocator_adaptor() _NOEXCEPT {}
44220cc2a42SHoward Hinnant    template <class _OuterA2,
44320cc2a42SHoward Hinnant              class = typename enable_if<
44420cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
44520cc2a42SHoward Hinnant                      >::type>
44653ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
447*b48c5010SNikolas Klauser        scoped_allocator_adaptor(_OuterA2&& __outer_alloc,
448*b48c5010SNikolas Klauser                                 const _InnerAllocs& ...__inner_allocs) _NOEXCEPT
449*b48c5010SNikolas Klauser            : base(_VSTD::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {}
45020cc2a42SHoward Hinnant    // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
45120cc2a42SHoward Hinnant    template <class _OuterA2,
45220cc2a42SHoward Hinnant              class = typename enable_if<
45320cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, const _OuterA2&>::value
45420cc2a42SHoward Hinnant                      >::type>
45553ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
45620cc2a42SHoward Hinnant        scoped_allocator_adaptor(
457cfd52789SHoward Hinnant            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
45820cc2a42SHoward Hinnant                : base(__other) {}
45920cc2a42SHoward Hinnant    template <class _OuterA2,
46020cc2a42SHoward Hinnant              class = typename enable_if<
46120cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
46220cc2a42SHoward Hinnant                      >::type>
46353ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
46420cc2a42SHoward Hinnant        scoped_allocator_adaptor(
465cfd52789SHoward Hinnant            scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
466ce48a113SHoward Hinnant                : base(_VSTD::move(__other)) {}
46720cc2a42SHoward Hinnant
468cd5215d8SMarshall Clow    // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
469cd5215d8SMarshall Clow    // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
47020cc2a42SHoward Hinnant    // ~scoped_allocator_adaptor() = default;
47120cc2a42SHoward Hinnant
47253ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
473cfd52789SHoward Hinnant    inner_allocator_type& inner_allocator() _NOEXCEPT
47420cc2a42SHoward Hinnant        {return base::inner_allocator();}
47553ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
476cfd52789SHoward Hinnant    const inner_allocator_type& inner_allocator() const _NOEXCEPT
47720cc2a42SHoward Hinnant        {return base::inner_allocator();}
47820cc2a42SHoward Hinnant
47953ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
480cfd52789SHoward Hinnant    outer_allocator_type& outer_allocator() _NOEXCEPT
48120cc2a42SHoward Hinnant        {return base::outer_allocator();}
48253ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
483cfd52789SHoward Hinnant    const outer_allocator_type& outer_allocator() const _NOEXCEPT
48420cc2a42SHoward Hinnant        {return base::outer_allocator();}
48520cc2a42SHoward Hinnant
4863fddff51SMarshall Clow    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
48720cc2a42SHoward Hinnant    pointer allocate(size_type __n)
48820cc2a42SHoward Hinnant        {return allocator_traits<outer_allocator_type>::
48920cc2a42SHoward Hinnant            allocate(outer_allocator(), __n);}
4903fddff51SMarshall Clow    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
49120cc2a42SHoward Hinnant    pointer allocate(size_type __n, const_void_pointer __hint)
49220cc2a42SHoward Hinnant        {return allocator_traits<outer_allocator_type>::
49320cc2a42SHoward Hinnant            allocate(outer_allocator(), __n, __hint);}
49420cc2a42SHoward Hinnant
49553ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
496cfd52789SHoward Hinnant    void deallocate(pointer __p, size_type __n) _NOEXCEPT
49720cc2a42SHoward Hinnant        {allocator_traits<outer_allocator_type>::
49820cc2a42SHoward Hinnant            deallocate(outer_allocator(), __p, __n);}
49920cc2a42SHoward Hinnant
50053ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
50120cc2a42SHoward Hinnant    size_type max_size() const
50253ec0b4eSHoward Hinnant        {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
50320cc2a42SHoward Hinnant
50420cc2a42SHoward Hinnant    template <class _Tp, class... _Args>
50553ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
50620cc2a42SHoward Hinnant        void construct(_Tp* __p, _Args&& ...__args)
5074ffd08caSEric Fiselier            {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
508ce48a113SHoward Hinnant                         __p, _VSTD::forward<_Args>(__args)...);}
5094ffd08caSEric Fiselier
5104ffd08caSEric Fiselier    template <class _T1, class _T2, class... _Args1, class... _Args2>
5114ffd08caSEric Fiselier    void construct(pair<_T1, _T2>* __p, piecewise_construct_t,
5124ffd08caSEric Fiselier                       tuple<_Args1...> __x, tuple<_Args2...> __y)
5134ffd08caSEric Fiselier    {
5144ffd08caSEric Fiselier        typedef __outermost<outer_allocator_type> _OM;
5154ffd08caSEric Fiselier        allocator_traits<typename _OM::type>::construct(
5164ffd08caSEric Fiselier            _OM()(outer_allocator()), __p, piecewise_construct
5174ffd08caSEric Fiselier          , __transform_tuple(
5184ffd08caSEric Fiselier              typename __uses_alloc_ctor<
5194ffd08caSEric Fiselier                  _T1, inner_allocator_type&, _Args1...
5204ffd08caSEric Fiselier              >::type()
5214ffd08caSEric Fiselier            , _VSTD::move(__x)
5224ffd08caSEric Fiselier            , typename __make_tuple_indices<sizeof...(_Args1)>::type{}
5234ffd08caSEric Fiselier          )
5244ffd08caSEric Fiselier          , __transform_tuple(
5254ffd08caSEric Fiselier              typename __uses_alloc_ctor<
5264ffd08caSEric Fiselier                  _T2, inner_allocator_type&, _Args2...
5274ffd08caSEric Fiselier              >::type()
5284ffd08caSEric Fiselier            , _VSTD::move(__y)
5294ffd08caSEric Fiselier            , typename __make_tuple_indices<sizeof...(_Args2)>::type{}
5304ffd08caSEric Fiselier          )
5314ffd08caSEric Fiselier        );
5324ffd08caSEric Fiselier    }
5334ffd08caSEric Fiselier
5344ffd08caSEric Fiselier    template <class _T1, class _T2>
5354ffd08caSEric Fiselier    void construct(pair<_T1, _T2>* __p)
5364ffd08caSEric Fiselier    { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); }
5374ffd08caSEric Fiselier
5384ffd08caSEric Fiselier    template <class _T1, class _T2, class _Up, class _Vp>
5394ffd08caSEric Fiselier    void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) {
5404ffd08caSEric Fiselier        construct(__p, piecewise_construct,
5414ffd08caSEric Fiselier                  _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)),
5424ffd08caSEric Fiselier                  _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y)));
5434ffd08caSEric Fiselier    }
5444ffd08caSEric Fiselier
5454ffd08caSEric Fiselier    template <class _T1, class _T2, class _Up, class _Vp>
5464ffd08caSEric Fiselier    void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) {
5474ffd08caSEric Fiselier        construct(__p, piecewise_construct,
5484ffd08caSEric Fiselier                  _VSTD::forward_as_tuple(__x.first),
5494ffd08caSEric Fiselier                  _VSTD::forward_as_tuple(__x.second));
5504ffd08caSEric Fiselier    }
5514ffd08caSEric Fiselier
5524ffd08caSEric Fiselier    template <class _T1, class _T2, class _Up, class _Vp>
5534ffd08caSEric Fiselier    void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) {
5544ffd08caSEric Fiselier        construct(__p, piecewise_construct,
5554ffd08caSEric Fiselier                  _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)),
5564ffd08caSEric Fiselier                  _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second)));
5574ffd08caSEric Fiselier    }
5584ffd08caSEric Fiselier
55920cc2a42SHoward Hinnant    template <class _Tp>
56053ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
56120cc2a42SHoward Hinnant        void destroy(_Tp* __p)
56220cc2a42SHoward Hinnant            {
56320cc2a42SHoward Hinnant                typedef __outermost<outer_allocator_type> _OM;
56420cc2a42SHoward Hinnant                allocator_traits<typename _OM::type>::
56520cc2a42SHoward Hinnant                                         destroy(_OM()(outer_allocator()), __p);
56620cc2a42SHoward Hinnant            }
56720cc2a42SHoward Hinnant
56853ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
569cfd52789SHoward Hinnant    scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
57020cc2a42SHoward Hinnant        {return base::select_on_container_copy_construction();}
57120cc2a42SHoward Hinnant
57220cc2a42SHoward Hinnantprivate:
57320cc2a42SHoward Hinnant
5744ffd08caSEric Fiselier
57520cc2a42SHoward Hinnant    template <class _OuterA2,
57620cc2a42SHoward Hinnant              class = typename enable_if<
57720cc2a42SHoward Hinnant                        is_constructible<outer_allocator_type, _OuterA2>::value
57820cc2a42SHoward Hinnant                      >::type>
57953ec0b4eSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
58020cc2a42SHoward Hinnant    scoped_allocator_adaptor(_OuterA2&& __o,
581cfd52789SHoward Hinnant                             const inner_allocator_type& __i) _NOEXCEPT
582ce48a113SHoward Hinnant        : base(_VSTD::forward<_OuterA2>(__o), __i) {}
58320cc2a42SHoward Hinnant
58420cc2a42SHoward Hinnant    template <class _Tp, class... _Args>
58553ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
58620cc2a42SHoward Hinnant        void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
58720cc2a42SHoward Hinnant            {
58820cc2a42SHoward Hinnant                typedef __outermost<outer_allocator_type> _OM;
58920cc2a42SHoward Hinnant                allocator_traits<typename _OM::type>::construct
59020cc2a42SHoward Hinnant                (
59120cc2a42SHoward Hinnant                    _OM()(outer_allocator()),
59220cc2a42SHoward Hinnant                    __p,
593ce48a113SHoward Hinnant                    _VSTD::forward<_Args>(__args)...
59420cc2a42SHoward Hinnant                );
59520cc2a42SHoward Hinnant            }
59620cc2a42SHoward Hinnant
59720cc2a42SHoward Hinnant    template <class _Tp, class... _Args>
59853ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
59920cc2a42SHoward Hinnant        void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
60020cc2a42SHoward Hinnant            {
60120cc2a42SHoward Hinnant                typedef __outermost<outer_allocator_type> _OM;
60220cc2a42SHoward Hinnant                allocator_traits<typename _OM::type>::construct
60320cc2a42SHoward Hinnant                (
60420cc2a42SHoward Hinnant                    _OM()(outer_allocator()),
6054ffd08caSEric Fiselier                    __p, allocator_arg, inner_allocator(),
606ce48a113SHoward Hinnant                    _VSTD::forward<_Args>(__args)...
60720cc2a42SHoward Hinnant                );
60820cc2a42SHoward Hinnant            }
60920cc2a42SHoward Hinnant
61020cc2a42SHoward Hinnant    template <class _Tp, class... _Args>
61153ec0b4eSHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
61220cc2a42SHoward Hinnant        void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
61320cc2a42SHoward Hinnant            {
61420cc2a42SHoward Hinnant                typedef __outermost<outer_allocator_type> _OM;
61520cc2a42SHoward Hinnant                allocator_traits<typename _OM::type>::construct
61620cc2a42SHoward Hinnant                (
61720cc2a42SHoward Hinnant                    _OM()(outer_allocator()),
61820cc2a42SHoward Hinnant                    __p,
619ce48a113SHoward Hinnant                    _VSTD::forward<_Args>(__args)...,
62020cc2a42SHoward Hinnant                    inner_allocator()
62120cc2a42SHoward Hinnant                );
62220cc2a42SHoward Hinnant            }
62320cc2a42SHoward Hinnant
6244ffd08caSEric Fiselier    template <class ..._Args, size_t ..._Idx>
6254ffd08caSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
6264ffd08caSEric Fiselier    tuple<_Args&&...>
6274ffd08caSEric Fiselier    __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t,
6284ffd08caSEric Fiselier                      __tuple_indices<_Idx...>)
6294ffd08caSEric Fiselier    {
6304ffd08caSEric Fiselier        return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...);
6314ffd08caSEric Fiselier    }
6324ffd08caSEric Fiselier
6334ffd08caSEric Fiselier    template <class ..._Args, size_t ..._Idx>
6344ffd08caSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
6354ffd08caSEric Fiselier    tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>
6364ffd08caSEric Fiselier    __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t,
6374ffd08caSEric Fiselier                      __tuple_indices<_Idx...>)
6384ffd08caSEric Fiselier    {
6394ffd08caSEric Fiselier        using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>;
6404ffd08caSEric Fiselier        return _Tup(allocator_arg, inner_allocator(),
6414ffd08caSEric Fiselier                    _VSTD::get<_Idx>(_VSTD::move(__t))...);
6424ffd08caSEric Fiselier    }
6434ffd08caSEric Fiselier
6444ffd08caSEric Fiselier    template <class ..._Args, size_t ..._Idx>
6454ffd08caSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
6464ffd08caSEric Fiselier    tuple<_Args&&..., inner_allocator_type&>
6474ffd08caSEric Fiselier    __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t,
6484ffd08caSEric Fiselier                      __tuple_indices<_Idx...>)
6494ffd08caSEric Fiselier    {
6504ffd08caSEric Fiselier        using _Tup = tuple<_Args&&..., inner_allocator_type&>;
6514ffd08caSEric Fiselier        return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator());
6524ffd08caSEric Fiselier    }
6534ffd08caSEric Fiselier
65420cc2a42SHoward Hinnant    template <class...> friend class __scoped_allocator_storage;
65520cc2a42SHoward Hinnant};
65620cc2a42SHoward Hinnant
657f9f97caeSKonstantin Varlamov#if _LIBCPP_STD_VER > 14
658f9f97caeSKonstantin Varlamovtemplate<class _OuterAlloc, class... _InnerAllocs>
659f9f97caeSKonstantin Varlamov    scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...)
660f9f97caeSKonstantin Varlamov        -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>;
661f9f97caeSKonstantin Varlamov#endif
662f9f97caeSKonstantin Varlamov
66320cc2a42SHoward Hinnanttemplate <class _OuterA1, class _OuterA2>
66420cc2a42SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
66520cc2a42SHoward Hinnantbool
66620cc2a42SHoward Hinnantoperator==(const scoped_allocator_adaptor<_OuterA1>& __a,
667cfd52789SHoward Hinnant           const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
66820cc2a42SHoward Hinnant{
66920cc2a42SHoward Hinnant    return __a.outer_allocator() == __b.outer_allocator();
67020cc2a42SHoward Hinnant}
67120cc2a42SHoward Hinnant
672dcaa2e92SHoward Hinnanttemplate <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
67320cc2a42SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
67420cc2a42SHoward Hinnantbool
675dcaa2e92SHoward Hinnantoperator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
676cfd52789SHoward Hinnant           const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
67720cc2a42SHoward Hinnant{
67820cc2a42SHoward Hinnant    return __a.outer_allocator() == __b.outer_allocator() &&
67920cc2a42SHoward Hinnant           __a.inner_allocator() == __b.inner_allocator();
68020cc2a42SHoward Hinnant}
68120cc2a42SHoward Hinnant
68220cc2a42SHoward Hinnanttemplate <class _OuterA1, class _OuterA2, class... _InnerAllocs>
68320cc2a42SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
68420cc2a42SHoward Hinnantbool
68520cc2a42SHoward Hinnantoperator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
686cfd52789SHoward Hinnant           const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
68720cc2a42SHoward Hinnant{
68820cc2a42SHoward Hinnant    return !(__a == __b);
68920cc2a42SHoward Hinnant}
69020cc2a42SHoward Hinnant
69154613ab4SEric Fiselier#endif // !defined(_LIBCPP_CXX03_LANG)
69220cc2a42SHoward Hinnant
69320cc2a42SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
69420cc2a42SHoward Hinnant
69520cc2a42SHoward Hinnant#endif // _LIBCPP_SCOPED_ALLOCATOR
696