Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Pablo Halpern 2009. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
8 //
|
Chris@101
|
9 // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
|
Chris@16
|
10 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
12 //
|
Chris@16
|
13 // See http://www.boost.org/libs/container for documentation.
|
Chris@16
|
14 //
|
Chris@16
|
15 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
16
|
Chris@16
|
17 #ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
|
Chris@16
|
18 #define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
|
Chris@16
|
19
|
Chris@16
|
20 #if defined (_MSC_VER)
|
Chris@16
|
21 # pragma once
|
Chris@16
|
22 #endif
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/container/detail/config_begin.hpp>
|
Chris@16
|
25 #include <boost/container/detail/workaround.hpp>
|
Chris@101
|
26
|
Chris@101
|
27 #include <boost/container/allocator_traits.hpp>
|
Chris@16
|
28 #include <boost/container/scoped_allocator_fwd.hpp>
|
Chris@101
|
29
|
Chris@101
|
30 #include <boost/container/detail/addressof.hpp>
|
Chris@101
|
31 #include <boost/container/detail/mpl.hpp>
|
Chris@101
|
32 #include <boost/container/detail/pair.hpp>
|
Chris@16
|
33 #include <boost/container/detail/type_traits.hpp>
|
Chris@101
|
34
|
Chris@101
|
35 #include <boost/move/adl_move_swap.hpp>
|
Chris@101
|
36 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
37 #include <boost/move/detail/fwd_macros.hpp>
|
Chris@101
|
38 #endif
|
Chris@101
|
39 #include <boost/move/utility_core.hpp>
|
Chris@101
|
40
|
Chris@101
|
41 #include <boost/core/no_exceptions_support.hpp>
|
Chris@16
|
42
|
Chris@16
|
43 namespace boost { namespace container {
|
Chris@16
|
44
|
Chris@101
|
45 //! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed
|
Chris@16
|
46 //! with an allocator as its last constructor argument. Ideally, all constructors of T (including the
|
Chris@16
|
47 //! copy and move constructors) should have a variant that accepts a final argument of
|
Chris@16
|
48 //! allocator_type.
|
Chris@16
|
49 //!
|
Chris@101
|
50 //! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type,
|
Chris@16
|
51 //! allocator_type and at least one constructor for which allocator_type is the last
|
Chris@16
|
52 //! parameter. If not all constructors of T can be called with a final allocator_type argument,
|
Chris@16
|
53 //! and if T is used in a context where a container must call such a constructor, then the program is
|
Chris@16
|
54 //! ill-formed.
|
Chris@16
|
55 //!
|
Chris@101
|
56 //! <code>
|
Chris@101
|
57 //! template <class T, class Allocator = allocator<T> >
|
Chris@16
|
58 //! class Z {
|
Chris@16
|
59 //! public:
|
Chris@16
|
60 //! typedef Allocator allocator_type;
|
Chris@16
|
61 //!
|
Chris@16
|
62 //! // Default constructor with optional allocator suffix
|
Chris@16
|
63 //! Z(const allocator_type& a = allocator_type());
|
Chris@16
|
64 //!
|
Chris@16
|
65 //! // Copy constructor and allocator-extended copy constructor
|
Chris@16
|
66 //! Z(const Z& zz);
|
Chris@16
|
67 //! Z(const Z& zz, const allocator_type& a);
|
Chris@16
|
68 //! };
|
Chris@16
|
69 //!
|
Chris@16
|
70 //! // Specialize trait for class template Z
|
Chris@16
|
71 //! template <class T, class Allocator = allocator<T> >
|
Chris@101
|
72 //! struct constructible_with_allocator_suffix<Z<T,Allocator> >
|
Chris@101
|
73 //! { static const bool value = true; };
|
Chris@101
|
74 //! </code>
|
Chris@16
|
75 //!
|
Chris@101
|
76 //! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)"
|
Chris@16
|
77 //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
Chris@16
|
78 //! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
|
Chris@16
|
79 //! Applications aiming portability with several compilers should always define this trait.
|
Chris@16
|
80 //!
|
Chris@16
|
81 //! In conforming C++11 compilers or compilers supporting SFINAE expressions
|
Chris@16
|
82 //! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
|
Chris@16
|
83 //! to detect if a type should be constructed with suffix or prefix allocator arguments.
|
Chris@16
|
84 template <class T>
|
Chris@16
|
85 struct constructible_with_allocator_suffix
|
Chris@101
|
86 { static const bool value = false; };
|
Chris@16
|
87
|
Chris@101
|
88 //! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed
|
Chris@101
|
89 //! with allocator_arg and T::allocator_type as its first two constructor arguments.
|
Chris@16
|
90 //! Ideally, all constructors of T (including the copy and move constructors) should have a variant
|
Chris@16
|
91 //! that accepts these two initial arguments.
|
Chris@16
|
92 //!
|
Chris@101
|
93 //! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type,
|
Chris@16
|
94 //! allocator_type and at least one constructor for which allocator_arg_t is the first
|
Chris@16
|
95 //! parameter and allocator_type is the second parameter. If not all constructors of T can be
|
Chris@16
|
96 //! called with these initial arguments, and if T is used in a context where a container must call such
|
Chris@16
|
97 //! a constructor, then the program is ill-formed.
|
Chris@16
|
98 //!
|
Chris@101
|
99 //! <code>
|
Chris@16
|
100 //! template <class T, class Allocator = allocator<T> >
|
Chris@16
|
101 //! class Y {
|
Chris@16
|
102 //! public:
|
Chris@16
|
103 //! typedef Allocator allocator_type;
|
Chris@101
|
104 //!
|
Chris@16
|
105 //! // Default constructor with and allocator-extended default constructor
|
Chris@16
|
106 //! Y();
|
Chris@16
|
107 //! Y(allocator_arg_t, const allocator_type& a);
|
Chris@101
|
108 //!
|
Chris@16
|
109 //! // Copy constructor and allocator-extended copy constructor
|
Chris@16
|
110 //! Y(const Y& yy);
|
Chris@16
|
111 //! Y(allocator_arg_t, const allocator_type& a, const Y& yy);
|
Chris@101
|
112 //!
|
Chris@16
|
113 //! // Variadic constructor and allocator-extended variadic constructor
|
Chris@16
|
114 //! template<class ...Args> Y(Args&& args...);
|
Chris@101
|
115 //! template<class ...Args>
|
Chris@101
|
116 //! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args);
|
Chris@16
|
117 //! };
|
Chris@101
|
118 //!
|
Chris@16
|
119 //! // Specialize trait for class template Y
|
Chris@16
|
120 //! template <class T, class Allocator = allocator<T> >
|
Chris@101
|
121 //! struct constructible_with_allocator_prefix<Y<T,Allocator> >
|
Chris@101
|
122 //! { static const bool value = true; };
|
Chris@101
|
123 //!
|
Chris@101
|
124 //! </code>
|
Chris@16
|
125 //!
|
Chris@16
|
126 //! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
|
Chris@16
|
127 //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
Chris@16
|
128 //! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
|
Chris@16
|
129 //! Applications aiming portability with several compilers should always define this trait.
|
Chris@16
|
130 //!
|
Chris@16
|
131 //! In conforming C++11 compilers or compilers supporting SFINAE expressions
|
Chris@16
|
132 //! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
|
Chris@16
|
133 //! to detect if a type should be constructed with suffix or prefix allocator arguments.
|
Chris@16
|
134 template <class T>
|
Chris@16
|
135 struct constructible_with_allocator_prefix
|
Chris@101
|
136 { static const bool value = false; };
|
Chris@16
|
137
|
Chris@101
|
138 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
139
|
Chris@16
|
140 namespace container_detail {
|
Chris@16
|
141
|
Chris@101
|
142 template<typename T, typename Allocator>
|
Chris@16
|
143 struct uses_allocator_imp
|
Chris@16
|
144 {
|
Chris@16
|
145 // Use SFINAE (Substitution Failure Is Not An Error) to detect the
|
Chris@101
|
146 // presence of an 'allocator_type' nested type convertilble from Allocator.
|
Chris@101
|
147 private:
|
Chris@101
|
148 typedef char yes_type;
|
Chris@101
|
149 struct no_type{ char dummy[2]; };
|
Chris@16
|
150
|
Chris@16
|
151 // Match this function if TypeT::allocator_type exists and is
|
Chris@101
|
152 // implicitly convertible from Allocator
|
Chris@101
|
153 template <class U>
|
Chris@101
|
154 static yes_type test(typename U::allocator_type);
|
Chris@16
|
155
|
Chris@16
|
156 // Match this function if TypeT::allocator_type does not exist or is
|
Chris@101
|
157 // not convertible from Allocator.
|
Chris@16
|
158 template <typename U>
|
Chris@101
|
159 static no_type test(...);
|
Chris@101
|
160 static Allocator alloc; // Declared but not defined
|
Chris@16
|
161
|
Chris@16
|
162 public:
|
Chris@101
|
163 static const bool value = sizeof(test<T>(alloc)) == sizeof(yes_type);
|
Chris@16
|
164 };
|
Chris@16
|
165
|
Chris@16
|
166 } //namespace container_detail {
|
Chris@16
|
167
|
Chris@101
|
168 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
169
|
Chris@16
|
170 //! <b>Remark</b>: Automatically detects if T has a nested allocator_type that is convertible from
|
Chris@101
|
171 //! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
|
Chris@101
|
172 //! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not
|
Chris@101
|
173 //! have a nested allocator_type but is nonetheless constructible using the specified Allocator.
|
Chris@16
|
174 //!
|
Chris@101
|
175 //! <b>Result</b>: uses_allocator<T, Allocator>::value== true if Convertible<Allocator,T::allocator_type>,
|
Chris@101
|
176 //! false otherwise.
|
Chris@101
|
177 template <typename T, typename Allocator>
|
Chris@16
|
178 struct uses_allocator
|
Chris@101
|
179 : container_detail::uses_allocator_imp<T, Allocator>
|
Chris@16
|
180 {};
|
Chris@16
|
181
|
Chris@101
|
182 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
183
|
Chris@16
|
184 namespace container_detail {
|
Chris@16
|
185
|
Chris@101
|
186 template <typename Allocator>
|
Chris@16
|
187 struct is_scoped_allocator_imp
|
Chris@16
|
188 {
|
Chris@101
|
189 typedef char yes_type;
|
Chris@101
|
190 struct no_type{ char dummy[2]; };
|
Chris@16
|
191
|
Chris@16
|
192 template <typename T>
|
Chris@101
|
193 static yes_type test(typename T::outer_allocator_type*);
|
Chris@16
|
194
|
Chris@101
|
195 template <typename T>
|
Chris@101
|
196 static int test(...);
|
Chris@101
|
197
|
Chris@101
|
198 static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0)));
|
Chris@16
|
199 };
|
Chris@16
|
200
|
Chris@16
|
201 template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
|
Chris@16
|
202 struct outermost_allocator_type_impl
|
Chris@16
|
203 {
|
Chris@16
|
204 typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
|
Chris@16
|
205 typedef typename outermost_allocator_type_impl<outer_type>::type type;
|
Chris@16
|
206 };
|
Chris@16
|
207
|
Chris@16
|
208 template<class MaybeScopedAlloc>
|
Chris@16
|
209 struct outermost_allocator_type_impl<MaybeScopedAlloc, false>
|
Chris@16
|
210 {
|
Chris@16
|
211 typedef MaybeScopedAlloc type;
|
Chris@16
|
212 };
|
Chris@16
|
213
|
Chris@16
|
214 template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
|
Chris@16
|
215 struct outermost_allocator_imp
|
Chris@16
|
216 {
|
Chris@16
|
217 typedef MaybeScopedAlloc type;
|
Chris@16
|
218
|
Chris@16
|
219 static type &get(MaybeScopedAlloc &a)
|
Chris@16
|
220 { return a; }
|
Chris@16
|
221
|
Chris@16
|
222 static const type &get(const MaybeScopedAlloc &a)
|
Chris@16
|
223 { return a; }
|
Chris@16
|
224 };
|
Chris@16
|
225
|
Chris@16
|
226 template<class MaybeScopedAlloc>
|
Chris@16
|
227 struct outermost_allocator_imp<MaybeScopedAlloc, true>
|
Chris@16
|
228 {
|
Chris@16
|
229 typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
|
Chris@16
|
230 typedef typename outermost_allocator_type_impl<outer_type>::type type;
|
Chris@16
|
231
|
Chris@16
|
232 static type &get(MaybeScopedAlloc &a)
|
Chris@16
|
233 { return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
|
Chris@16
|
234
|
Chris@16
|
235 static const type &get(const MaybeScopedAlloc &a)
|
Chris@16
|
236 { return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
|
Chris@16
|
237 };
|
Chris@16
|
238
|
Chris@16
|
239 } //namespace container_detail {
|
Chris@16
|
240
|
Chris@101
|
241 template <typename Allocator>
|
Chris@16
|
242 struct is_scoped_allocator
|
Chris@101
|
243 : container_detail::is_scoped_allocator_imp<Allocator>
|
Chris@16
|
244 {};
|
Chris@16
|
245
|
Chris@101
|
246 template <typename Allocator>
|
Chris@16
|
247 struct outermost_allocator
|
Chris@101
|
248 : container_detail::outermost_allocator_imp<Allocator>
|
Chris@16
|
249 {};
|
Chris@16
|
250
|
Chris@101
|
251 template <typename Allocator>
|
Chris@101
|
252 typename container_detail::outermost_allocator_imp<Allocator>::type &
|
Chris@101
|
253 get_outermost_allocator(Allocator &a)
|
Chris@101
|
254 { return container_detail::outermost_allocator_imp<Allocator>::get(a); }
|
Chris@16
|
255
|
Chris@101
|
256 template <typename Allocator>
|
Chris@101
|
257 const typename container_detail::outermost_allocator_imp<Allocator>::type &
|
Chris@101
|
258 get_outermost_allocator(const Allocator &a)
|
Chris@101
|
259 { return container_detail::outermost_allocator_imp<Allocator>::get(a); }
|
Chris@16
|
260
|
Chris@16
|
261 namespace container_detail {
|
Chris@16
|
262
|
Chris@16
|
263 // Check if we can detect is_convertible using advanced SFINAE expressions
|
Chris@101
|
264 #if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
265
|
Chris@16
|
266 //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list
|
Chris@16
|
267 //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html
|
Chris@16
|
268 //! Thanks Mathias!
|
Chris@16
|
269
|
Chris@16
|
270 //With variadic templates, we need a single class to implement the trait
|
Chris@16
|
271 template<class T, class ...Args>
|
Chris@101
|
272 struct is_constructible
|
Chris@16
|
273 {
|
Chris@16
|
274 typedef char yes_type;
|
Chris@16
|
275 struct no_type
|
Chris@16
|
276 { char padding[2]; };
|
Chris@16
|
277
|
Chris@16
|
278 template<std::size_t N>
|
Chris@16
|
279 struct dummy;
|
Chris@16
|
280
|
Chris@16
|
281 template<class X>
|
Chris@101
|
282 static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int);
|
Chris@16
|
283
|
Chris@16
|
284 template<class X>
|
Chris@16
|
285 static no_type test(...);
|
Chris@16
|
286
|
Chris@16
|
287 static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
|
Chris@16
|
288 };
|
Chris@16
|
289
|
Chris@16
|
290 template <class T, class InnerAlloc, class ...Args>
|
Chris@16
|
291 struct is_constructible_with_allocator_prefix
|
Chris@16
|
292 : is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
|
Chris@16
|
293 {};
|
Chris@16
|
294
|
Chris@101
|
295 #else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
296
|
Chris@16
|
297 //Without advanced SFINAE expressions, we can't use is_constructible
|
Chris@16
|
298 //so backup to constructible_with_allocator_xxx
|
Chris@16
|
299
|
Chris@16
|
300 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
301
|
Chris@101
|
302 template <class T, class InnerAlloc, class ...Args>
|
Chris@16
|
303 struct is_constructible_with_allocator_prefix
|
Chris@16
|
304 : constructible_with_allocator_prefix<T>
|
Chris@16
|
305 {};
|
Chris@101
|
306
|
Chris@101
|
307 template <class T, class InnerAlloc, class ...Args>
|
Chris@16
|
308 struct is_constructible_with_allocator_suffix
|
Chris@16
|
309 : constructible_with_allocator_suffix<T>
|
Chris@101
|
310 {};
|
Chris@16
|
311
|
Chris@16
|
312 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
313
|
Chris@101
|
314 template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
|
Chris@16
|
315 struct is_constructible_with_allocator_prefix
|
Chris@16
|
316 : constructible_with_allocator_prefix<T>
|
Chris@16
|
317 {};
|
Chris@101
|
318
|
Chris@101
|
319 template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
|
Chris@16
|
320 struct is_constructible_with_allocator_suffix
|
Chris@16
|
321 : constructible_with_allocator_suffix<T>
|
Chris@101
|
322 {};
|
Chris@16
|
323
|
Chris@16
|
324 #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
325
|
Chris@16
|
326 #endif // #if !defined(BOOST_NO_SFINAE_EXPR)
|
Chris@16
|
327
|
Chris@16
|
328 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
329
|
Chris@101
|
330 // allocator_arg_t
|
Chris@16
|
331 template < typename OutermostAlloc
|
Chris@16
|
332 , typename InnerAlloc
|
Chris@16
|
333 , typename T
|
Chris@16
|
334 , class ...Args
|
Chris@16
|
335 >
|
Chris@16
|
336 inline void dispatch_allocator_prefix_suffix
|
Chris@101
|
337 ( true_type use_alloc_prefix, OutermostAlloc& outermost_alloc
|
Chris@16
|
338 , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args) ...args)
|
Chris@16
|
339 {
|
Chris@16
|
340 (void)use_alloc_prefix;
|
Chris@16
|
341 allocator_traits<OutermostAlloc>::construct
|
Chris@16
|
342 ( outermost_alloc, p, allocator_arg, inner_alloc, ::boost::forward<Args>(args)...);
|
Chris@16
|
343 }
|
Chris@16
|
344
|
Chris@101
|
345 // allocator suffix
|
Chris@16
|
346 template < typename OutermostAlloc
|
Chris@16
|
347 , typename InnerAlloc
|
Chris@16
|
348 , typename T
|
Chris@16
|
349 , class ...Args
|
Chris@16
|
350 >
|
Chris@16
|
351 inline void dispatch_allocator_prefix_suffix
|
Chris@101
|
352 ( false_type use_alloc_prefix, OutermostAlloc& outermost_alloc
|
Chris@16
|
353 , InnerAlloc &inner_alloc, T* p, BOOST_FWD_REF(Args)...args)
|
Chris@16
|
354 {
|
Chris@16
|
355 (void)use_alloc_prefix;
|
Chris@16
|
356 allocator_traits<OutermostAlloc>::construct
|
Chris@16
|
357 (outermost_alloc, p, ::boost::forward<Args>(args)..., inner_alloc);
|
Chris@16
|
358 }
|
Chris@16
|
359
|
Chris@16
|
360 template < typename OutermostAlloc
|
Chris@16
|
361 , typename InnerAlloc
|
Chris@16
|
362 , typename T
|
Chris@16
|
363 , class ...Args
|
Chris@16
|
364 >
|
Chris@16
|
365 inline void dispatch_uses_allocator
|
Chris@101
|
366 ( true_type uses_allocator, OutermostAlloc& outermost_alloc
|
Chris@16
|
367 , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args)...args)
|
Chris@16
|
368 {
|
Chris@16
|
369 (void)uses_allocator;
|
Chris@16
|
370 //BOOST_STATIC_ASSERT((is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>::value ||
|
Chris@16
|
371 // is_constructible_with_allocator_suffix<T, InnerAlloc, Args...>::value ));
|
Chris@16
|
372 dispatch_allocator_prefix_suffix
|
Chris@101
|
373 ( bool_< is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>::value>()
|
Chris@16
|
374 , outermost_alloc, inner_alloc, p, ::boost::forward<Args>(args)...);
|
Chris@16
|
375 }
|
Chris@16
|
376
|
Chris@16
|
377 template < typename OutermostAlloc
|
Chris@16
|
378 , typename InnerAlloc
|
Chris@16
|
379 , typename T
|
Chris@16
|
380 , class ...Args
|
Chris@16
|
381 >
|
Chris@16
|
382 inline void dispatch_uses_allocator
|
Chris@101
|
383 ( false_type uses_allocator, OutermostAlloc & outermost_alloc
|
Chris@16
|
384 , InnerAlloc & inner_alloc
|
Chris@16
|
385 ,T* p, BOOST_FWD_REF(Args)...args)
|
Chris@16
|
386 {
|
Chris@16
|
387 (void)uses_allocator; (void)inner_alloc;
|
Chris@16
|
388 allocator_traits<OutermostAlloc>::construct
|
Chris@16
|
389 (outermost_alloc, p, ::boost::forward<Args>(args)...);
|
Chris@16
|
390 }
|
Chris@16
|
391
|
Chris@16
|
392 #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
393
|
Chris@101
|
394 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
|
Chris@101
|
395 template < typename OutermostAlloc, typename InnerAlloc, typename T\
|
Chris@101
|
396 BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
|
Chris@101
|
397 inline void dispatch_allocator_prefix_suffix\
|
Chris@101
|
398 (true_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\
|
Chris@101
|
399 InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
Chris@101
|
400 {\
|
Chris@101
|
401 (void)use_alloc_prefix,\
|
Chris@101
|
402 allocator_traits<OutermostAlloc>::construct\
|
Chris@101
|
403 (outermost_alloc, p, allocator_arg, inner_alloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
Chris@101
|
404 }\
|
Chris@101
|
405 \
|
Chris@101
|
406 template < typename OutermostAlloc, typename InnerAlloc, typename T\
|
Chris@101
|
407 BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
Chris@101
|
408 inline void dispatch_allocator_prefix_suffix\
|
Chris@101
|
409 (false_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\
|
Chris@101
|
410 InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
Chris@101
|
411 {\
|
Chris@101
|
412 (void)use_alloc_prefix;\
|
Chris@101
|
413 allocator_traits<OutermostAlloc>::construct\
|
Chris@101
|
414 (outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, inner_alloc);\
|
Chris@101
|
415 }\
|
Chris@101
|
416 \
|
Chris@101
|
417 template < typename OutermostAlloc, typename InnerAlloc, typename T\
|
Chris@101
|
418 BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
Chris@101
|
419 inline void dispatch_uses_allocator\
|
Chris@101
|
420 (true_type uses_allocator, OutermostAlloc& outermost_alloc,\
|
Chris@101
|
421 InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
Chris@101
|
422 {\
|
Chris@101
|
423 (void)uses_allocator;\
|
Chris@101
|
424 dispatch_allocator_prefix_suffix\
|
Chris@101
|
425 ( bool_< is_constructible_with_allocator_prefix<T, InnerAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::value >()\
|
Chris@101
|
426 , outermost_alloc, inner_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
Chris@101
|
427 }\
|
Chris@101
|
428 \
|
Chris@101
|
429 template < typename OutermostAlloc, typename InnerAlloc, typename T\
|
Chris@101
|
430 BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
Chris@101
|
431 inline void dispatch_uses_allocator\
|
Chris@101
|
432 (false_type uses_allocator, OutermostAlloc &outermost_alloc,\
|
Chris@101
|
433 InnerAlloc &inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
Chris@101
|
434 {\
|
Chris@101
|
435 (void)uses_allocator; (void)inner_alloc;\
|
Chris@101
|
436 allocator_traits<OutermostAlloc>::construct(outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
Chris@101
|
437 }\
|
Chris@101
|
438 //
|
Chris@101
|
439 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
|
Chris@101
|
440 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
|
Chris@16
|
441
|
Chris@16
|
442 #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
443
|
Chris@16
|
444 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
445
|
Chris@16
|
446 template <typename OuterAlloc, class ...InnerAllocs>
|
Chris@16
|
447 class scoped_allocator_adaptor_base
|
Chris@16
|
448 : public OuterAlloc
|
Chris@16
|
449 {
|
Chris@16
|
450 typedef allocator_traits<OuterAlloc> outer_traits_type;
|
Chris@16
|
451 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
|
Chris@16
|
452
|
Chris@16
|
453 public:
|
Chris@16
|
454 template <class OuterA2>
|
Chris@16
|
455 struct rebind_base
|
Chris@16
|
456 {
|
Chris@16
|
457 typedef scoped_allocator_adaptor_base<OuterA2, InnerAllocs...> other;
|
Chris@16
|
458 };
|
Chris@16
|
459
|
Chris@16
|
460 typedef OuterAlloc outer_allocator_type;
|
Chris@16
|
461 typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
|
Chris@16
|
462 typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
Chris@16
|
463 typedef scoped_allocator_adaptor
|
Chris@16
|
464 <OuterAlloc, InnerAllocs...> scoped_allocator_type;
|
Chris@101
|
465 typedef container_detail::bool_<
|
Chris@16
|
466 outer_traits_type::propagate_on_container_copy_assignment::value ||
|
Chris@16
|
467 inner_allocator_type::propagate_on_container_copy_assignment::value
|
Chris@16
|
468 > propagate_on_container_copy_assignment;
|
Chris@101
|
469 typedef container_detail::bool_<
|
Chris@16
|
470 outer_traits_type::propagate_on_container_move_assignment::value ||
|
Chris@16
|
471 inner_allocator_type::propagate_on_container_move_assignment::value
|
Chris@16
|
472 > propagate_on_container_move_assignment;
|
Chris@101
|
473 typedef container_detail::bool_<
|
Chris@16
|
474 outer_traits_type::propagate_on_container_swap::value ||
|
Chris@16
|
475 inner_allocator_type::propagate_on_container_swap::value
|
Chris@16
|
476 > propagate_on_container_swap;
|
Chris@101
|
477 typedef container_detail::bool_<
|
Chris@101
|
478 outer_traits_type::is_always_equal::value &&
|
Chris@101
|
479 inner_allocator_type::is_always_equal::value
|
Chris@101
|
480 > is_always_equal;
|
Chris@16
|
481
|
Chris@16
|
482 scoped_allocator_adaptor_base()
|
Chris@16
|
483 {}
|
Chris@16
|
484
|
Chris@16
|
485 template <class OuterA2>
|
Chris@16
|
486 scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
|
Chris@16
|
487 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
Chris@16
|
488 , m_inner(args...)
|
Chris@16
|
489 {}
|
Chris@16
|
490
|
Chris@16
|
491 scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
|
Chris@16
|
492 : outer_allocator_type(other.outer_allocator())
|
Chris@16
|
493 , m_inner(other.inner_allocator())
|
Chris@16
|
494 {}
|
Chris@16
|
495
|
Chris@16
|
496 scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
Chris@16
|
497 : outer_allocator_type(::boost::move(other.outer_allocator()))
|
Chris@16
|
498 , m_inner(::boost::move(other.inner_allocator()))
|
Chris@16
|
499 {}
|
Chris@16
|
500
|
Chris@16
|
501 template <class OuterA2>
|
Chris@16
|
502 scoped_allocator_adaptor_base
|
Chris@16
|
503 (const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
|
Chris@16
|
504 : outer_allocator_type(other.outer_allocator())
|
Chris@16
|
505 , m_inner(other.inner_allocator())
|
Chris@16
|
506 {}
|
Chris@16
|
507
|
Chris@16
|
508 template <class OuterA2>
|
Chris@16
|
509 scoped_allocator_adaptor_base
|
Chris@16
|
510 (BOOST_RV_REF_BEG scoped_allocator_adaptor_base
|
Chris@16
|
511 <OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
|
Chris@16
|
512 : outer_allocator_type(other.outer_allocator())
|
Chris@16
|
513 , m_inner(other.inner_allocator())
|
Chris@16
|
514 {}
|
Chris@16
|
515
|
Chris@16
|
516 public:
|
Chris@16
|
517 struct internal_type_t{};
|
Chris@16
|
518
|
Chris@16
|
519 template <class OuterA2>
|
Chris@16
|
520 scoped_allocator_adaptor_base
|
Chris@16
|
521 ( internal_type_t
|
Chris@16
|
522 , BOOST_FWD_REF(OuterA2) outerAlloc
|
Chris@16
|
523 , const inner_allocator_type &inner)
|
Chris@16
|
524 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
Chris@16
|
525 , m_inner(inner)
|
Chris@16
|
526 {}
|
Chris@16
|
527
|
Chris@16
|
528 public:
|
Chris@16
|
529
|
Chris@16
|
530 scoped_allocator_adaptor_base &operator=
|
Chris@16
|
531 (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
Chris@16
|
532 {
|
Chris@16
|
533 outer_allocator_type::operator=(other.outer_allocator());
|
Chris@16
|
534 m_inner = other.inner_allocator();
|
Chris@16
|
535 return *this;
|
Chris@16
|
536 }
|
Chris@16
|
537
|
Chris@16
|
538 scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
Chris@16
|
539 {
|
Chris@16
|
540 outer_allocator_type::operator=(boost::move(other.outer_allocator()));
|
Chris@16
|
541 m_inner = ::boost::move(other.inner_allocator());
|
Chris@16
|
542 return *this;
|
Chris@16
|
543 }
|
Chris@16
|
544
|
Chris@16
|
545 void swap(scoped_allocator_adaptor_base &r)
|
Chris@16
|
546 {
|
Chris@101
|
547 boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
|
Chris@101
|
548 boost::adl_move_swap(this->m_inner, r.inner_allocator());
|
Chris@16
|
549 }
|
Chris@16
|
550
|
Chris@16
|
551 friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
|
Chris@16
|
552 { l.swap(r); }
|
Chris@16
|
553
|
Chris@101
|
554 inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
555 { return m_inner; }
|
Chris@16
|
556
|
Chris@101
|
557 inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
558 { return m_inner; }
|
Chris@16
|
559
|
Chris@101
|
560 outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
561 { return static_cast<outer_allocator_type&>(*this); }
|
Chris@16
|
562
|
Chris@101
|
563 const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
564 { return static_cast<const outer_allocator_type&>(*this); }
|
Chris@16
|
565
|
Chris@16
|
566 scoped_allocator_type select_on_container_copy_construction() const
|
Chris@16
|
567 {
|
Chris@16
|
568 return scoped_allocator_type
|
Chris@16
|
569 (internal_type_t()
|
Chris@16
|
570 ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
|
Chris@16
|
571 ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
Chris@16
|
572 );
|
Chris@16
|
573 }
|
Chris@16
|
574
|
Chris@16
|
575 private:
|
Chris@16
|
576 inner_allocator_type m_inner;
|
Chris@16
|
577 };
|
Chris@16
|
578
|
Chris@16
|
579 #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
580
|
Chris@16
|
581 //Let's add a dummy first template parameter to allow creating
|
Chris@16
|
582 //specializations up to maximum InnerAlloc count
|
Chris@101
|
583 template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
|
Chris@16
|
584 class scoped_allocator_adaptor_base;
|
Chris@16
|
585
|
Chris@16
|
586 //Specializations for the adaptor with InnerAlloc allocators
|
Chris@16
|
587
|
Chris@101
|
588 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\
|
Chris@101
|
589 template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
|
Chris@101
|
590 class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
|
Chris@101
|
591 : public OuterAlloc\
|
Chris@101
|
592 {\
|
Chris@101
|
593 typedef allocator_traits<OuterAlloc> outer_traits_type;\
|
Chris@101
|
594 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\
|
Chris@101
|
595 \
|
Chris@101
|
596 public:\
|
Chris@101
|
597 template <class OuterA2>\
|
Chris@101
|
598 struct rebind_base\
|
Chris@101
|
599 {\
|
Chris@101
|
600 typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\
|
Chris@101
|
601 };\
|
Chris@101
|
602 \
|
Chris@101
|
603 typedef OuterAlloc outer_allocator_type;\
|
Chris@101
|
604 typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\
|
Chris@101
|
605 typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\
|
Chris@101
|
606 typedef allocator_traits<inner_allocator_type> inner_traits_type;\
|
Chris@101
|
607 typedef container_detail::bool_<\
|
Chris@101
|
608 outer_traits_type::propagate_on_container_copy_assignment::value ||\
|
Chris@101
|
609 inner_allocator_type::propagate_on_container_copy_assignment::value\
|
Chris@101
|
610 > propagate_on_container_copy_assignment;\
|
Chris@101
|
611 typedef container_detail::bool_<\
|
Chris@101
|
612 outer_traits_type::propagate_on_container_move_assignment::value ||\
|
Chris@101
|
613 inner_allocator_type::propagate_on_container_move_assignment::value\
|
Chris@101
|
614 > propagate_on_container_move_assignment;\
|
Chris@101
|
615 typedef container_detail::bool_<\
|
Chris@101
|
616 outer_traits_type::propagate_on_container_swap::value ||\
|
Chris@101
|
617 inner_allocator_type::propagate_on_container_swap::value\
|
Chris@101
|
618 > propagate_on_container_swap;\
|
Chris@101
|
619 \
|
Chris@101
|
620 typedef container_detail::bool_<\
|
Chris@101
|
621 outer_traits_type::is_always_equal::value &&\
|
Chris@101
|
622 inner_allocator_type::is_always_equal::value\
|
Chris@101
|
623 > is_always_equal;\
|
Chris@101
|
624 \
|
Chris@101
|
625 scoped_allocator_adaptor_base(){}\
|
Chris@101
|
626 \
|
Chris@101
|
627 template <class OuterA2>\
|
Chris@101
|
628 scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
|
Chris@101
|
629 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
|
Chris@101
|
630 , m_inner(BOOST_MOVE_ARG##N)\
|
Chris@101
|
631 {}\
|
Chris@101
|
632 \
|
Chris@101
|
633 scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\
|
Chris@101
|
634 : outer_allocator_type(other.outer_allocator())\
|
Chris@101
|
635 , m_inner(other.inner_allocator())\
|
Chris@101
|
636 {}\
|
Chris@101
|
637 \
|
Chris@101
|
638 scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
|
Chris@101
|
639 : outer_allocator_type(::boost::move(other.outer_allocator()))\
|
Chris@101
|
640 , m_inner(::boost::move(other.inner_allocator()))\
|
Chris@101
|
641 {}\
|
Chris@101
|
642 \
|
Chris@101
|
643 template <class OuterA2>\
|
Chris@101
|
644 scoped_allocator_adaptor_base\
|
Chris@101
|
645 (const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\
|
Chris@101
|
646 : outer_allocator_type(other.outer_allocator())\
|
Chris@101
|
647 , m_inner(other.inner_allocator())\
|
Chris@101
|
648 {}\
|
Chris@101
|
649 \
|
Chris@101
|
650 template <class OuterA2>\
|
Chris@101
|
651 scoped_allocator_adaptor_base\
|
Chris@101
|
652 (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\
|
Chris@101
|
653 : outer_allocator_type(other.outer_allocator())\
|
Chris@101
|
654 , m_inner(other.inner_allocator())\
|
Chris@101
|
655 {}\
|
Chris@101
|
656 \
|
Chris@101
|
657 public:\
|
Chris@101
|
658 struct internal_type_t{};\
|
Chris@101
|
659 \
|
Chris@101
|
660 template <class OuterA2>\
|
Chris@101
|
661 scoped_allocator_adaptor_base\
|
Chris@101
|
662 ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\
|
Chris@101
|
663 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
|
Chris@101
|
664 , m_inner(inner)\
|
Chris@101
|
665 {}\
|
Chris@101
|
666 \
|
Chris@101
|
667 public:\
|
Chris@101
|
668 scoped_allocator_adaptor_base &operator=\
|
Chris@101
|
669 (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
|
Chris@101
|
670 {\
|
Chris@101
|
671 outer_allocator_type::operator=(other.outer_allocator());\
|
Chris@101
|
672 m_inner = other.inner_allocator();\
|
Chris@101
|
673 return *this;\
|
Chris@101
|
674 }\
|
Chris@101
|
675 \
|
Chris@101
|
676 scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
|
Chris@101
|
677 {\
|
Chris@101
|
678 outer_allocator_type::operator=(boost::move(other.outer_allocator()));\
|
Chris@101
|
679 m_inner = ::boost::move(other.inner_allocator());\
|
Chris@101
|
680 return *this;\
|
Chris@101
|
681 }\
|
Chris@101
|
682 \
|
Chris@101
|
683 void swap(scoped_allocator_adaptor_base &r)\
|
Chris@101
|
684 {\
|
Chris@101
|
685 boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\
|
Chris@101
|
686 boost::adl_move_swap(this->m_inner, r.inner_allocator());\
|
Chris@101
|
687 }\
|
Chris@101
|
688 \
|
Chris@101
|
689 friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
|
Chris@101
|
690 { l.swap(r); }\
|
Chris@101
|
691 \
|
Chris@101
|
692 inner_allocator_type& inner_allocator()\
|
Chris@101
|
693 { return m_inner; }\
|
Chris@101
|
694 \
|
Chris@101
|
695 inner_allocator_type const& inner_allocator() const\
|
Chris@101
|
696 { return m_inner; }\
|
Chris@101
|
697 \
|
Chris@101
|
698 outer_allocator_type & outer_allocator()\
|
Chris@101
|
699 { return static_cast<outer_allocator_type&>(*this); }\
|
Chris@101
|
700 \
|
Chris@101
|
701 const outer_allocator_type &outer_allocator() const\
|
Chris@101
|
702 { return static_cast<const outer_allocator_type&>(*this); }\
|
Chris@101
|
703 \
|
Chris@101
|
704 scoped_allocator_type select_on_container_copy_construction() const\
|
Chris@101
|
705 {\
|
Chris@101
|
706 return scoped_allocator_type\
|
Chris@101
|
707 (internal_type_t()\
|
Chris@101
|
708 ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\
|
Chris@101
|
709 ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\
|
Chris@101
|
710 );\
|
Chris@101
|
711 }\
|
Chris@101
|
712 private:\
|
Chris@101
|
713 inner_allocator_type m_inner;\
|
Chris@101
|
714 };\
|
Chris@16
|
715 //!
|
Chris@101
|
716 BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE)
|
Chris@101
|
717 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE
|
Chris@16
|
718
|
Chris@16
|
719 #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@16
|
720
|
Chris@101
|
721 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@101
|
722 #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true
|
Chris@101
|
723 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9
|
Chris@101
|
724 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9
|
Chris@101
|
725 #else
|
Chris@101
|
726 #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE
|
Chris@101
|
727 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs...
|
Chris@101
|
728 #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs
|
Chris@101
|
729 #endif
|
Chris@101
|
730
|
Chris@16
|
731 //Specialization for adaptor without any InnerAlloc
|
Chris@16
|
732 template <typename OuterAlloc>
|
Chris@101
|
733 class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>
|
Chris@16
|
734 : public OuterAlloc
|
Chris@16
|
735 {
|
Chris@16
|
736 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
|
Chris@16
|
737 public:
|
Chris@16
|
738
|
Chris@16
|
739 template <class U>
|
Chris@16
|
740 struct rebind_base
|
Chris@16
|
741 {
|
Chris@16
|
742 typedef scoped_allocator_adaptor_base
|
Chris@16
|
743 <typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
|
Chris@101
|
744 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other;
|
Chris@16
|
745 };
|
Chris@16
|
746
|
Chris@16
|
747 typedef OuterAlloc outer_allocator_type;
|
Chris@16
|
748 typedef allocator_traits<OuterAlloc> outer_traits_type;
|
Chris@16
|
749 typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
|
Chris@16
|
750 typedef inner_allocator_type scoped_allocator_type;
|
Chris@16
|
751 typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
Chris@16
|
752 typedef typename outer_traits_type::
|
Chris@16
|
753 propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
Chris@16
|
754 typedef typename outer_traits_type::
|
Chris@16
|
755 propagate_on_container_move_assignment propagate_on_container_move_assignment;
|
Chris@16
|
756 typedef typename outer_traits_type::
|
Chris@16
|
757 propagate_on_container_swap propagate_on_container_swap;
|
Chris@101
|
758 typedef typename outer_traits_type::
|
Chris@101
|
759 is_always_equal is_always_equal;
|
Chris@16
|
760
|
Chris@16
|
761 scoped_allocator_adaptor_base()
|
Chris@16
|
762 {}
|
Chris@16
|
763
|
Chris@16
|
764 template <class OuterA2>
|
Chris@16
|
765 scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
|
Chris@16
|
766 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
Chris@16
|
767 {}
|
Chris@16
|
768
|
Chris@16
|
769 scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
|
Chris@16
|
770 : outer_allocator_type(other.outer_allocator())
|
Chris@16
|
771 {}
|
Chris@16
|
772
|
Chris@16
|
773 scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
Chris@16
|
774 : outer_allocator_type(::boost::move(other.outer_allocator()))
|
Chris@16
|
775 {}
|
Chris@16
|
776
|
Chris@16
|
777 template <class OuterA2>
|
Chris@16
|
778 scoped_allocator_adaptor_base
|
Chris@101
|
779 (const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other)
|
Chris@16
|
780 : outer_allocator_type(other.outer_allocator())
|
Chris@16
|
781 {}
|
Chris@16
|
782
|
Chris@16
|
783 template <class OuterA2>
|
Chris@16
|
784 scoped_allocator_adaptor_base
|
Chris@101
|
785 (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
|
Chris@16
|
786 : outer_allocator_type(other.outer_allocator())
|
Chris@16
|
787 {}
|
Chris@16
|
788
|
Chris@16
|
789 public:
|
Chris@16
|
790 struct internal_type_t{};
|
Chris@16
|
791
|
Chris@16
|
792 template <class OuterA2>
|
Chris@16
|
793 scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
|
Chris@16
|
794 : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
Chris@16
|
795 {}
|
Chris@101
|
796
|
Chris@16
|
797 public:
|
Chris@16
|
798 scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
Chris@16
|
799 {
|
Chris@16
|
800 outer_allocator_type::operator=(other.outer_allocator());
|
Chris@16
|
801 return *this;
|
Chris@16
|
802 }
|
Chris@16
|
803
|
Chris@16
|
804 scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
Chris@16
|
805 {
|
Chris@16
|
806 outer_allocator_type::operator=(boost::move(other.outer_allocator()));
|
Chris@16
|
807 return *this;
|
Chris@16
|
808 }
|
Chris@16
|
809
|
Chris@16
|
810 void swap(scoped_allocator_adaptor_base &r)
|
Chris@16
|
811 {
|
Chris@101
|
812 boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
|
Chris@16
|
813 }
|
Chris@16
|
814
|
Chris@16
|
815 friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
|
Chris@16
|
816 { l.swap(r); }
|
Chris@16
|
817
|
Chris@16
|
818 inner_allocator_type& inner_allocator()
|
Chris@16
|
819 { return static_cast<inner_allocator_type&>(*this); }
|
Chris@16
|
820
|
Chris@16
|
821 inner_allocator_type const& inner_allocator() const
|
Chris@16
|
822 { return static_cast<const inner_allocator_type&>(*this); }
|
Chris@16
|
823
|
Chris@16
|
824 outer_allocator_type & outer_allocator()
|
Chris@16
|
825 { return static_cast<outer_allocator_type&>(*this); }
|
Chris@16
|
826
|
Chris@16
|
827 const outer_allocator_type &outer_allocator() const
|
Chris@16
|
828 { return static_cast<const outer_allocator_type&>(*this); }
|
Chris@16
|
829
|
Chris@16
|
830 scoped_allocator_type select_on_container_copy_construction() const
|
Chris@16
|
831 {
|
Chris@16
|
832 return scoped_allocator_type
|
Chris@16
|
833 (internal_type_t()
|
Chris@16
|
834 ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
|
Chris@16
|
835 //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
Chris@16
|
836 //as inner_allocator() is equal to *this and that would trigger an infinite loop
|
Chris@16
|
837 , this->inner_allocator()
|
Chris@16
|
838 );
|
Chris@16
|
839 }
|
Chris@16
|
840 };
|
Chris@16
|
841
|
Chris@16
|
842 } //namespace container_detail {
|
Chris@16
|
843
|
Chris@101
|
844 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
845
|
Chris@16
|
846 //Scoped allocator
|
Chris@16
|
847 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
848
|
Chris@101
|
849 #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
Chris@16
|
850
|
Chris@101
|
851 //! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
|
Chris@101
|
852 //! The class template scoped_allocator_adaptor is an allocator template that specifies
|
Chris@101
|
853 //! the memory resource (the outer allocator) to be used by a container (as any other
|
Chris@101
|
854 //! allocator does) and also specifies an inner allocator resource to be passed to
|
Chris@101
|
855 //! the constructor of every element within the container.
|
Chris@101
|
856 //!
|
Chris@101
|
857 //! This adaptor is
|
Chris@101
|
858 //! instantiated with one outer and zero or more inner allocator types. If
|
Chris@101
|
859 //! instantiated with only one allocator type, the inner allocator becomes the
|
Chris@101
|
860 //! scoped_allocator_adaptor itself, thus using the same allocator resource for the
|
Chris@101
|
861 //! container and every element within the container and, if the elements themselves
|
Chris@101
|
862 //! are containers, each of their elements recursively. If instantiated with more than
|
Chris@101
|
863 //! one allocator, the first allocator is the outer allocator for use by the container,
|
Chris@101
|
864 //! the second allocator is passed to the constructors of the container's elements,
|
Chris@101
|
865 //! and, if the elements themselves are containers, the third allocator is passed to
|
Chris@101
|
866 //! the elements' elements, and so on. If containers are nested to a depth greater
|
Chris@101
|
867 //! than the number of allocators, the last allocator is used repeatedly, as in the
|
Chris@101
|
868 //! single-allocator case, for any remaining recursions.
|
Chris@101
|
869 //!
|
Chris@101
|
870 //! [<b>Note</b>: The
|
Chris@101
|
871 //! scoped_allocator_adaptor is derived from the outer allocator type so it can be
|
Chris@101
|
872 //! substituted for the outer allocator type in most expressions. -end note]
|
Chris@101
|
873 //!
|
Chris@101
|
874 //! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
|
Chris@101
|
875 //! an <code>outer_allocator()</code> member function and
|
Chris@101
|
876 //! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
|
Chris@101
|
877 //! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
|
Chris@101
|
878 //!
|
Chris@101
|
879 //! [<b>Note</b>: <code>OUTERMOST(x)</code> and
|
Chris@101
|
880 //! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
|
Chris@101
|
881 //! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
|
Chris@101
|
882 //! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
|
Chris@101
|
883 template <typename OuterAlloc, typename ...InnerAllocs>
|
Chris@101
|
884 class scoped_allocator_adaptor
|
Chris@16
|
885
|
Chris@101
|
886 #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
Chris@16
|
887
|
Chris@101
|
888 template <typename OuterAlloc, typename ...InnerAllocs>
|
Chris@101
|
889 class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
|
Chris@16
|
890
|
Chris@101
|
891 #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
Chris@16
|
892
|
Chris@16
|
893 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
894
|
Chris@101
|
895 template <typename OuterAlloc, BOOST_MOVE_CLASS9>
|
Chris@16
|
896 class scoped_allocator_adaptor
|
Chris@16
|
897 #endif
|
Chris@101
|
898
|
Chris@16
|
899 : public container_detail::scoped_allocator_adaptor_base
|
Chris@101
|
900 <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
|
Chris@16
|
901 {
|
Chris@16
|
902 BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
|
Chris@16
|
903
|
Chris@16
|
904 public:
|
Chris@101
|
905 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
906 typedef container_detail::scoped_allocator_adaptor_base
|
Chris@101
|
907 <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type;
|
Chris@16
|
908 typedef typename base_type::internal_type_t internal_type_t;
|
Chris@101
|
909 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
910 typedef OuterAlloc outer_allocator_type;
|
Chris@16
|
911 //! Type: For exposition only
|
Chris@16
|
912 //!
|
Chris@16
|
913 typedef allocator_traits<OuterAlloc> outer_traits_type;
|
Chris@101
|
914 //! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
|
Chris@101
|
915 //! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
|
Chris@16
|
916 typedef typename base_type::inner_allocator_type inner_allocator_type;
|
Chris@16
|
917 typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
Chris@16
|
918 typedef typename outer_traits_type::value_type value_type;
|
Chris@16
|
919 typedef typename outer_traits_type::size_type size_type;
|
Chris@16
|
920 typedef typename outer_traits_type::difference_type difference_type;
|
Chris@16
|
921 typedef typename outer_traits_type::pointer pointer;
|
Chris@16
|
922 typedef typename outer_traits_type::const_pointer const_pointer;
|
Chris@16
|
923 typedef typename outer_traits_type::void_pointer void_pointer;
|
Chris@16
|
924 typedef typename outer_traits_type::const_void_pointer const_void_pointer;
|
Chris@101
|
925 //! Type: A type with a constant boolean <code>value</code> == true if
|
Chris@101
|
926 //!`allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is
|
Chris@101
|
927 //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
Chris@16
|
928 typedef typename base_type::
|
Chris@16
|
929 propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
Chris@101
|
930 //! Type: A type with a constant boolean <code>value</code> == true if
|
Chris@101
|
931 //!`allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is
|
Chris@101
|
932 //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
Chris@16
|
933 typedef typename base_type::
|
Chris@16
|
934 propagate_on_container_move_assignment propagate_on_container_move_assignment;
|
Chris@101
|
935
|
Chris@101
|
936 //! Type: A type with a constant boolean <code>value</code> == true if
|
Chris@101
|
937 //! `allocator_traits<Allocator>::propagate_on_container_swap::value` is
|
Chris@101
|
938 //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
Chris@16
|
939 typedef typename base_type::
|
Chris@16
|
940 propagate_on_container_swap propagate_on_container_swap;
|
Chris@16
|
941
|
Chris@101
|
942 //! Type: A type with a constant boolean <code>value</code> == true if
|
Chris@101
|
943 //!`allocator_traits<Allocator>::is_always_equal::value` is
|
Chris@101
|
944 //! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
Chris@101
|
945 typedef typename base_type::
|
Chris@101
|
946 is_always_equal is_always_equal;
|
Chris@101
|
947
|
Chris@16
|
948 //! Type: Rebinds scoped allocator to
|
Chris@101
|
949 //! <code>typedef scoped_allocator_adaptor
|
Chris@16
|
950 //! < typename outer_traits_type::template portable_rebind_alloc<U>::type
|
Chris@101
|
951 //! , InnerAllocs... ></code>
|
Chris@16
|
952 template <class U>
|
Chris@16
|
953 struct rebind
|
Chris@16
|
954 {
|
Chris@16
|
955 typedef scoped_allocator_adaptor
|
Chris@16
|
956 < typename outer_traits_type::template portable_rebind_alloc<U>::type
|
Chris@101
|
957 , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other;
|
Chris@16
|
958 };
|
Chris@16
|
959
|
Chris@16
|
960 //! <b>Effects</b>: value-initializes the OuterAlloc base class
|
Chris@16
|
961 //! and the inner allocator object.
|
Chris@16
|
962 scoped_allocator_adaptor()
|
Chris@16
|
963 {}
|
Chris@16
|
964
|
Chris@16
|
965 ~scoped_allocator_adaptor()
|
Chris@16
|
966 {}
|
Chris@16
|
967
|
Chris@16
|
968 //! <b>Effects</b>: initializes each allocator within the adaptor with
|
Chris@16
|
969 //! the corresponding allocator from other.
|
Chris@16
|
970 scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
|
Chris@16
|
971 : base_type(other.base())
|
Chris@16
|
972 {}
|
Chris@16
|
973
|
Chris@16
|
974 //! <b>Effects</b>: move constructs each allocator within the adaptor with
|
Chris@16
|
975 //! the corresponding allocator from other.
|
Chris@16
|
976 scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
|
Chris@16
|
977 : base_type(::boost::move(other.base()))
|
Chris@16
|
978 {}
|
Chris@16
|
979
|
Chris@16
|
980 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
981
|
Chris@16
|
982 //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
|
Chris@16
|
983 //!
|
Chris@16
|
984 //! <b>Effects</b>: initializes the OuterAlloc base class with boost::forward<OuterA2>(outerAlloc) and inner
|
Chris@16
|
985 //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the
|
Chris@16
|
986 //! corresponding allocator from the argument list).
|
Chris@16
|
987 template <class OuterA2>
|
Chris@16
|
988 scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
|
Chris@16
|
989 : base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
|
Chris@16
|
990 {}
|
Chris@16
|
991 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
992
|
Chris@101
|
993 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\
|
Chris@101
|
994 template <class OuterA2>\
|
Chris@101
|
995 scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\
|
Chris@101
|
996 : base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\
|
Chris@101
|
997 {}\
|
Chris@101
|
998 //
|
Chris@101
|
999 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE)
|
Chris@101
|
1000 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE
|
Chris@16
|
1001
|
Chris@16
|
1002 #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1003
|
Chris@16
|
1004 //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
|
Chris@16
|
1005 //!
|
Chris@16
|
1006 //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
|
Chris@16
|
1007 template <class OuterA2>
|
Chris@101
|
1008 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
|
Chris@16
|
1009 : base_type(other.base())
|
Chris@16
|
1010 {}
|
Chris@16
|
1011
|
Chris@16
|
1012 //! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
|
Chris@16
|
1013 //!
|
Chris@16
|
1014 //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator
|
Chris@16
|
1015 //! rvalue from other.
|
Chris@16
|
1016 template <class OuterA2>
|
Chris@101
|
1017 scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor
|
Chris@101
|
1018 <OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other)
|
Chris@16
|
1019 : base_type(::boost::move(other.base()))
|
Chris@16
|
1020 {}
|
Chris@16
|
1021
|
Chris@16
|
1022 scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
|
Chris@16
|
1023 { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
|
Chris@16
|
1024
|
Chris@16
|
1025 scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
|
Chris@101
|
1026 { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
|
Chris@16
|
1027
|
Chris@16
|
1028 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1029 //! <b>Effects</b>: swaps *this with r.
|
Chris@16
|
1030 //!
|
Chris@16
|
1031 void swap(scoped_allocator_adaptor &r);
|
Chris@16
|
1032
|
Chris@16
|
1033 //! <b>Effects</b>: swaps *this with r.
|
Chris@16
|
1034 //!
|
Chris@16
|
1035 friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
|
Chris@16
|
1036
|
Chris@16
|
1037 //! <b>Returns</b>:
|
Chris@101
|
1038 //! <code>static_cast<OuterAlloc&>(*this)</code>.
|
Chris@101
|
1039 outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
|
Chris@16
|
1040
|
Chris@16
|
1041 //! <b>Returns</b>:
|
Chris@101
|
1042 //! <code>static_cast<const OuterAlloc&>(*this)</code>.
|
Chris@101
|
1043 const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
|
Chris@16
|
1044
|
Chris@16
|
1045 //! <b>Returns</b>:
|
Chris@101
|
1046 //! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
Chris@101
|
1047 inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
|
Chris@16
|
1048
|
Chris@16
|
1049 //! <b>Returns</b>:
|
Chris@101
|
1050 //! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
Chris@101
|
1051 inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
|
Chris@16
|
1052
|
Chris@16
|
1053 #endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1054
|
Chris@16
|
1055 //! <b>Returns</b>:
|
Chris@101
|
1056 //! <code>allocator_traits<OuterAlloc>::max_size(outer_allocator())</code>.
|
Chris@101
|
1057 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@101
|
1058 { return outer_traits_type::max_size(this->outer_allocator()); }
|
Chris@16
|
1059
|
Chris@16
|
1060 //! <b>Effects</b>:
|
Chris@101
|
1061 //! calls <code>OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)</code>.
|
Chris@16
|
1062 template <class T>
|
Chris@101
|
1063 void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
1064 {
|
Chris@16
|
1065 allocator_traits<typename outermost_allocator<OuterAlloc>::type>
|
Chris@16
|
1066 ::destroy(get_outermost_allocator(this->outer_allocator()), p);
|
Chris@16
|
1067 }
|
Chris@16
|
1068
|
Chris@16
|
1069 //! <b>Returns</b>:
|
Chris@101
|
1070 //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
|
Chris@16
|
1071 pointer allocate(size_type n)
|
Chris@101
|
1072 { return outer_traits_type::allocate(this->outer_allocator(), n); }
|
Chris@16
|
1073
|
Chris@16
|
1074 //! <b>Returns</b>:
|
Chris@101
|
1075 //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
|
Chris@16
|
1076 pointer allocate(size_type n, const_void_pointer hint)
|
Chris@101
|
1077 { return outer_traits_type::allocate(this->outer_allocator(), n, hint); }
|
Chris@16
|
1078
|
Chris@16
|
1079 //! <b>Effects</b>:
|
Chris@101
|
1080 //! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
|
Chris@16
|
1081 void deallocate(pointer p, size_type n)
|
Chris@101
|
1082 { outer_traits_type::deallocate(this->outer_allocator(), p, n); }
|
Chris@16
|
1083
|
Chris@16
|
1084 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@101
|
1085 //! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator
|
Chris@101
|
1086 //! Allocator in the adaptor is initialized from the result of calling
|
Chris@101
|
1087 //! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
|
Chris@16
|
1088 //! the corresponding allocator in *this.
|
Chris@16
|
1089 scoped_allocator_adaptor select_on_container_copy_construction() const;
|
Chris@16
|
1090 #endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1091
|
Chris@101
|
1092 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1093 base_type &base() { return *this; }
|
Chris@16
|
1094
|
Chris@16
|
1095 const base_type &base() const { return *this; }
|
Chris@101
|
1096 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1097
|
Chris@16
|
1098 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1099
|
Chris@16
|
1100 //! <b>Effects</b>:
|
Chris@101
|
1101 //! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
|
Chris@101
|
1102 //! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct
|
Chris@101
|
1103 //! (OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
|
Chris@16
|
1104 //!
|
Chris@101
|
1105 //! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
|
Chris@101
|
1106 //! <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value</code> is true, calls
|
Chris@101
|
1107 //! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
|
Chris@101
|
1108 //! inner_allocator(), std::forward<Args>(args)...)</code>.
|
Chris@16
|
1109 //!
|
Chris@101
|
1110 //! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
|
Chris@16
|
1111 //! be implemented so that condition will be replaced by
|
Chris@16
|
1112 //! constructible_with_allocator_prefix<T>::value. -end note]
|
Chris@16
|
1113 //!
|
Chris@16
|
1114 //! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
|
Chris@101
|
1115 //! <code>is_constructible<T, Args..., inner_allocator_type>::value</code> is true, calls
|
Chris@101
|
1116 //! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
|
Chris@101
|
1117 //! std::forward<Args>(args)..., inner_allocator())</code>.
|
Chris@16
|
1118 //!
|
Chris@101
|
1119 //! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
|
Chris@16
|
1120 //! implemented so that condition will be replaced by
|
Chris@101
|
1121 //! <code>constructible_with_allocator_suffix<T>::value</code>. -end note]
|
Chris@16
|
1122 //!
|
Chris@16
|
1123 //! 4) Otherwise, the program is ill-formed.
|
Chris@16
|
1124 //!
|
Chris@101
|
1125 //! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
|
Chris@16
|
1126 //! to true but the specific constructor does not take an allocator. This definition prevents a silent
|
Chris@16
|
1127 //! failure to pass an inner allocator to a contained element. -end note]
|
Chris@16
|
1128 template < typename T, class ...Args>
|
Chris@16
|
1129 #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1130 void
|
Chris@16
|
1131 #else
|
Chris@16
|
1132 typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type
|
Chris@16
|
1133 #endif
|
Chris@16
|
1134 construct(T* p, BOOST_FWD_REF(Args)...args)
|
Chris@16
|
1135 {
|
Chris@16
|
1136 container_detail::dispatch_uses_allocator
|
Chris@101
|
1137 ( container_detail::bool_<uses_allocator<T, inner_allocator_type>::value>()
|
Chris@16
|
1138 , get_outermost_allocator(this->outer_allocator())
|
Chris@16
|
1139 , this->inner_allocator()
|
Chris@16
|
1140 , p, ::boost::forward<Args>(args)...);
|
Chris@16
|
1141 }
|
Chris@16
|
1142
|
Chris@16
|
1143 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1144
|
Chris@16
|
1145 //Disable this overload if the first argument is pair as some compilers have
|
Chris@16
|
1146 //overload selection problems when the first parameter is a pair.
|
Chris@101
|
1147 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
|
Chris@101
|
1148 template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
|
Chris@101
|
1149 typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type\
|
Chris@101
|
1150 construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
|
Chris@101
|
1151 {\
|
Chris@101
|
1152 container_detail::dispatch_uses_allocator\
|
Chris@101
|
1153 ( container_detail::bool_<uses_allocator<T, inner_allocator_type>::value>()\
|
Chris@101
|
1154 , get_outermost_allocator(this->outer_allocator())\
|
Chris@101
|
1155 , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
|
Chris@101
|
1156 }\
|
Chris@101
|
1157 //
|
Chris@101
|
1158 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE)
|
Chris@101
|
1159 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE
|
Chris@16
|
1160
|
Chris@16
|
1161 #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1162
|
Chris@16
|
1163 template <class T1, class T2>
|
Chris@16
|
1164 void construct(std::pair<T1,T2>* p)
|
Chris@16
|
1165 { this->construct_pair(p); }
|
Chris@16
|
1166
|
Chris@16
|
1167 template <class T1, class T2>
|
Chris@16
|
1168 void construct(container_detail::pair<T1,T2>* p)
|
Chris@16
|
1169 { this->construct_pair(p); }
|
Chris@16
|
1170
|
Chris@16
|
1171 template <class T1, class T2, class U, class V>
|
Chris@16
|
1172 void construct(std::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
Chris@16
|
1173 { this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<V>(y)); }
|
Chris@16
|
1174
|
Chris@16
|
1175 template <class T1, class T2, class U, class V>
|
Chris@16
|
1176 void construct(container_detail::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
Chris@16
|
1177 { this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<V>(y)); }
|
Chris@101
|
1178
|
Chris@16
|
1179 template <class T1, class T2, class U, class V>
|
Chris@16
|
1180 void construct(std::pair<T1, T2>* p, const std::pair<U, V>& x)
|
Chris@16
|
1181 { this->construct_pair(p, x); }
|
Chris@16
|
1182
|
Chris@16
|
1183 template <class T1, class T2, class U, class V>
|
Chris@16
|
1184 void construct( container_detail::pair<T1, T2>* p
|
Chris@16
|
1185 , const container_detail::pair<U, V>& x)
|
Chris@16
|
1186 { this->construct_pair(p, x); }
|
Chris@101
|
1187
|
Chris@16
|
1188 template <class T1, class T2, class U, class V>
|
Chris@16
|
1189 void construct( std::pair<T1, T2>* p
|
Chris@16
|
1190 , BOOST_RV_REF_BEG std::pair<U, V> BOOST_RV_REF_END x)
|
Chris@16
|
1191 { this->construct_pair(p, x); }
|
Chris@16
|
1192
|
Chris@16
|
1193 template <class T1, class T2, class U, class V>
|
Chris@16
|
1194 void construct( container_detail::pair<T1, T2>* p
|
Chris@16
|
1195 , BOOST_RV_REF_BEG container_detail::pair<U, V> BOOST_RV_REF_END x)
|
Chris@16
|
1196 { this->construct_pair(p, x); }
|
Chris@16
|
1197
|
Chris@101
|
1198 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1199 private:
|
Chris@16
|
1200 template <class Pair>
|
Chris@16
|
1201 void construct_pair(Pair* p)
|
Chris@16
|
1202 {
|
Chris@16
|
1203 this->construct(container_detail::addressof(p->first));
|
Chris@16
|
1204 BOOST_TRY{
|
Chris@16
|
1205 this->construct(container_detail::addressof(p->second));
|
Chris@16
|
1206 }
|
Chris@16
|
1207 BOOST_CATCH(...){
|
Chris@16
|
1208 this->destroy(container_detail::addressof(p->first));
|
Chris@16
|
1209 BOOST_RETHROW
|
Chris@16
|
1210 }
|
Chris@16
|
1211 BOOST_CATCH_END
|
Chris@16
|
1212 }
|
Chris@16
|
1213
|
Chris@16
|
1214 template <class Pair, class U, class V>
|
Chris@16
|
1215 void construct_pair(Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
Chris@16
|
1216 {
|
Chris@16
|
1217 this->construct(container_detail::addressof(p->first), ::boost::forward<U>(x));
|
Chris@16
|
1218 BOOST_TRY{
|
Chris@16
|
1219 this->construct(container_detail::addressof(p->second), ::boost::forward<V>(y));
|
Chris@16
|
1220 }
|
Chris@16
|
1221 BOOST_CATCH(...){
|
Chris@16
|
1222 this->destroy(container_detail::addressof(p->first));
|
Chris@16
|
1223 BOOST_RETHROW
|
Chris@16
|
1224 }
|
Chris@16
|
1225 BOOST_CATCH_END
|
Chris@16
|
1226 }
|
Chris@16
|
1227
|
Chris@16
|
1228 template <class Pair, class Pair2>
|
Chris@16
|
1229 void construct_pair(Pair* p, const Pair2& pr)
|
Chris@101
|
1230 { this->construct_pair(p, pr.first, pr.second); }
|
Chris@16
|
1231
|
Chris@16
|
1232 template <class Pair, class Pair2>
|
Chris@16
|
1233 void construct_pair(Pair* p, BOOST_RV_REF(Pair2) pr)
|
Chris@101
|
1234 { this->construct_pair(p, ::boost::move(pr.first), ::boost::move(pr.second)); }
|
Chris@16
|
1235
|
Chris@16
|
1236 //template <class T1, class T2, class... Args1, class... Args2>
|
Chris@16
|
1237 //void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
|
Chris@16
|
1238
|
Chris@16
|
1239 public:
|
Chris@16
|
1240 //Internal function
|
Chris@16
|
1241 template <class OuterA2>
|
Chris@16
|
1242 scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
|
Chris@16
|
1243 : base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
|
Chris@16
|
1244 {}
|
Chris@16
|
1245
|
Chris@101
|
1246 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
Chris@16
|
1247 };
|
Chris@16
|
1248
|
Chris@101
|
1249 template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
|
Chris@101
|
1250 inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
|
Chris@101
|
1251 ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
|
Chris@101
|
1252 {
|
Chris@16
|
1253 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
Chris@16
|
1254 const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
|
Chris@16
|
1255 #else
|
Chris@101
|
1256 const bool has_zero_inner = boost::container::container_detail::is_same<P0, void>::value;
|
Chris@16
|
1257 #endif
|
Chris@101
|
1258 typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
|
Chris@101
|
1259 ::outer_allocator_type outer_allocator_type;
|
Chris@101
|
1260 typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
|
Chris@101
|
1261 ::inner_allocator_type inner_allocator_type;
|
Chris@101
|
1262
|
Chris@101
|
1263 return allocator_traits<outer_allocator_type>::equal(a.outer_allocator(), b.outer_allocator())
|
Chris@101
|
1264 && (has_zero_inner ||
|
Chris@101
|
1265 allocator_traits<inner_allocator_type>::equal(a.inner_allocator(), b.inner_allocator()));
|
Chris@16
|
1266 }
|
Chris@16
|
1267
|
Chris@101
|
1268 template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
|
Chris@101
|
1269 inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
|
Chris@101
|
1270 ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
|
Chris@101
|
1271 { return !(a == b); }
|
Chris@16
|
1272
|
Chris@16
|
1273 }} // namespace boost { namespace container {
|
Chris@16
|
1274
|
Chris@16
|
1275 #include <boost/container/detail/config_end.hpp>
|
Chris@16
|
1276
|
Chris@16
|
1277 #endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
|