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