zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob cf82affb (26232B) - Raw


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