]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/scoped_allocator
Vendor import of libc++ trunk r351319 (just before the release_80
[FreeBSD/FreeBSD.git] / include / scoped_allocator
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