blob: 5864689d1f2906b9ad0400d221eb4d89a2b83296 [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;
Marshall Clowf0324bc2015-06-02 16:34:03 +000041 typedef see below is_always_equal;
Howard Hinnante92c3d72010-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 Hinnant06674332011-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 Hinnante92c3d72010-08-19 18:39:17 +000056 template <class OuterA2>
Howard Hinnant06674332011-05-28 18:51:12 +000057 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000058 template <class OuterA2>
Howard Hinnant06674332011-05-28 18:51:12 +000059 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000060
61 ~scoped_allocator_adaptor();
62
Howard Hinnant06674332011-05-28 18:51:12 +000063 inner_allocator_type& inner_allocator() noexcept;
64 const inner_allocator_type& inner_allocator() const noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000065
Howard Hinnant06674332011-05-28 18:51:12 +000066 outer_allocator_type& outer_allocator() noexcept;
67 const outer_allocator_type& outer_allocator() const noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000068
69 pointer allocate(size_type n);
70 pointer allocate(size_type n, const_void_pointer hint);
Howard Hinnant06674332011-05-28 18:51:12 +000071 void deallocate(pointer p, size_type n) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000072
73 size_type max_size() const;
74 template <class T, class... Args> void construct(T* p, Args&& args);
75 template <class T1, class T2, class... Args1, class... Args2>
76 void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
77 tuple<Args2...> y);
78 template <class T1, class T2>
79 void construct(pair<T1, T2>* p);
80 template <class T1, class T2, class U, class V>
81 void construct(pair<T1, T2>* p, U&& x, V&& y);
82 template <class T1, class T2, class U, class V>
83 void construct(pair<T1, T2>* p, const pair<U, V>& x);
84 template <class T1, class T2, class U, class V>
85 void construct(pair<T1, T2>* p, pair<U, V>&& x);
86 template <class T> void destroy(T* p);
87
Howard Hinnant06674332011-05-28 18:51:12 +000088 template <class T> void destroy(T* p) noexcept;
89
90 scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000091};
92
93template <class OuterA1, class OuterA2, class... InnerAllocs>
94 bool
95 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
Howard Hinnant06674332011-05-28 18:51:12 +000096 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +000097
98template <class OuterA1, class OuterA2, class... InnerAllocs>
99 bool
100 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
Howard Hinnant06674332011-05-28 18:51:12 +0000101 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
Howard Hinnante92c3d72010-08-19 18:39:17 +0000102
103} // std
104
105*/
106
107#include <__config>
108#include <memory>
109
Howard Hinnant08e17472011-10-17 20:05:10 +0000110#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000111#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000112#endif
Howard Hinnante92c3d72010-08-19 18:39:17 +0000113
114_LIBCPP_BEGIN_NAMESPACE_STD
115
Howard Hinnant73d21a42010-09-04 23:28:19 +0000116#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000117
118// scoped_allocator_adaptor
119
120template <class ..._Allocs>
121class scoped_allocator_adaptor;
122
123template <class ..._Allocs> struct __get_poc_copy_assignment;
124
125template <class _A0>
126struct __get_poc_copy_assignment<_A0>
127{
128 static const bool value = allocator_traits<_A0>::
129 propagate_on_container_copy_assignment::value;
130};
131
132template <class _A0, class ..._Allocs>
133struct __get_poc_copy_assignment<_A0, _Allocs...>
134{
135 static const bool value =
136 allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
137 __get_poc_copy_assignment<_Allocs...>::value;
138};
139
140template <class ..._Allocs> struct __get_poc_move_assignment;
141
142template <class _A0>
143struct __get_poc_move_assignment<_A0>
144{
145 static const bool value = allocator_traits<_A0>::
146 propagate_on_container_move_assignment::value;
147};
148
149template <class _A0, class ..._Allocs>
150struct __get_poc_move_assignment<_A0, _Allocs...>
151{
152 static const bool value =
153 allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
154 __get_poc_move_assignment<_Allocs...>::value;
155};
156
157template <class ..._Allocs> struct __get_poc_swap;
158
159template <class _A0>
160struct __get_poc_swap<_A0>
161{
162 static const bool value = allocator_traits<_A0>::
163 propagate_on_container_swap::value;
164};
165
166template <class _A0, class ..._Allocs>
167struct __get_poc_swap<_A0, _Allocs...>
168{
169 static const bool value =
170 allocator_traits<_A0>::propagate_on_container_swap::value ||
171 __get_poc_swap<_Allocs...>::value;
172};
173
Marshall Clowf0324bc2015-06-02 16:34:03 +0000174template <class _A0, class ..._Allocs>
175struct __get_poc_always_equal<_A0, _Allocs...>
176{
177 static const bool value =
178 allocator_traits<_A0>::is_always_equal::value ||
179 __get_poc_always_equal<_Allocs...>::value;
180};
181
Howard Hinnante92c3d72010-08-19 18:39:17 +0000182template <class ..._Allocs>
183class __scoped_allocator_storage;
184
185template <class _OuterAlloc, class... _InnerAllocs>
186class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
187 : public _OuterAlloc
188{
189 typedef _OuterAlloc outer_allocator_type;
190protected:
191 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
192
193private:
194 inner_allocator_type __inner_;
195
196protected:
Howard Hinnant324bb032010-08-22 00:02:43 +0000197
Howard Hinnant28c97e62010-09-23 16:27:36 +0000198 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000199 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000200
201 template <class _OuterA2,
202 class = typename enable_if<
203 is_constructible<outer_allocator_type, _OuterA2>::value
204 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000205 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000206 __scoped_allocator_storage(_OuterA2&& __outerAlloc,
Howard Hinnant06674332011-05-28 18:51:12 +0000207 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000208 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
Howard Hinnante92c3d72010-08-19 18:39:17 +0000209 __inner_(__innerAllocs...) {}
210
211 template <class _OuterA2,
212 class = typename enable_if<
213 is_constructible<outer_allocator_type, const _OuterA2&>::value
214 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000215 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000216 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000217 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000218 : outer_allocator_type(__other.outer_allocator()),
219 __inner_(__other.inner_allocator()) {}
220
221 template <class _OuterA2,
222 class = typename enable_if<
223 is_constructible<outer_allocator_type, _OuterA2>::value
224 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000226 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000227 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000228 : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
229 __inner_(_VSTD::move(__other.inner_allocator())) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000230
231 template <class _OuterA2,
232 class = typename enable_if<
233 is_constructible<outer_allocator_type, _OuterA2>::value
234 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000235 _LIBCPP_INLINE_VISIBILITY
236 __scoped_allocator_storage(_OuterA2&& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000237 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000238 : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
Howard Hinnant28c97e62010-09-23 16:27:36 +0000239 __inner_(__i)
240 {
241 }
Howard Hinnante92c3d72010-08-19 18:39:17 +0000242
Howard Hinnant28c97e62010-09-23 16:27:36 +0000243 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000244 inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000245 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000246 const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000247
Howard Hinnant28c97e62010-09-23 16:27:36 +0000248 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000249 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000250 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000251 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000252 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000253 {return static_cast<const outer_allocator_type&>(*this);}
254
255 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000256 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000257 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000258 {
259 return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
260 (
261 allocator_traits<outer_allocator_type>::
262 select_on_container_copy_construction(outer_allocator()),
263 allocator_traits<inner_allocator_type>::
264 select_on_container_copy_construction(inner_allocator())
265 );
266 }
267
268 template <class...> friend class __scoped_allocator_storage;
269};
270
271template <class _OuterAlloc>
272class __scoped_allocator_storage<_OuterAlloc>
273 : public _OuterAlloc
274{
275 typedef _OuterAlloc outer_allocator_type;
276protected:
277 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
278
Howard Hinnant28c97e62010-09-23 16:27:36 +0000279 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000280 __scoped_allocator_storage() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000281
282 template <class _OuterA2,
283 class = typename enable_if<
284 is_constructible<outer_allocator_type, _OuterA2>::value
285 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000286 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000287 __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000288 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000289
290 template <class _OuterA2,
291 class = typename enable_if<
292 is_constructible<outer_allocator_type, const _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 const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000297 : outer_allocator_type(__other.outer_allocator()) {}
298
299 template <class _OuterA2,
300 class = typename enable_if<
301 is_constructible<outer_allocator_type, _OuterA2>::value
302 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000303 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000304 __scoped_allocator_storage(
Howard Hinnant06674332011-05-28 18:51:12 +0000305 __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000306 : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000307
Howard Hinnant28c97e62010-09-23 16:27:36 +0000308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000309 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000310 {return static_cast<inner_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000311 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000312 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000313 {return static_cast<const inner_allocator_type&>(*this);}
314
Howard Hinnant28c97e62010-09-23 16:27:36 +0000315 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000316 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000317 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000318 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000319 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000320 {return static_cast<const outer_allocator_type&>(*this);}
321
Howard Hinnant28c97e62010-09-23 16:27:36 +0000322 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000323 scoped_allocator_adaptor<outer_allocator_type>
Howard Hinnant06674332011-05-28 18:51:12 +0000324 select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000325 {return scoped_allocator_adaptor<outer_allocator_type>(
326 allocator_traits<outer_allocator_type>::
327 select_on_container_copy_construction(outer_allocator())
328 );}
329
330 __scoped_allocator_storage(const outer_allocator_type& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000331 const inner_allocator_type& __i) _NOEXCEPT;
Howard Hinnante92c3d72010-08-19 18:39:17 +0000332
333 template <class...> friend class __scoped_allocator_storage;
334};
335
336// __outermost
337
338template <class _Alloc>
339decltype(declval<_Alloc>().outer_allocator(), true_type())
340__has_outer_allocator_test(_Alloc&& __a);
341
342template <class _Alloc>
343false_type
344__has_outer_allocator_test(const volatile _Alloc& __a);
345
346template <class _Alloc>
347struct __has_outer_allocator
348 : public common_type
349 <
350 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
351 >::type
352{
353};
354
355template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
356struct __outermost
357{
358 typedef _Alloc type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000359 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000360 type& operator()(type& __a) const _NOEXCEPT {return __a;}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000361};
362
363template <class _Alloc>
364struct __outermost<_Alloc, true>
365{
366 typedef typename remove_reference
367 <
Howard Hinnant0949eed2011-06-30 21:18:19 +0000368 decltype(_VSTD::declval<_Alloc>().outer_allocator())
Howard Hinnante92c3d72010-08-19 18:39:17 +0000369 >::type _OuterAlloc;
370 typedef typename __outermost<_OuterAlloc>::type type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000371 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000372 type& operator()(_Alloc& __a) const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000373 {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
374};
375
376template <class _OuterAlloc, class... _InnerAllocs>
Howard Hinnant0f678bd2013-08-12 18:38:34 +0000377class _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000378 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
379{
380 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
381 typedef allocator_traits<_OuterAlloc> _OuterTraits;
382public:
383 typedef _OuterAlloc outer_allocator_type;
384 typedef typename base::inner_allocator_type inner_allocator_type;
385 typedef typename _OuterTraits::size_type size_type;
386 typedef typename _OuterTraits::difference_type difference_type;
387 typedef typename _OuterTraits::pointer pointer;
388 typedef typename _OuterTraits::const_pointer const_pointer;
389 typedef typename _OuterTraits::void_pointer void_pointer;
390 typedef typename _OuterTraits::const_void_pointer const_void_pointer;
391
392 typedef integral_constant
393 <
394 bool,
395 __get_poc_copy_assignment<outer_allocator_type,
396 _InnerAllocs...>::value
397 > propagate_on_container_copy_assignment;
398 typedef integral_constant
399 <
400 bool,
401 __get_poc_move_assignment<outer_allocator_type,
402 _InnerAllocs...>::value
403 > propagate_on_container_move_assignment;
404 typedef integral_constant
405 <
406 bool,
407 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
408 > propagate_on_container_swap;
Marshall Clowf0324bc2015-06-02 16:34:03 +0000409 typedef integral_constant
410 <
411 bool,
412 __get_poc_always_equal<outer_allocator_type, _InnerAllocs...>::value
413 > is_always_equal;
Howard Hinnante92c3d72010-08-19 18:39:17 +0000414
415 template <class _Tp>
416 struct rebind
417 {
418 typedef scoped_allocator_adaptor
419 <
420 typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
421 > other;
422 };
423
Howard Hinnant28c97e62010-09-23 16:27:36 +0000424 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000425 scoped_allocator_adaptor() _NOEXCEPT {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000426 template <class _OuterA2,
427 class = typename enable_if<
428 is_constructible<outer_allocator_type, _OuterA2>::value
429 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000430 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000431 scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
Howard Hinnant06674332011-05-28 18:51:12 +0000432 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000433 : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000434 // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
435 template <class _OuterA2,
436 class = typename enable_if<
437 is_constructible<outer_allocator_type, const _OuterA2&>::value
438 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000440 scoped_allocator_adaptor(
Howard Hinnant06674332011-05-28 18:51:12 +0000441 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000442 : base(__other) {}
443 template <class _OuterA2,
444 class = typename enable_if<
445 is_constructible<outer_allocator_type, _OuterA2>::value
446 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000448 scoped_allocator_adaptor(
Howard Hinnant06674332011-05-28 18:51:12 +0000449 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000450 : base(_VSTD::move(__other)) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000451
452 // ~scoped_allocator_adaptor() = default;
453
Howard Hinnant28c97e62010-09-23 16:27:36 +0000454 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000455 inner_allocator_type& inner_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000456 {return base::inner_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000457 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000458 const inner_allocator_type& inner_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000459 {return base::inner_allocator();}
460
Howard Hinnant28c97e62010-09-23 16:27:36 +0000461 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000462 outer_allocator_type& outer_allocator() _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000463 {return base::outer_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000464 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000465 const outer_allocator_type& outer_allocator() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000466 {return base::outer_allocator();}
467
Howard Hinnant28c97e62010-09-23 16:27:36 +0000468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000469 pointer allocate(size_type __n)
470 {return allocator_traits<outer_allocator_type>::
471 allocate(outer_allocator(), __n);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000473 pointer allocate(size_type __n, const_void_pointer __hint)
474 {return allocator_traits<outer_allocator_type>::
475 allocate(outer_allocator(), __n, __hint);}
476
Howard Hinnant28c97e62010-09-23 16:27:36 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000478 void deallocate(pointer __p, size_type __n) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000479 {allocator_traits<outer_allocator_type>::
480 deallocate(outer_allocator(), __p, __n);}
481
Howard Hinnant28c97e62010-09-23 16:27:36 +0000482 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000483 size_type max_size() const
Howard Hinnant28c97e62010-09-23 16:27:36 +0000484 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000485
486 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000487 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000488 void construct(_Tp* __p, _Args&& ...__args)
489 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000490 __p, _VSTD::forward<_Args>(__args)...);}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000491 template <class _Tp>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000493 void destroy(_Tp* __p)
494 {
495 typedef __outermost<outer_allocator_type> _OM;
496 allocator_traits<typename _OM::type>::
497 destroy(_OM()(outer_allocator()), __p);
498 }
499
Howard Hinnant28c97e62010-09-23 16:27:36 +0000500 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant06674332011-05-28 18:51:12 +0000501 scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000502 {return base::select_on_container_copy_construction();}
503
504private:
505
506 template <class _OuterA2,
507 class = typename enable_if<
508 is_constructible<outer_allocator_type, _OuterA2>::value
509 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000511 scoped_allocator_adaptor(_OuterA2&& __o,
Howard Hinnant06674332011-05-28 18:51:12 +0000512 const inner_allocator_type& __i) _NOEXCEPT
Howard Hinnant0949eed2011-06-30 21:18:19 +0000513 : base(_VSTD::forward<_OuterA2>(__o), __i) {}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000514
515 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000516 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000517 void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
518 {
519 typedef __outermost<outer_allocator_type> _OM;
520 allocator_traits<typename _OM::type>::construct
521 (
522 _OM()(outer_allocator()),
523 __p,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000524 _VSTD::forward<_Args>(__args)...
Howard Hinnante92c3d72010-08-19 18:39:17 +0000525 );
526 }
527
528 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000529 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000530 void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
531 {
532 typedef __outermost<outer_allocator_type> _OM;
533 allocator_traits<typename _OM::type>::construct
534 (
535 _OM()(outer_allocator()),
536 __p,
537 allocator_arg,
538 inner_allocator(),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000539 _VSTD::forward<_Args>(__args)...
Howard Hinnante92c3d72010-08-19 18:39:17 +0000540 );
541 }
542
543 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000545 void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
546 {
547 typedef __outermost<outer_allocator_type> _OM;
548 allocator_traits<typename _OM::type>::construct
549 (
550 _OM()(outer_allocator()),
551 __p,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000552 _VSTD::forward<_Args>(__args)...,
Howard Hinnante92c3d72010-08-19 18:39:17 +0000553 inner_allocator()
554 );
555 }
556
557 template <class...> friend class __scoped_allocator_storage;
558};
559
560template <class _OuterA1, class _OuterA2>
561inline _LIBCPP_INLINE_VISIBILITY
562bool
563operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000564 const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000565{
566 return __a.outer_allocator() == __b.outer_allocator();
567}
568
Howard Hinnantfead2e22011-05-17 20:41:18 +0000569template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000570inline _LIBCPP_INLINE_VISIBILITY
571bool
Howard Hinnantfead2e22011-05-17 20:41:18 +0000572operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000573 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000574{
575 return __a.outer_allocator() == __b.outer_allocator() &&
576 __a.inner_allocator() == __b.inner_allocator();
577}
578
579template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
580inline _LIBCPP_INLINE_VISIBILITY
581bool
582operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
Howard Hinnant06674332011-05-28 18:51:12 +0000583 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
Howard Hinnante92c3d72010-08-19 18:39:17 +0000584{
585 return !(__a == __b);
586}
587
Howard Hinnant73d21a42010-09-04 23:28:19 +0000588#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000589
590_LIBCPP_END_NAMESPACE_STD
591
592#endif // _LIBCPP_SCOPED_ALLOCATOR