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