annotate DEPENDENCIES/generic/include/boost/container/scoped_allocator.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
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