]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/scoped_allocator
Vendor import of libc++ trunk r291274:
[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);
72     pointer allocate(size_type n, const_void_pointer hint);
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
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_INLINE_VISIBILITY
481     pointer allocate(size_type __n)
482         {return allocator_traits<outer_allocator_type>::
483             allocate(outer_allocator(), __n);}
484     _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