blob: aa8bece6d3313ca00a1e943aa2b11dc1a92f6499 [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
Howard Hinnant08e17472011-10-17 20:05:10 +0000109#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000110#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000111#endif
Howard Hinnante92c3d72010-08-19 18:39:17 +0000112
113_LIBCPP_BEGIN_NAMESPACE_STD
114
Howard Hinnant73d21a42010-09-04 23:28:19 +0000115#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000116
117// scoped_allocator_adaptor
118
119template <class ..._Allocs>
120class scoped_allocator_adaptor;
121
122template <class ..._Allocs> struct __get_poc_copy_assignment;
123
124template <class _A0>
125struct __get_poc_copy_assignment<_A0>
126{
127 static const bool value = allocator_traits<_A0>::
128 propagate_on_container_copy_assignment::value;
129};
130
131template <class _A0, class ..._Allocs>
132struct __get_poc_copy_assignment<_A0, _Allocs...>
133{
134 static const bool value =
135 allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
136 __get_poc_copy_assignment<_Allocs...>::value;
137};
138
139template <class ..._Allocs> struct __get_poc_move_assignment;
140
141template <class _A0>
142struct __get_poc_move_assignment<_A0>
143{
144 static const bool value = allocator_traits<_A0>::
145 propagate_on_container_move_assignment::value;
146};
147
148template <class _A0, class ..._Allocs>
149struct __get_poc_move_assignment<_A0, _Allocs...>
150{
151 static const bool value =
152 allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
153 __get_poc_move_assignment<_Allocs...>::value;
154};
155
156template <class ..._Allocs> struct __get_poc_swap;
157
158template <class _A0>
159struct __get_poc_swap<_A0>
160{
161 static const bool value = allocator_traits<_A0>::
162 propagate_on_container_swap::value;
163};
164
165template <class _A0, class ..._Allocs>
166struct __get_poc_swap<_A0, _Allocs...>
167{
168 static const bool value =
169 allocator_traits<_A0>::propagate_on_container_swap::value ||
170 __get_poc_swap<_Allocs...>::value;
171};
172
173template <class ..._Allocs>
174class __scoped_allocator_storage;
175
176template <class _OuterAlloc, class... _InnerAllocs>
177class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
178 : public _OuterAlloc
179{
180 typedef _OuterAlloc outer_allocator_type;
181protected:
182 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
183
184private:
185 inner_allocator_type __inner_;
186
187protected:
Howard Hinnant324bb032010-08-22 00:02:43 +0000188
Howard Hinnant28c97e62010-09-23 16:27:36 +0000189 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000190 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000191
192 template <class _OuterA2,
193 class = typename enable_if<
194 is_constructible<outer_allocator_type, _OuterA2>::value
195 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000196 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000197 __scoped_allocator_storage(_OuterA2&& __outerAlloc,
Howard Hinnant06674332011-05-28 18:51:12 +0000198 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000199 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
Howard Hinnante92c3d72010-08-19 18:39:17 +0000200 __inner_(__innerAllocs...) {}
201
202 template <class _OuterA2,
203 class = typename enable_if<
204 is_constructible<outer_allocator_type, const _OuterA2&>::value
205 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000206 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000207 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000208 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000209 : outer_allocator_type(__other.outer_allocator()),
210 __inner_(__other.inner_allocator()) {}
211
212 template <class _OuterA2,
213 class = typename enable_if<
214 is_constructible<outer_allocator_type, _OuterA2>::value
215 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000216 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000217 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000218 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000219 : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
220 __inner_(_VSTD::move(__other.inner_allocator())) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000221
222 template <class _OuterA2,
223 class = typename enable_if<
224 is_constructible<outer_allocator_type, _OuterA2>::value
225 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000226 _LIBCPP_INLINE_VISIBILITY
227 __scoped_allocator_storage(_OuterA2&& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000228 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000229 : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
Howard Hinnant28c97e62010-09-23 16:27:36 +0000230 __inner_(__i)
231 {
232 }
Howard Hinnante92c3d72010-08-19 18:39:17 +0000233
Howard Hinnant28c97e62010-09-23 16:27:36 +0000234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000235 inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000237 const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000238
Howard Hinnant28c97e62010-09-23 16:27:36 +0000239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000240 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000241 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000243 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000244 {return static_cast<const outer_allocator_type&>(*this);}
245
246 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000247 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000248 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000249 {
250 return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
251 (
252 allocator_traits<outer_allocator_type>::
253 select_on_container_copy_construction(outer_allocator()),
254 allocator_traits<inner_allocator_type>::
255 select_on_container_copy_construction(inner_allocator())
256 );
257 }
258
259 template <class...> friend class __scoped_allocator_storage;
260};
261
262template <class _OuterAlloc>
263class __scoped_allocator_storage<_OuterAlloc>
264 : public _OuterAlloc
265{
266 typedef _OuterAlloc outer_allocator_type;
267protected:
268 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
269
Howard Hinnant28c97e62010-09-23 16:27:36 +0000270 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000271 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000272
273 template <class _OuterA2,
274 class = typename enable_if<
275 is_constructible<outer_allocator_type, _OuterA2>::value
276 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000277 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000278 __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000279 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000280
281 template <class _OuterA2,
282 class = typename enable_if<
283 is_constructible<outer_allocator_type, const _OuterA2&>::value
284 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000285 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000286 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000287 const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000288 : outer_allocator_type(__other.outer_allocator()) {}
289
290 template <class _OuterA2,
291 class = typename enable_if<
292 is_constructible<outer_allocator_type, _OuterA2>::value
293 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000294 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000295 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000296 __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000297 : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000298
Howard Hinnant28c97e62010-09-23 16:27:36 +0000299 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000300 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000301 {return static_cast<inner_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000302 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000303 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000304 {return static_cast<const inner_allocator_type&>(*this);}
305
Howard Hinnant28c97e62010-09-23 16:27:36 +0000306 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000307 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000308 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000309 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000310 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000311 {return static_cast<const outer_allocator_type&>(*this);}
312
Howard Hinnant28c97e62010-09-23 16:27:36 +0000313 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000314 scoped_allocator_adaptor<outer_allocator_type>
Howard Hinnant06674332011-05-28 18:51:12 +0000315 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000316 {return scoped_allocator_adaptor<outer_allocator_type>(
317 allocator_traits<outer_allocator_type>::
318 select_on_container_copy_construction(outer_allocator())
319 );}
320
321 __scoped_allocator_storage(const outer_allocator_type& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000322 const inner_allocator_type& __i) _NOEXCEPT;
Howard Hinnante92c3d72010-08-19 18:39:17 +0000323
324 template <class...> friend class __scoped_allocator_storage;
325};
326
327// __outermost
328
329template <class _Alloc>
330decltype(declval<_Alloc>().outer_allocator(), true_type())
331__has_outer_allocator_test(_Alloc&& __a);
332
333template <class _Alloc>
334false_type
335__has_outer_allocator_test(const volatile _Alloc& __a);
336
337template <class _Alloc>
338struct __has_outer_allocator
339 : public common_type
340 <
341 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
342 >::type
343{
344};
345
346template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
347struct __outermost
348{
349 typedef _Alloc type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000350 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000351 type& operator()(type& __a) const _NOEXCEPT {return __a;}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000352};
353
354template <class _Alloc>
355struct __outermost<_Alloc, true>
356{
357 typedef typename remove_reference
358 <
Howard Hinnant0949eed2011-06-30 21:18:19 +0000359 decltype(_VSTD::declval<_Alloc>().outer_allocator())
Howard Hinnante92c3d72010-08-19 18:39:17 +0000360 >::type _OuterAlloc;
361 typedef typename __outermost<_OuterAlloc>::type type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000362 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000363 type& operator()(_Alloc& __a) const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000364 {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
365};
366
367template <class _OuterAlloc, class... _InnerAllocs>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000368class _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000369 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
370{
371 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
372 typedef allocator_traits<_OuterAlloc> _OuterTraits;
373public:
374 typedef _OuterAlloc outer_allocator_type;
375 typedef typename base::inner_allocator_type inner_allocator_type;
376 typedef typename _OuterTraits::size_type size_type;
377 typedef typename _OuterTraits::difference_type difference_type;
378 typedef typename _OuterTraits::pointer pointer;
379 typedef typename _OuterTraits::const_pointer const_pointer;
380 typedef typename _OuterTraits::void_pointer void_pointer;
381 typedef typename _OuterTraits::const_void_pointer const_void_pointer;
382
383 typedef integral_constant
384 <
385 bool,
386 __get_poc_copy_assignment<outer_allocator_type,
387 _InnerAllocs...>::value
388 > propagate_on_container_copy_assignment;
389 typedef integral_constant
390 <
391 bool,
392 __get_poc_move_assignment<outer_allocator_type,
393 _InnerAllocs...>::value
394 > propagate_on_container_move_assignment;
395 typedef integral_constant
396 <
397 bool,
398 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
399 > propagate_on_container_swap;
400
401 template <class _Tp>
402 struct rebind
403 {
404 typedef scoped_allocator_adaptor
405 <
406 typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
407 > other;
408 };
409
Howard Hinnant28c97e62010-09-23 16:27:36 +0000410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000411 scoped_allocator_adaptor() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000412 template <class _OuterA2,
413 class = typename enable_if<
414 is_constructible<outer_allocator_type, _OuterA2>::value
415 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000417 scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
Howard Hinnant06674332011-05-28 18:51:12 +0000418 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000419 : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000420 // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
421 template <class _OuterA2,
422 class = typename enable_if<
423 is_constructible<outer_allocator_type, const _OuterA2&>::value
424 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000425 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000426 scoped_allocator_adaptor(
Howard Hinnant06674332011-05-28 18:51:12 +0000427 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000428 : base(__other) {}
429 template <class _OuterA2,
430 class = typename enable_if<
431 is_constructible<outer_allocator_type, _OuterA2>::value
432 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000434 scoped_allocator_adaptor(
Howard Hinnant06674332011-05-28 18:51:12 +0000435 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000436 : base(_VSTD::move(__other)) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000437
438 // ~scoped_allocator_adaptor() = default;
439
Howard Hinnant28c97e62010-09-23 16:27:36 +0000440 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000441 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000442 {return base::inner_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000444 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000445 {return base::inner_allocator();}
446
Howard Hinnant28c97e62010-09-23 16:27:36 +0000447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000448 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000449 {return base::outer_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000451 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000452 {return base::outer_allocator();}
453
Howard Hinnant28c97e62010-09-23 16:27:36 +0000454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000455 pointer allocate(size_type __n)
456 {return allocator_traits<outer_allocator_type>::
457 allocate(outer_allocator(), __n);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000459 pointer allocate(size_type __n, const_void_pointer __hint)
460 {return allocator_traits<outer_allocator_type>::
461 allocate(outer_allocator(), __n, __hint);}
462
Howard Hinnant28c97e62010-09-23 16:27:36 +0000463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000464 void deallocate(pointer __p, size_type __n) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000465 {allocator_traits<outer_allocator_type>::
466 deallocate(outer_allocator(), __p, __n);}
467
Howard Hinnant28c97e62010-09-23 16:27:36 +0000468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000469 size_type max_size() const
Howard Hinnant28c97e62010-09-23 16:27:36 +0000470 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000471
472 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000474 void construct(_Tp* __p, _Args&& ...__args)
475 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000476 __p, _VSTD::forward<_Args>(__args)...);}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000477 template <class _Tp>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000478 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000479 void destroy(_Tp* __p)
480 {
481 typedef __outermost<outer_allocator_type> _OM;
482 allocator_traits<typename _OM::type>::
483 destroy(_OM()(outer_allocator()), __p);
484 }
485
Howard Hinnant28c97e62010-09-23 16:27:36 +0000486 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000487 scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000488 {return base::select_on_container_copy_construction();}
489
490private:
491
492 template <class _OuterA2,
493 class = typename enable_if<
494 is_constructible<outer_allocator_type, _OuterA2>::value
495 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000496 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000497 scoped_allocator_adaptor(_OuterA2&& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000498 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000499 : base(_VSTD::forward<_OuterA2>(__o), __i) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000500
501 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000502 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000503 void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
504 {
505 typedef __outermost<outer_allocator_type> _OM;
506 allocator_traits<typename _OM::type>::construct
507 (
508 _OM()(outer_allocator()),
509 __p,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000510 _VSTD::forward<_Args>(__args)...
Howard Hinnante92c3d72010-08-19 18:39:17 +0000511 );
512 }
513
514 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000515 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000516 void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
517 {
518 typedef __outermost<outer_allocator_type> _OM;
519 allocator_traits<typename _OM::type>::construct
520 (
521 _OM()(outer_allocator()),
522 __p,
523 allocator_arg,
524 inner_allocator(),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000525 _VSTD::forward<_Args>(__args)...
Howard Hinnante92c3d72010-08-19 18:39:17 +0000526 );
527 }
528
529 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000531 void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
532 {
533 typedef __outermost<outer_allocator_type> _OM;
534 allocator_traits<typename _OM::type>::construct
535 (
536 _OM()(outer_allocator()),
537 __p,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000538 _VSTD::forward<_Args>(__args)...,
Howard Hinnante92c3d72010-08-19 18:39:17 +0000539 inner_allocator()
540 );
541 }
542
543 template <class...> friend class __scoped_allocator_storage;
544};
545
546template <class _OuterA1, class _OuterA2>
547inline _LIBCPP_INLINE_VISIBILITY
548bool
549operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000550 const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000551{
552 return __a.outer_allocator() == __b.outer_allocator();
553}
554
Howard Hinnantfead2e22011-05-17 20:41:18 +0000555template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000556inline _LIBCPP_INLINE_VISIBILITY
557bool
Howard Hinnantfead2e22011-05-17 20:41:18 +0000558operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000559 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000560{
561 return __a.outer_allocator() == __b.outer_allocator() &&
562 __a.inner_allocator() == __b.inner_allocator();
563}
564
565template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
566inline _LIBCPP_INLINE_VISIBILITY
567bool
568operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000569 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000570{
571 return !(__a == __b);
572}
573
Howard Hinnant73d21a42010-09-04 23:28:19 +0000574#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000575
576_LIBCPP_END_NAMESPACE_STD
577
578#endif // _LIBCPP_SCOPED_ALLOCATOR