blob: f361bccbbd9f5f30b06c49ee43d63e9f65488282 [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,
52 const InnerAllocs&... innerAllocs);
53 scoped_allocator_adaptor(const scoped_allocator_adaptor& other);
54 template <class OuterA2>
55 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other);
56 template <class OuterA2>
57 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other);
58
59 ~scoped_allocator_adaptor();
60
61 inner_allocator_type& inner_allocator();
62 const inner_allocator_type& inner_allocator() const;
63
64 outer_allocator_type& outer_allocator();
65 const outer_allocator_type& outer_allocator() const;
66
67 pointer allocate(size_type n);
68 pointer allocate(size_type n, const_void_pointer hint);
69 void deallocate(pointer p, size_type n);
70
71 size_type max_size() const;
72 template <class T, class... Args> void construct(T* p, Args&& args);
73 template <class T1, class T2, class... Args1, class... Args2>
74 void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
75 tuple<Args2...> y);
76 template <class T1, class T2>
77 void construct(pair<T1, T2>* p);
78 template <class T1, class T2, class U, class V>
79 void construct(pair<T1, T2>* p, U&& x, V&& y);
80 template <class T1, class T2, class U, class V>
81 void construct(pair<T1, T2>* p, const pair<U, V>& x);
82 template <class T1, class T2, class U, class V>
83 void construct(pair<T1, T2>* p, pair<U, V>&& x);
84 template <class T> void destroy(T* p);
85
86 scoped_allocator_adaptor select_on_container_copy_construction() const;
87};
88
89template <class OuterA1, class OuterA2, class... InnerAllocs>
90 bool
91 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
92 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b);
93
94template <class OuterA1, class OuterA2, class... InnerAllocs>
95 bool
96 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
97 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b);
98
99} // std
100
101*/
102
103#include <__config>
104#include <memory>
105
106#pragma GCC system_header
107
108_LIBCPP_BEGIN_NAMESPACE_STD
109
Howard Hinnant73d21a42010-09-04 23:28:19 +0000110#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000111
112// scoped_allocator_adaptor
113
114template <class ..._Allocs>
115class scoped_allocator_adaptor;
116
117template <class ..._Allocs> struct __get_poc_copy_assignment;
118
119template <class _A0>
120struct __get_poc_copy_assignment<_A0>
121{
122 static const bool value = allocator_traits<_A0>::
123 propagate_on_container_copy_assignment::value;
124};
125
126template <class _A0, class ..._Allocs>
127struct __get_poc_copy_assignment<_A0, _Allocs...>
128{
129 static const bool value =
130 allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
131 __get_poc_copy_assignment<_Allocs...>::value;
132};
133
134template <class ..._Allocs> struct __get_poc_move_assignment;
135
136template <class _A0>
137struct __get_poc_move_assignment<_A0>
138{
139 static const bool value = allocator_traits<_A0>::
140 propagate_on_container_move_assignment::value;
141};
142
143template <class _A0, class ..._Allocs>
144struct __get_poc_move_assignment<_A0, _Allocs...>
145{
146 static const bool value =
147 allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
148 __get_poc_move_assignment<_Allocs...>::value;
149};
150
151template <class ..._Allocs> struct __get_poc_swap;
152
153template <class _A0>
154struct __get_poc_swap<_A0>
155{
156 static const bool value = allocator_traits<_A0>::
157 propagate_on_container_swap::value;
158};
159
160template <class _A0, class ..._Allocs>
161struct __get_poc_swap<_A0, _Allocs...>
162{
163 static const bool value =
164 allocator_traits<_A0>::propagate_on_container_swap::value ||
165 __get_poc_swap<_Allocs...>::value;
166};
167
168template <class ..._Allocs>
169class __scoped_allocator_storage;
170
171template <class _OuterAlloc, class... _InnerAllocs>
172class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
173 : public _OuterAlloc
174{
175 typedef _OuterAlloc outer_allocator_type;
176protected:
177 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
178
179private:
180 inner_allocator_type __inner_;
181
182protected:
Howard Hinnant324bb032010-08-22 00:02:43 +0000183
Howard Hinnant28c97e62010-09-23 16:27:36 +0000184 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000185 __scoped_allocator_storage() {}
186
187 template <class _OuterA2,
188 class = typename enable_if<
189 is_constructible<outer_allocator_type, _OuterA2>::value
190 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000191 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000192 __scoped_allocator_storage(_OuterA2&& __outerAlloc,
193 const _InnerAllocs& ...__innerAllocs)
194 : outer_allocator_type(_STD::forward<_OuterA2>(__outerAlloc)),
195 __inner_(__innerAllocs...) {}
196
197 template <class _OuterA2,
198 class = typename enable_if<
199 is_constructible<outer_allocator_type, const _OuterA2&>::value
200 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000201 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000202 __scoped_allocator_storage(
203 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other)
204 : outer_allocator_type(__other.outer_allocator()),
205 __inner_(__other.inner_allocator()) {}
206
207 template <class _OuterA2,
208 class = typename enable_if<
209 is_constructible<outer_allocator_type, _OuterA2>::value
210 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000211 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000212 __scoped_allocator_storage(
213 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other)
214 : outer_allocator_type(_STD::move(__other.outer_allocator())),
215 __inner_(_STD::move(__other.inner_allocator())) {}
216
217 template <class _OuterA2,
218 class = typename enable_if<
219 is_constructible<outer_allocator_type, _OuterA2>::value
220 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000221 _LIBCPP_INLINE_VISIBILITY
222 __scoped_allocator_storage(_OuterA2&& __o,
223 const inner_allocator_type& __i)
224 : outer_allocator_type(_STD::forward<_OuterA2>(__o)),
225 __inner_(__i)
226 {
227 }
Howard Hinnante92c3d72010-08-19 18:39:17 +0000228
Howard Hinnant28c97e62010-09-23 16:27:36 +0000229 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000230 inner_allocator_type& inner_allocator() {return __inner_;}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000231 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000232 const inner_allocator_type& inner_allocator() const {return __inner_;}
233
Howard Hinnant28c97e62010-09-23 16:27:36 +0000234 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000235 outer_allocator_type& outer_allocator()
236 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000237 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000238 const outer_allocator_type& outer_allocator() const
239 {return static_cast<const outer_allocator_type&>(*this);}
240
241 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000243 select_on_container_copy_construction() const
244 {
245 return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
246 (
247 allocator_traits<outer_allocator_type>::
248 select_on_container_copy_construction(outer_allocator()),
249 allocator_traits<inner_allocator_type>::
250 select_on_container_copy_construction(inner_allocator())
251 );
252 }
253
254 template <class...> friend class __scoped_allocator_storage;
255};
256
257template <class _OuterAlloc>
258class __scoped_allocator_storage<_OuterAlloc>
259 : public _OuterAlloc
260{
261 typedef _OuterAlloc outer_allocator_type;
262protected:
263 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
264
Howard Hinnant28c97e62010-09-23 16:27:36 +0000265 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000266 __scoped_allocator_storage() {}
267
268 template <class _OuterA2,
269 class = typename enable_if<
270 is_constructible<outer_allocator_type, _OuterA2>::value
271 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000272 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000273 __scoped_allocator_storage(_OuterA2&& __outerAlloc)
274 : outer_allocator_type(_STD::forward<_OuterA2>(__outerAlloc)) {}
275
276 template <class _OuterA2,
277 class = typename enable_if<
278 is_constructible<outer_allocator_type, const _OuterA2&>::value
279 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000280 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000281 __scoped_allocator_storage(
282 const __scoped_allocator_storage<_OuterA2>& __other)
283 : outer_allocator_type(__other.outer_allocator()) {}
284
285 template <class _OuterA2,
286 class = typename enable_if<
287 is_constructible<outer_allocator_type, _OuterA2>::value
288 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000289 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000290 __scoped_allocator_storage(
291 __scoped_allocator_storage<_OuterA2>&& __other)
292 : outer_allocator_type(_STD::move(__other.outer_allocator())) {}
293
Howard Hinnant28c97e62010-09-23 16:27:36 +0000294 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000295 inner_allocator_type& inner_allocator()
296 {return static_cast<inner_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000297 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000298 const inner_allocator_type& inner_allocator() const
299 {return static_cast<const inner_allocator_type&>(*this);}
300
Howard Hinnant28c97e62010-09-23 16:27:36 +0000301 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000302 outer_allocator_type& outer_allocator()
303 {return static_cast<outer_allocator_type&>(*this);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000304 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000305 const outer_allocator_type& outer_allocator() const
306 {return static_cast<const outer_allocator_type&>(*this);}
307
Howard Hinnant28c97e62010-09-23 16:27:36 +0000308 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000309 scoped_allocator_adaptor<outer_allocator_type>
310 select_on_container_copy_construction() const
311 {return scoped_allocator_adaptor<outer_allocator_type>(
312 allocator_traits<outer_allocator_type>::
313 select_on_container_copy_construction(outer_allocator())
314 );}
315
316 __scoped_allocator_storage(const outer_allocator_type& __o,
317 const inner_allocator_type& __i);
318
319 template <class...> friend class __scoped_allocator_storage;
320};
321
322// __outermost
323
324template <class _Alloc>
325decltype(declval<_Alloc>().outer_allocator(), true_type())
326__has_outer_allocator_test(_Alloc&& __a);
327
328template <class _Alloc>
329false_type
330__has_outer_allocator_test(const volatile _Alloc& __a);
331
332template <class _Alloc>
333struct __has_outer_allocator
334 : public common_type
335 <
336 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
337 >::type
338{
339};
340
341template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
342struct __outermost
343{
344 typedef _Alloc type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000345 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000346 type& operator()(type& __a) const {return __a;}
347};
348
349template <class _Alloc>
350struct __outermost<_Alloc, true>
351{
352 typedef typename remove_reference
353 <
354 decltype(_STD::declval<_Alloc>().outer_allocator())
355 >::type _OuterAlloc;
356 typedef typename __outermost<_OuterAlloc>::type type;
Howard Hinnant28c97e62010-09-23 16:27:36 +0000357 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000358 type& operator()(_Alloc& __a) const
359 {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
360};
361
362template <class _OuterAlloc, class... _InnerAllocs>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000363class _LIBCPP_VISIBLE scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000364 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
365{
366 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
367 typedef allocator_traits<_OuterAlloc> _OuterTraits;
368public:
369 typedef _OuterAlloc outer_allocator_type;
370 typedef typename base::inner_allocator_type inner_allocator_type;
371 typedef typename _OuterTraits::size_type size_type;
372 typedef typename _OuterTraits::difference_type difference_type;
373 typedef typename _OuterTraits::pointer pointer;
374 typedef typename _OuterTraits::const_pointer const_pointer;
375 typedef typename _OuterTraits::void_pointer void_pointer;
376 typedef typename _OuterTraits::const_void_pointer const_void_pointer;
377
378 typedef integral_constant
379 <
380 bool,
381 __get_poc_copy_assignment<outer_allocator_type,
382 _InnerAllocs...>::value
383 > propagate_on_container_copy_assignment;
384 typedef integral_constant
385 <
386 bool,
387 __get_poc_move_assignment<outer_allocator_type,
388 _InnerAllocs...>::value
389 > propagate_on_container_move_assignment;
390 typedef integral_constant
391 <
392 bool,
393 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
394 > propagate_on_container_swap;
395
396 template <class _Tp>
397 struct rebind
398 {
399 typedef scoped_allocator_adaptor
400 <
401 typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
402 > other;
403 };
404
Howard Hinnant28c97e62010-09-23 16:27:36 +0000405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000406 scoped_allocator_adaptor() {}
407 template <class _OuterA2,
408 class = typename enable_if<
409 is_constructible<outer_allocator_type, _OuterA2>::value
410 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000411 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000412 scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
413 const _InnerAllocs& ...__innerAllocs)
414 : base(_STD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
415 // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
416 template <class _OuterA2,
417 class = typename enable_if<
418 is_constructible<outer_allocator_type, const _OuterA2&>::value
419 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000421 scoped_allocator_adaptor(
422 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other)
423 : base(__other) {}
424 template <class _OuterA2,
425 class = typename enable_if<
426 is_constructible<outer_allocator_type, _OuterA2>::value
427 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000428 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000429 scoped_allocator_adaptor(
430 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other)
431 : base(_STD::move(__other)) {}
432
433 // ~scoped_allocator_adaptor() = default;
434
Howard Hinnant28c97e62010-09-23 16:27:36 +0000435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000436 inner_allocator_type& inner_allocator()
437 {return base::inner_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000438 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000439 const inner_allocator_type& inner_allocator() const
440 {return base::inner_allocator();}
441
Howard Hinnant28c97e62010-09-23 16:27:36 +0000442 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000443 outer_allocator_type& outer_allocator()
444 {return base::outer_allocator();}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000445 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000446 const outer_allocator_type& outer_allocator() const
447 {return base::outer_allocator();}
448
Howard Hinnant28c97e62010-09-23 16:27:36 +0000449 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000450 pointer allocate(size_type __n)
451 {return allocator_traits<outer_allocator_type>::
452 allocate(outer_allocator(), __n);}
Howard Hinnant28c97e62010-09-23 16:27:36 +0000453 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000454 pointer allocate(size_type __n, const_void_pointer __hint)
455 {return allocator_traits<outer_allocator_type>::
456 allocate(outer_allocator(), __n, __hint);}
457
Howard Hinnant28c97e62010-09-23 16:27:36 +0000458 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000459 void deallocate(pointer __p, size_type __n)
460 {allocator_traits<outer_allocator_type>::
461 deallocate(outer_allocator(), __p, __n);}
462
Howard Hinnant28c97e62010-09-23 16:27:36 +0000463 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000464 size_type max_size() const
Howard Hinnant28c97e62010-09-23 16:27:36 +0000465 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
Howard Hinnante92c3d72010-08-19 18:39:17 +0000466
467 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000469 void construct(_Tp* __p, _Args&& ...__args)
470 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
471 __p, _STD::forward<_Args>(__args)...);}
472 template <class _Tp>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000473 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000474 void destroy(_Tp* __p)
475 {
476 typedef __outermost<outer_allocator_type> _OM;
477 allocator_traits<typename _OM::type>::
478 destroy(_OM()(outer_allocator()), __p);
479 }
480
Howard Hinnant28c97e62010-09-23 16:27:36 +0000481 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000482 scoped_allocator_adaptor select_on_container_copy_construction() const
483 {return base::select_on_container_copy_construction();}
484
485private:
486
487 template <class _OuterA2,
488 class = typename enable_if<
489 is_constructible<outer_allocator_type, _OuterA2>::value
490 >::type>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000491 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000492 scoped_allocator_adaptor(_OuterA2&& __o,
493 const inner_allocator_type& __i)
494 : base(_STD::forward<_OuterA2>(__o), __i) {}
495
496 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000497 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000498 void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
499 {
500 typedef __outermost<outer_allocator_type> _OM;
501 allocator_traits<typename _OM::type>::construct
502 (
503 _OM()(outer_allocator()),
504 __p,
505 _STD::forward<_Args>(__args)...
506 );
507 }
508
509 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000511 void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
512 {
513 typedef __outermost<outer_allocator_type> _OM;
514 allocator_traits<typename _OM::type>::construct
515 (
516 _OM()(outer_allocator()),
517 __p,
518 allocator_arg,
519 inner_allocator(),
520 _STD::forward<_Args>(__args)...
521 );
522 }
523
524 template <class _Tp, class... _Args>
Howard Hinnant28c97e62010-09-23 16:27:36 +0000525 _LIBCPP_INLINE_VISIBILITY
Howard Hinnante92c3d72010-08-19 18:39:17 +0000526 void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
527 {
528 typedef __outermost<outer_allocator_type> _OM;
529 allocator_traits<typename _OM::type>::construct
530 (
531 _OM()(outer_allocator()),
532 __p,
533 _STD::forward<_Args>(__args)...,
534 inner_allocator()
535 );
536 }
537
538 template <class...> friend class __scoped_allocator_storage;
539};
540
541template <class _OuterA1, class _OuterA2>
542inline _LIBCPP_INLINE_VISIBILITY
543bool
544operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
545 const scoped_allocator_adaptor<_OuterA2>& __b)
546{
547 return __a.outer_allocator() == __b.outer_allocator();
548}
549
Howard Hinnantfead2e22011-05-17 20:41:18 +0000550template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
Howard Hinnante92c3d72010-08-19 18:39:17 +0000551inline _LIBCPP_INLINE_VISIBILITY
552bool
Howard Hinnantfead2e22011-05-17 20:41:18 +0000553operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
554 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000555{
556 return __a.outer_allocator() == __b.outer_allocator() &&
557 __a.inner_allocator() == __b.inner_allocator();
558}
559
560template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
561inline _LIBCPP_INLINE_VISIBILITY
562bool
563operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
564 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b)
565{
566 return !(__a == __b);
567}
568
Howard Hinnant73d21a42010-09-04 23:28:19 +0000569#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
Howard Hinnante92c3d72010-08-19 18:39:17 +0000570
571_LIBCPP_END_NAMESPACE_STD
572
573#endif // _LIBCPP_SCOPED_ALLOCATOR