blob: e8822955dd277a8f9918dcef8202c0a42618fbc4 [file] [log] [blame]
Howard Hinnante92c3d72010-08-19 18:39:17 +00001// -*- C++ -*-
2//===-------------------------- scoped_allocator --------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
Howard Hinnantb64f8b02010-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 Hinnante92c3d72010-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 Hinnant324bb032010-08-22 00:02:43 +000024 scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only
Howard Hinnante92c3d72010-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;
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,
Howard Hinnant06674332011-05-28 18:51:12 +000052 const InnerAllocs&... innerAllocs) noexcept;
53 scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
54 scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000055 template <class OuterA2>
Howard Hinnant06674332011-05-28 18:51:12 +000056 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000057 template <class OuterA2>
Howard Hinnant06674332011-05-28 18:51:12 +000058 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000059
60 ~scoped_allocator_adaptor();
61
Howard Hinnant06674332011-05-28 18:51:12 +000062 inner_allocator_type& inner_allocator() noexcept;
63 const inner_allocator_type& inner_allocator() const noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000064
Howard Hinnant06674332011-05-28 18:51:12 +000065 outer_allocator_type& outer_allocator() noexcept;
66 const outer_allocator_type& outer_allocator() const noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000067
68 pointer allocate(size_type n);
69 pointer allocate(size_type n, const_void_pointer hint);
Howard Hinnant06674332011-05-28 18:51:12 +000070 void deallocate(pointer p, size_type n) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000071
72 size_type max_size() const;
73 template <class T, class... Args> void construct(T* p, Args&& args);
74 template <class T1, class T2, class... Args1, class... Args2>
75 void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
76 tuple<Args2...> y);
77 template <class T1, class T2>
78 void construct(pair<T1, T2>* p);
79 template <class T1, class T2, class U, class V>
80 void construct(pair<T1, T2>* p, U&& x, V&& y);
81 template <class T1, class T2, class U, class V>
82 void construct(pair<T1, T2>* p, const pair<U, V>& x);
83 template <class T1, class T2, class U, class V>
84 void construct(pair<T1, T2>* p, pair<U, V>&& x);
85 template <class T> void destroy(T* p);
86
Howard Hinnant06674332011-05-28 18:51:12 +000087 template <class T> void destroy(T* p) noexcept;
88
89 scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000090};
91
92template <class OuterA1, class OuterA2, class... InnerAllocs>
93 bool
94 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
Howard Hinnant06674332011-05-28 18:51:12 +000095 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000096
97template <class OuterA1, class OuterA2, class... InnerAllocs>
98 bool
99 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
Howard Hinnant06674332011-05-28 18:51:12 +0000100 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +0000101
102} // std
103
104*/
105
106#include <__config>
107#include <memory>
108
109#pragma GCC system_header
110
111_LIBCPP_BEGIN_NAMESPACE_STD
112
Howard Hinnant73d21a42010-09-04 23:28:19 +0000113#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000114
115// scoped_allocator_adaptor
116
117template <class ..._Allocs>
118class scoped_allocator_adaptor;
119
120template <class ..._Allocs> struct __get_poc_copy_assignment;
121
122template <class _A0>
123struct __get_poc_copy_assignment<_A0>
124{
125 static const bool value = allocator_traits<_A0>::
126 propagate_on_container_copy_assignment::value;
127};
128
129template <class _A0, class ..._Allocs>
130struct __get_poc_copy_assignment<_A0, _Allocs...>
131{
132 static const bool value =
133 allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
134 __get_poc_copy_assignment<_Allocs...>::value;
135};
136
137template <class ..._Allocs> struct __get_poc_move_assignment;
138
139template <class _A0>
140struct __get_poc_move_assignment<_A0>
141{
142 static const bool value = allocator_traits<_A0>::
143 propagate_on_container_move_assignment::value;
144};
145
146template <class _A0, class ..._Allocs>
147struct __get_poc_move_assignment<_A0, _Allocs...>
148{
149 static const bool value =
150 allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
151 __get_poc_move_assignment<_Allocs...>::value;
152};
153
154template <class ..._Allocs> struct __get_poc_swap;
155
156template <class _A0>
157struct __get_poc_swap<_A0>
158{
159 static const bool value = allocator_traits<_A0>::
160 propagate_on_container_swap::value;
161};
162
163template <class _A0, class ..._Allocs>
164struct __get_poc_swap<_A0, _Allocs...>
165{
166 static const bool value =
167 allocator_traits<_A0>::propagate_on_container_swap::value ||
168 __get_poc_swap<_Allocs...>::value;
169};
170
171template <class ..._Allocs>
172class __scoped_allocator_storage;
173
174template <class _OuterAlloc, class... _InnerAllocs>
175class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
176 : public _OuterAlloc
177{
178 typedef _OuterAlloc outer_allocator_type;
179protected:
180 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
181
182private:
183 inner_allocator_type __inner_;
184
185protected:
Howard Hinnant324bb032010-08-22 00:02:43 +0000186
Howard Hinnant28c97e62010-09-23 16:27:36 +0000187 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000188 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000189
190 template <class _OuterA2,
191 class = typename enable_if<
192 is_constructible<outer_allocator_type, _OuterA2>::value
193 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000194 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000195 __scoped_allocator_storage(_OuterA2&& __outerAlloc,
Howard Hinnant06674332011-05-28 18:51:12 +0000196 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000197 : outer_allocator_type(_STD::forward<_OuterA2>(__outerAlloc)),
198 __inner_(__innerAllocs...) {}
199
200 template <class _OuterA2,
201 class = typename enable_if<
202 is_constructible<outer_allocator_type, const _OuterA2&>::value
203 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000204 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000205 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000206 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000207 : outer_allocator_type(__other.outer_allocator()),
208 __inner_(__other.inner_allocator()) {}
209
210 template <class _OuterA2,
211 class = typename enable_if<
212 is_constructible<outer_allocator_type, _OuterA2>::value
213 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000214 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000215 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000216 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000217 : outer_allocator_type(_STD::move(__other.outer_allocator())),
218 __inner_(_STD::move(__other.inner_allocator())) {}
219
220 template <class _OuterA2,
221 class = typename enable_if<
222 is_constructible<outer_allocator_type, _OuterA2>::value
223 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000224 _LIBCPP_INLINE_VISIBILITY
225 __scoped_allocator_storage(_OuterA2&& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000226 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnant28c97e62010-09-23 16:27:36 +0000227 : outer_allocator_type(_STD::forward<_OuterA2>(__o)),
228 __inner_(__i)
229 {
230 }
Howard Hinnante92c3d72010-08-19 18:39:17 +0000231
Howard Hinnant28c97e62010-09-23 16:27:36 +0000232 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000233 inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000235 const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000236
Howard Hinnant28c97e62010-09-23 16:27:36 +0000237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000238 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000239 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000240 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000241 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000242 {return static_cast<const outer_allocator_type&>(*this);}
243
244 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000246 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000247 {
248 return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
249 (
250 allocator_traits<outer_allocator_type>::
251 select_on_container_copy_construction(outer_allocator()),
252 allocator_traits<inner_allocator_type>::
253 select_on_container_copy_construction(inner_allocator())
254 );
255 }
256
257 template <class...> friend class __scoped_allocator_storage;
258};
259
260template <class _OuterAlloc>
261class __scoped_allocator_storage<_OuterAlloc>
262 : public _OuterAlloc
263{
264 typedef _OuterAlloc outer_allocator_type;
265protected:
266 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
267
Howard Hinnant28c97e62010-09-23 16:27:36 +0000268 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000269 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000270
271 template <class _OuterA2,
272 class = typename enable_if<
273 is_constructible<outer_allocator_type, _OuterA2>::value
274 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000275 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000276 __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000277 : outer_allocator_type(_STD::forward<_OuterA2>(__outerAlloc)) {}
278
279 template <class _OuterA2,
280 class = typename enable_if<
281 is_constructible<outer_allocator_type, const _OuterA2&>::value
282 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000283 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000284 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000285 const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000286 : outer_allocator_type(__other.outer_allocator()) {}
287
288 template <class _OuterA2,
289 class = typename enable_if<
290 is_constructible<outer_allocator_type, _OuterA2>::value
291 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000292 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000293 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000294 __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000295 : outer_allocator_type(_STD::move(__other.outer_allocator())) {}
296
Howard Hinnant28c97e62010-09-23 16:27:36 +0000297 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000298 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000299 {return static_cast<inner_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000300 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000301 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000302 {return static_cast<const inner_allocator_type&>(*this);}
303
Howard Hinnant28c97e62010-09-23 16:27:36 +0000304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000305 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000306 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000307 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000308 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000309 {return static_cast<const outer_allocator_type&>(*this);}
310
Howard Hinnant28c97e62010-09-23 16:27:36 +0000311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000312 scoped_allocator_adaptor<outer_allocator_type>
Howard Hinnant06674332011-05-28 18:51:12 +0000313 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000314 {return scoped_allocator_adaptor<outer_allocator_type>(
315 allocator_traits<outer_allocator_type>::
316 select_on_container_copy_construction(outer_allocator())
317 );}
318
319 __scoped_allocator_storage(const outer_allocator_type& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000320 const inner_allocator_type& __i) _NOEXCEPT;
Howard Hinnante92c3d72010-08-19 18:39:17 +0000321
322 template <class...> friend class __scoped_allocator_storage;
323};
324
325// __outermost
326
327template <class _Alloc>
328decltype(declval<_Alloc>().outer_allocator(), true_type())
329__has_outer_allocator_test(_Alloc&& __a);
330
331template <class _Alloc>
332false_type
333__has_outer_allocator_test(const volatile _Alloc& __a);
334
335template <class _Alloc>
336struct __has_outer_allocator
337 : public common_type
338 <
339 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
340 >::type
341{
342};
343
344template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
345struct __outermost
346{
347 typedef _Alloc type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000348 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000349 type& operator()(type& __a) const _NOEXCEPT {return __a;}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000350};
351
352template <class _Alloc>
353struct __outermost<_Alloc, true>
354{
355 typedef typename remove_reference
356 <
357 decltype(_STD::declval<_Alloc>().outer_allocator())
358 >::type _OuterAlloc;
359 typedef typename __outermost<_OuterAlloc>::type type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000360 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000361 type& operator()(_Alloc& __a) const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000362 {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
363};
364
365template <class _OuterAlloc, class... _InnerAllocs>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000366class _LIBCPP_VISIBLE scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000367 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
368{
369 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
370 typedef allocator_traits<_OuterAlloc> _OuterTraits;
371public:
372 typedef _OuterAlloc outer_allocator_type;
373 typedef typename base::inner_allocator_type inner_allocator_type;
374 typedef typename _OuterTraits::size_type size_type;
375 typedef typename _OuterTraits::difference_type difference_type;
376 typedef typename _OuterTraits::pointer pointer;
377 typedef typename _OuterTraits::const_pointer const_pointer;
378 typedef typename _OuterTraits::void_pointer void_pointer;
379 typedef typename _OuterTraits::const_void_pointer const_void_pointer;
380
381 typedef integral_constant
382 <
383 bool,
384 __get_poc_copy_assignment<outer_allocator_type,
385 _InnerAllocs...>::value
386 > propagate_on_container_copy_assignment;
387 typedef integral_constant
388 <
389 bool,
390 __get_poc_move_assignment<outer_allocator_type,
391 _InnerAllocs...>::value
392 > propagate_on_container_move_assignment;
393 typedef integral_constant
394 <
395 bool,
396 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
397 > propagate_on_container_swap;
398
399 template <class _Tp>
400 struct rebind
401 {
402 typedef scoped_allocator_adaptor
403 <
404 typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
405 > other;
406 };
407
Howard Hinnant28c97e62010-09-23 16:27:36 +0000408 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000409 scoped_allocator_adaptor() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000410 template <class _OuterA2,
411 class = typename enable_if<
412 is_constructible<outer_allocator_type, _OuterA2>::value
413 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000414 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000415 scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
Howard Hinnant06674332011-05-28 18:51:12 +0000416 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000417 : base(_STD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
418 // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
419 template <class _OuterA2,
420 class = typename enable_if<
421 is_constructible<outer_allocator_type, const _OuterA2&>::value
422 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000424 scoped_allocator_adaptor(
Howard Hinnant06674332011-05-28 18:51:12 +0000425 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000426 : base(__other) {}
427 template <class _OuterA2,
428 class = typename enable_if<
429 is_constructible<outer_allocator_type, _OuterA2>::value
430 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000432 scoped_allocator_adaptor(
Howard Hinnant06674332011-05-28 18:51:12 +0000433 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000434 : base(_STD::move(__other)) {}
435
436 // ~scoped_allocator_adaptor() = default;
437
Howard Hinnant28c97e62010-09-23 16:27:36 +0000438 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000439 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000440 {return base::inner_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000441 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000442 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000443 {return base::inner_allocator();}
444
Howard Hinnant28c97e62010-09-23 16:27:36 +0000445 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000446 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000447 {return base::outer_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000449 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000450 {return base::outer_allocator();}
451
Howard Hinnant28c97e62010-09-23 16:27:36 +0000452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000453 pointer allocate(size_type __n)
454 {return allocator_traits<outer_allocator_type>::
455 allocate(outer_allocator(), __n);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000456 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000457 pointer allocate(size_type __n, const_void_pointer __hint)
458 {return allocator_traits<outer_allocator_type>::
459 allocate(outer_allocator(), __n, __hint);}
460
Howard Hinnant28c97e62010-09-23 16:27:36 +0000461 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000462 void deallocate(pointer __p, size_type __n) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000463 {allocator_traits<outer_allocator_type>::
464 deallocate(outer_allocator(), __p, __n);}
465
Howard Hinnant28c97e62010-09-23 16:27:36 +0000466 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000467 size_type max_size() const
Howard Hinnant28c97e62010-09-23 16:27:36 +0000468 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000469
470 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000472 void construct(_Tp* __p, _Args&& ...__args)
473 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
474 __p, _STD::forward<_Args>(__args)...);}
475 template <class _Tp>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000476 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000477 void destroy(_Tp* __p)
478 {
479 typedef __outermost<outer_allocator_type> _OM;
480 allocator_traits<typename _OM::type>::
481 destroy(_OM()(outer_allocator()), __p);
482 }
483
Howard Hinnant28c97e62010-09-23 16:27:36 +0000484 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000485 scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000486 {return base::select_on_container_copy_construction();}
487
488private:
489
490 template <class _OuterA2,
491 class = typename enable_if<
492 is_constructible<outer_allocator_type, _OuterA2>::value
493 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000494 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000495 scoped_allocator_adaptor(_OuterA2&& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000496 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000497 : base(_STD::forward<_OuterA2>(__o), __i) {}
498
499 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000500 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000501 void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
502 {
503 typedef __outermost<outer_allocator_type> _OM;
504 allocator_traits<typename _OM::type>::construct
505 (
506 _OM()(outer_allocator()),
507 __p,
508 _STD::forward<_Args>(__args)...
509 );
510 }
511
512 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000513 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000514 void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
515 {
516 typedef __outermost<outer_allocator_type> _OM;
517 allocator_traits<typename _OM::type>::construct
518 (
519 _OM()(outer_allocator()),
520 __p,
521 allocator_arg,
522 inner_allocator(),
523 _STD::forward<_Args>(__args)...
524 );
525 }
526
527 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000528 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000529 void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
530 {
531 typedef __outermost<outer_allocator_type> _OM;
532 allocator_traits<typename _OM::type>::construct
533 (
534 _OM()(outer_allocator()),
535 __p,
536 _STD::forward<_Args>(__args)...,
537 inner_allocator()
538 );
539 }
540
541 template <class...> friend class __scoped_allocator_storage;
542};
543
544template <class _OuterA1, class _OuterA2>
545inline _LIBCPP_INLINE_VISIBILITY
546bool
547operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000548 const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000549{
550 return __a.outer_allocator() == __b.outer_allocator();
551}
552
Howard Hinnantfead2e22011-05-17 20:41:18 +0000553template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000554inline _LIBCPP_INLINE_VISIBILITY
555bool
Howard Hinnantfead2e22011-05-17 20:41:18 +0000556operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000557 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000558{
559 return __a.outer_allocator() == __b.outer_allocator() &&
560 __a.inner_allocator() == __b.inner_allocator();
561}
562
563template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
564inline _LIBCPP_INLINE_VISIBILITY
565bool
566operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000567 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000568{
569 return !(__a == __b);
570}
571
Howard Hinnant73d21a42010-09-04 23:28:19 +0000572#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000573
574_LIBCPP_END_NAMESPACE_STD
575
576#endif // _LIBCPP_SCOPED_ALLOCATOR