blob: bdbb0136b5c3f4ed14eabe97e4b422fbc84a8d73 [file] [log] [blame]
Howard Hinnant20cc2a42010-08-19 18:39:17 +00001// -*- C++ -*-
2//===-------------------------- scoped_allocator --------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
Howard Hinnant412dbeb2010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant20cc2a42010-08-19 18:39:17 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_SCOPED_ALLOCATOR
12#define _LIBCPP_SCOPED_ALLOCATOR
13
14/*
15 scoped_allocator synopsis
16
17namespace std
18{
19
20template <class OuterAlloc, class... InnerAllocs>
21class scoped_allocator_adaptor : public OuterAlloc
22{
23 typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
Howard Hinnantb3371f62010-08-22 00:02:43 +000024 scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
Howard Hinnant20cc2a42010-08-19 18:39:17 +000025public:
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;
Marshall Clow31a47312015-06-02 16:34:03 +000041 typedef see below is_always_equal;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000042
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,
Howard Hinnantcfd52782011-05-28 18:51:12 +000053 const InnerAllocs&... innerAllocs) noexcept;
54 scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
55 scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000056 template <class OuterA2>
Howard Hinnantcfd52782011-05-28 18:51:12 +000057 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000058 template <class OuterA2>
Howard Hinnantcfd52782011-05-28 18:51:12 +000059 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000060
Marshall Clowcd5215d2015-10-25 19:52:47 +000061 scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
62 scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000063 ~scoped_allocator_adaptor();
64
Howard Hinnantcfd52782011-05-28 18:51:12 +000065 inner_allocator_type& inner_allocator() noexcept;
66 const inner_allocator_type& inner_allocator() const noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000067
Howard Hinnantcfd52782011-05-28 18:51:12 +000068 outer_allocator_type& outer_allocator() noexcept;
69 const outer_allocator_type& outer_allocator() const noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000070
Marshall Clow3fddff52017-11-26 02:55:38 +000071 pointer allocate(size_type n); // [[nodiscard]] in C++20
72 pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20
Howard Hinnantcfd52782011-05-28 18:51:12 +000073 void deallocate(pointer p, size_type n) noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000074
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
Howard Hinnantcfd52782011-05-28 18:51:12 +000090 template <class T> void destroy(T* p) noexcept;
91
92 scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000093};
94
95template <class OuterA1, class OuterA2, class... InnerAllocs>
96 bool
97 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
Howard Hinnantcfd52782011-05-28 18:51:12 +000098 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +000099
100template <class OuterA1, class OuterA2, class... InnerAllocs>
101 bool
102 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000103 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000104
105} // std
106
107*/
108
109#include <__config>
110#include <memory>
Marshall Clowf56972e2018-09-12 19:41:40 +0000111#include <version>
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000112
Howard Hinnant073458b2011-10-17 20:05:10 +0000113#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000114#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +0000115#endif
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000116
117_LIBCPP_BEGIN_NAMESPACE_STD
118
Eric Fiselier54613ab2016-09-25 03:34:28 +0000119#if !defined(_LIBCPP_CXX03_LANG)
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000120
121// scoped_allocator_adaptor
122
123template <class ..._Allocs>
124class scoped_allocator_adaptor;
125
126template <class ..._Allocs> struct __get_poc_copy_assignment;
127
128template <class _A0>
129struct __get_poc_copy_assignment<_A0>
130{
131 static const bool value = allocator_traits<_A0>::
132 propagate_on_container_copy_assignment::value;
133};
134
135template <class _A0, class ..._Allocs>
136struct __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
143template <class ..._Allocs> struct __get_poc_move_assignment;
144
145template <class _A0>
146struct __get_poc_move_assignment<_A0>
147{
148 static const bool value = allocator_traits<_A0>::
149 propagate_on_container_move_assignment::value;
150};
151
152template <class _A0, class ..._Allocs>
153struct __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
160template <class ..._Allocs> struct __get_poc_swap;
161
162template <class _A0>
163struct __get_poc_swap<_A0>
164{
165 static const bool value = allocator_traits<_A0>::
166 propagate_on_container_swap::value;
167};
168
169template <class _A0, class ..._Allocs>
170struct __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
Marshall Clow8880c202015-06-02 21:40:58 +0000177template <class ..._Allocs> struct __get_is_always_equal;
178
179template <class _A0>
180struct __get_is_always_equal<_A0>
181{
182 static const bool value = allocator_traits<_A0>::is_always_equal::value;
183};
184
Marshall Clow31a47312015-06-02 16:34:03 +0000185template <class _A0, class ..._Allocs>
Marshall Clow8880c202015-06-02 21:40:58 +0000186struct __get_is_always_equal<_A0, _Allocs...>
Marshall Clow31a47312015-06-02 16:34:03 +0000187{
188 static const bool value =
Marshall Clow2abfcd52015-06-03 16:15:55 +0000189 allocator_traits<_A0>::is_always_equal::value &&
Marshall Clow8880c202015-06-02 21:40:58 +0000190 __get_is_always_equal<_Allocs...>::value;
Marshall Clow31a47312015-06-02 16:34:03 +0000191};
192
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000193template <class ..._Allocs>
194class __scoped_allocator_storage;
195
196template <class _OuterAlloc, class... _InnerAllocs>
197class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
198 : public _OuterAlloc
199{
200 typedef _OuterAlloc outer_allocator_type;
201protected:
202 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
203
204private:
205 inner_allocator_type __inner_;
206
207protected:
Howard Hinnantb3371f62010-08-22 00:02:43 +0000208
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000209 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000210 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000211
212 template <class _OuterA2,
213 class = typename enable_if<
214 is_constructible<outer_allocator_type, _OuterA2>::value
215 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000216 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000217 __scoped_allocator_storage(_OuterA2&& __outerAlloc,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000218 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000219 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000220 __inner_(__innerAllocs...) {}
221
222 template <class _OuterA2,
223 class = typename enable_if<
224 is_constructible<outer_allocator_type, const _OuterA2&>::value
225 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000226 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000227 __scoped_allocator_storage(
Howard Hinnantcfd52782011-05-28 18:51:12 +0000228 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000229 : 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>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000237 __scoped_allocator_storage(
Howard Hinnantcfd52782011-05-28 18:51:12 +0000238 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000239 : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
240 __inner_(_VSTD::move(__other.inner_allocator())) {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000241
242 template <class _OuterA2,
243 class = typename enable_if<
244 is_constructible<outer_allocator_type, _OuterA2>::value
245 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000246 _LIBCPP_INLINE_VISIBILITY
247 __scoped_allocator_storage(_OuterA2&& __o,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000248 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000249 : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000250 __inner_(__i)
251 {
252 }
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000253
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000254 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000255 inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000257 const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000258
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000259 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000260 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000261 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000262 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000263 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000264 {return static_cast<const outer_allocator_type&>(*this);}
265
266 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000267 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000268 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000269 {
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
282template <class _OuterAlloc>
283class __scoped_allocator_storage<_OuterAlloc>
284 : public _OuterAlloc
285{
286 typedef _OuterAlloc outer_allocator_type;
287protected:
288 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
289
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000290 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000291 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000292
293 template <class _OuterA2,
294 class = typename enable_if<
295 is_constructible<outer_allocator_type, _OuterA2>::value
296 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000297 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000298 __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000299 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000300
301 template <class _OuterA2,
302 class = typename enable_if<
303 is_constructible<outer_allocator_type, const _OuterA2&>::value
304 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000305 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000306 __scoped_allocator_storage(
Howard Hinnantcfd52782011-05-28 18:51:12 +0000307 const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000308 : 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>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000314 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000315 __scoped_allocator_storage(
Howard Hinnantcfd52782011-05-28 18:51:12 +0000316 __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000317 : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000318
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000319 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000320 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000321 {return static_cast<inner_allocator_type&>(*this);}
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000322 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000323 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000324 {return static_cast<const inner_allocator_type&>(*this);}
325
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000326 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000327 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000328 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000329 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000330 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000331 {return static_cast<const outer_allocator_type&>(*this);}
332
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000333 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000334 scoped_allocator_adaptor<outer_allocator_type>
Howard Hinnantcfd52782011-05-28 18:51:12 +0000335 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000336 {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,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000342 const inner_allocator_type& __i) _NOEXCEPT;
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000343
344 template <class...> friend class __scoped_allocator_storage;
345};
346
347// __outermost
348
349template <class _Alloc>
350decltype(declval<_Alloc>().outer_allocator(), true_type())
351__has_outer_allocator_test(_Alloc&& __a);
352
353template <class _Alloc>
354false_type
355__has_outer_allocator_test(const volatile _Alloc& __a);
356
357template <class _Alloc>
358struct __has_outer_allocator
359 : public common_type
360 <
361 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
362 >::type
363{
364};
365
366template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
367struct __outermost
368{
369 typedef _Alloc type;
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000370 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000371 type& operator()(type& __a) const _NOEXCEPT {return __a;}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000372};
373
374template <class _Alloc>
375struct __outermost<_Alloc, true>
376{
377 typedef typename remove_reference
378 <
Howard Hinnantce48a112011-06-30 21:18:19 +0000379 decltype(_VSTD::declval<_Alloc>().outer_allocator())
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000380 >::type _OuterAlloc;
381 typedef typename __outermost<_OuterAlloc>::type type;
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000383 type& operator()(_Alloc& __a) const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000384 {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
385};
386
387template <class _OuterAlloc, class... _InnerAllocs>
Eric Fiseliere2f2d1e2017-01-04 23:56:00 +0000388class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000389 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
390{
391 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
392 typedef allocator_traits<_OuterAlloc> _OuterTraits;
393public:
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;
Marshall Clow31a47312015-06-02 16:34:03 +0000420 typedef integral_constant
421 <
422 bool,
Marshall Clow8880c202015-06-02 21:40:58 +0000423 __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
Marshall Clow31a47312015-06-02 16:34:03 +0000424 > is_always_equal;
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000425
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
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000436 scoped_allocator_adaptor() _NOEXCEPT {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000437 template <class _OuterA2,
438 class = typename enable_if<
439 is_constructible<outer_allocator_type, _OuterA2>::value
440 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000441 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000442 scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000443 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000444 : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000445 // 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>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000451 scoped_allocator_adaptor(
Howard Hinnantcfd52782011-05-28 18:51:12 +0000452 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000453 : base(__other) {}
454 template <class _OuterA2,
455 class = typename enable_if<
456 is_constructible<outer_allocator_type, _OuterA2>::value
457 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000459 scoped_allocator_adaptor(
Howard Hinnantcfd52782011-05-28 18:51:12 +0000460 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000461 : base(_VSTD::move(__other)) {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000462
Marshall Clowcd5215d2015-10-25 19:52:47 +0000463 // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default;
464 // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default;
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000465 // ~scoped_allocator_adaptor() = default;
466
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000468 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000469 {return base::inner_allocator();}
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000470 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000471 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000472 {return base::inner_allocator();}
473
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000475 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000476 {return base::outer_allocator();}
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000478 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000479 {return base::outer_allocator();}
480
Marshall Clow3fddff52017-11-26 02:55:38 +0000481 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000482 pointer allocate(size_type __n)
483 {return allocator_traits<outer_allocator_type>::
484 allocate(outer_allocator(), __n);}
Marshall Clow3fddff52017-11-26 02:55:38 +0000485 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000486 pointer allocate(size_type __n, const_void_pointer __hint)
487 {return allocator_traits<outer_allocator_type>::
488 allocate(outer_allocator(), __n, __hint);}
489
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000490 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000491 void deallocate(pointer __p, size_type __n) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000492 {allocator_traits<outer_allocator_type>::
493 deallocate(outer_allocator(), __p, __n);}
494
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000496 size_type max_size() const
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000497 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000498
499 template <class _Tp, class... _Args>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000500 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000501 void construct(_Tp* __p, _Args&& ...__args)
Eric Fiselier4ffd08c2016-12-14 21:29:29 +0000502 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(),
Howard Hinnantce48a112011-06-30 21:18:19 +0000503 __p, _VSTD::forward<_Args>(__args)...);}
Eric Fiselier4ffd08c2016-12-14 21:29:29 +0000504
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
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000554 template <class _Tp>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000556 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
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantcfd52782011-05-28 18:51:12 +0000564 scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000565 {return base::select_on_container_copy_construction();}
566
567private:
568
Eric Fiselier4ffd08c2016-12-14 21:29:29 +0000569
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000570 template <class _OuterA2,
571 class = typename enable_if<
572 is_constructible<outer_allocator_type, _OuterA2>::value
573 >::type>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000575 scoped_allocator_adaptor(_OuterA2&& __o,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000576 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnantce48a112011-06-30 21:18:19 +0000577 : base(_VSTD::forward<_OuterA2>(__o), __i) {}
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000578
579 template <class _Tp, class... _Args>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000580 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000581 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,
Howard Hinnantce48a112011-06-30 21:18:19 +0000588 _VSTD::forward<_Args>(__args)...
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000589 );
590 }
591
592 template <class _Tp, class... _Args>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000593 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000594 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()),
Eric Fiselier4ffd08c2016-12-14 21:29:29 +0000600 __p, allocator_arg, inner_allocator(),
Howard Hinnantce48a112011-06-30 21:18:19 +0000601 _VSTD::forward<_Args>(__args)...
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000602 );
603 }
604
605 template <class _Tp, class... _Args>
Howard Hinnant53ec0b42010-09-23 16:27:36 +0000606 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000607 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,
Howard Hinnantce48a112011-06-30 21:18:19 +0000614 _VSTD::forward<_Args>(__args)...,
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000615 inner_allocator()
616 );
617 }
618
Eric Fiselier4ffd08c2016-12-14 21:29:29 +0000619 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
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000649 template <class...> friend class __scoped_allocator_storage;
650};
651
652template <class _OuterA1, class _OuterA2>
653inline _LIBCPP_INLINE_VISIBILITY
654bool
655operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000656 const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000657{
658 return __a.outer_allocator() == __b.outer_allocator();
659}
660
Howard Hinnantdcaa2e92011-05-17 20:41:18 +0000661template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000662inline _LIBCPP_INLINE_VISIBILITY
663bool
Howard Hinnantdcaa2e92011-05-17 20:41:18 +0000664operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000665 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000666{
667 return __a.outer_allocator() == __b.outer_allocator() &&
668 __a.inner_allocator() == __b.inner_allocator();
669}
670
671template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
672inline _LIBCPP_INLINE_VISIBILITY
673bool
674operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
Howard Hinnantcfd52782011-05-28 18:51:12 +0000675 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000676{
677 return !(__a == __b);
678}
679
Eric Fiselier54613ab2016-09-25 03:34:28 +0000680#endif // !defined(_LIBCPP_CXX03_LANG)
Howard Hinnant20cc2a42010-08-19 18:39:17 +0000681
682_LIBCPP_END_NAMESPACE_STD
683
684#endif // _LIBCPP_SCOPED_ALLOCATOR