diff options
Diffstat (limited to 'boost/container/scoped_allocator.hpp')
-rw-r--r-- | boost/container/scoped_allocator.hpp | 1061 |
1 files changed, 402 insertions, 659 deletions
diff --git a/boost/container/scoped_allocator.hpp b/boost/container/scoped_allocator.hpp index 0a2987194f..55514aae21 100644 --- a/boost/container/scoped_allocator.hpp +++ b/boost/container/scoped_allocator.hpp @@ -23,24 +23,31 @@ #include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/workaround.hpp> -#include <boost/container/scoped_allocator_fwd.hpp> -#include <boost/type_traits/integral_constant.hpp> + #include <boost/container/allocator_traits.hpp> -#include <boost/container/detail/type_traits.hpp> -#include <boost/container/detail/utilities.hpp> -#include <utility> +#include <boost/container/scoped_allocator_fwd.hpp> + +#include <boost/container/detail/addressof.hpp> +#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/pair.hpp> +#include <boost/container/detail/type_traits.hpp> + +#include <boost/move/adl_move_swap.hpp> +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/move/detail/fwd_macros.hpp> +#endif #include <boost/move/utility_core.hpp> + #include <boost/core/no_exceptions_support.hpp> namespace boost { namespace container { -//! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed +//! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed //! with an allocator as its last constructor argument. Ideally, all constructors of T (including the //! copy and move constructors) should have a variant that accepts a final argument of //! allocator_type. //! -//! <b>Requires</b>: if a specialization is derived from true_type, T must have a nested type, +//! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type, //! allocator_type and at least one constructor for which allocator_type is the last //! parameter. If not all constructors of T can be called with a final allocator_type argument, //! and if T is used in a context where a container must call such a constructor, then the program is @@ -63,10 +70,10 @@ namespace boost { namespace container { //! // Specialize trait for class template Z //! template <class T, class Allocator = allocator<T> > //! struct constructible_with_allocator_suffix<Z<T,Allocator> > -//! : ::boost::true_type { }; +//! { static const bool value = true; }; //! </code> //! -//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)" +//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)" //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as //! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. //! Applications aiming portability with several compilers should always define this trait. @@ -76,15 +83,14 @@ namespace boost { namespace container { //! to detect if a type should be constructed with suffix or prefix allocator arguments. template <class T> struct constructible_with_allocator_suffix - : ::boost::false_type -{}; +{ static const bool value = false; }; -//! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed +//! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed //! with allocator_arg and T::allocator_type as its first two constructor arguments. //! Ideally, all constructors of T (including the copy and move constructors) should have a variant //! that accepts these two initial arguments. //! -//! <b>Requires</b>: if a specialization is derived from true_type, T must have a nested type, +//! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type, //! allocator_type and at least one constructor for which allocator_arg_t is the first //! parameter and allocator_type is the second parameter. If not all constructors of T can be //! called with these initial arguments, and if T is used in a context where a container must call such @@ -107,13 +113,13 @@ struct constructible_with_allocator_suffix //! // Variadic constructor and allocator-extended variadic constructor //! template<class ...Args> Y(Args&& args...); //! template<class ...Args> -//! Y(allocator_arg_t, const allocator_type& a, Args&&... args); +//! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args); //! }; //! //! // Specialize trait for class template Y //! template <class T, class Allocator = allocator<T> > //! struct constructible_with_allocator_prefix<Y<T,Allocator> > -//! : ::boost::true_type { }; +//! { static const bool value = true; }; //! //! </code> //! @@ -127,34 +133,34 @@ struct constructible_with_allocator_suffix //! to detect if a type should be constructed with suffix or prefix allocator arguments. template <class T> struct constructible_with_allocator_prefix - : ::boost::false_type -{}; +{ static const bool value = false; }; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { -template<typename T, typename Alloc> +template<typename T, typename Allocator> struct uses_allocator_imp { // Use SFINAE (Substitution Failure Is Not An Error) to detect the - // presence of an 'allocator_type' nested type convertilble from Alloc. - + // presence of an 'allocator_type' nested type convertilble from Allocator. private: + typedef char yes_type; + struct no_type{ char dummy[2]; }; + // Match this function if TypeT::allocator_type exists and is - // implicitly convertible from Alloc - template <typename U> - static char test(int, typename U::allocator_type); + // implicitly convertible from Allocator + template <class U> + static yes_type test(typename U::allocator_type); // Match this function if TypeT::allocator_type does not exist or is - // not convertible from Alloc. + // not convertible from Allocator. template <typename U> - static int test(LowPriorityConversion<int>, LowPriorityConversion<Alloc>); - - static Alloc alloc; // Declared but not defined + static no_type test(...); + static Allocator alloc; // Declared but not defined public: - enum { value = sizeof(test<T>(0, alloc)) == sizeof(char) }; + static const bool value = sizeof(test<T>(alloc)) == sizeof(yes_type); }; } //namespace container_detail { @@ -162,31 +168,34 @@ struct uses_allocator_imp #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! <b>Remark</b>: Automatically detects if T has a nested allocator_type that is convertible from -//! Alloc. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may -//! specialize this type to derive from true_type for a T of user-defined type if T does not -//! have a nested allocator_type but is nonetheless constructible using the specified Alloc. +//! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may +//! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not +//! have a nested allocator_type but is nonetheless constructible using the specified Allocator. //! -//! <b>Result</b>: derived from true_type if Convertible<Alloc,T::allocator_type> and -//! derived from false_type otherwise. -template <typename T, typename Alloc> +//! <b>Result</b>: uses_allocator<T, Allocator>::value== true if Convertible<Allocator,T::allocator_type>, +//! false otherwise. +template <typename T, typename Allocator> struct uses_allocator - : boost::integral_constant<bool, container_detail::uses_allocator_imp<T, Alloc>::value> + : container_detail::uses_allocator_imp<T, Allocator> {}; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { -template <typename Alloc> +template <typename Allocator> struct is_scoped_allocator_imp { + typedef char yes_type; + struct no_type{ char dummy[2]; }; + template <typename T> - static char test(int, typename T::outer_allocator_type*); + static yes_type test(typename T::outer_allocator_type*); template <typename T> - static int test(LowPriorityConversion<int>, void*); + static int test(...); - static const bool value = (sizeof(char) == sizeof(test<Alloc>(0, 0))); + static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0))); }; template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value > @@ -229,40 +238,38 @@ struct outermost_allocator_imp<MaybeScopedAlloc, true> } //namespace container_detail { -template <typename Alloc> +template <typename Allocator> struct is_scoped_allocator - : boost::integral_constant<bool, container_detail::is_scoped_allocator_imp<Alloc>::value> + : container_detail::is_scoped_allocator_imp<Allocator> {}; -template <typename Alloc> +template <typename Allocator> struct outermost_allocator - : container_detail::outermost_allocator_imp<Alloc> + : container_detail::outermost_allocator_imp<Allocator> {}; -template <typename Alloc> -typename container_detail::outermost_allocator_imp<Alloc>::type & - get_outermost_allocator(Alloc &a) -{ return container_detail::outermost_allocator_imp<Alloc>::get(a); } +template <typename Allocator> +typename container_detail::outermost_allocator_imp<Allocator>::type & + get_outermost_allocator(Allocator &a) +{ return container_detail::outermost_allocator_imp<Allocator>::get(a); } -template <typename Alloc> -const typename container_detail::outermost_allocator_imp<Alloc>::type & - get_outermost_allocator(const Alloc &a) -{ return container_detail::outermost_allocator_imp<Alloc>::get(a); } +template <typename Allocator> +const typename container_detail::outermost_allocator_imp<Allocator>::type & + get_outermost_allocator(const Allocator &a) +{ return container_detail::outermost_allocator_imp<Allocator>::get(a); } namespace container_detail { // Check if we can detect is_convertible using advanced SFINAE expressions -#if !defined(BOOST_NO_SFINAE_EXPR) +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html //! Thanks Mathias! //With variadic templates, we need a single class to implement the trait - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template<class T, class ...Args> - struct is_constructible_impl + struct is_constructible { typedef char yes_type; struct no_type @@ -272,7 +279,7 @@ namespace container_detail { struct dummy; template<class X> - static yes_type test(dummy<sizeof(X(boost::move_detail::declval<Args>()...))>*); + static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int); template<class X> static no_type test(...); @@ -280,148 +287,39 @@ namespace container_detail { static const bool value = sizeof(test<T>(0)) == sizeof(yes_type); }; - template<class T, class ...Args> - struct is_constructible - : boost::integral_constant<bool, is_constructible_impl<T, Args...>::value> - {}; - template <class T, class InnerAlloc, class ...Args> struct is_constructible_with_allocator_prefix : is_constructible<T, allocator_arg_t, InnerAlloc, Args...> {}; - #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - - //Without variadic templates, we need to use the preprocessor to generate - //some specializations. - - #define BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS \ - BOOST_PP_ADD(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, 3) - //! - - //Generate N+1 template parameters so that we can specialize N - template<class T - BOOST_PP_ENUM_TRAILING( BOOST_PP_ADD(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1) - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > - struct is_constructible_impl; - - //Generate N specializations, from 0 to - //BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS parameters - #define BOOST_PP_LOCAL_MACRO(n) \ - template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> \ - struct is_constructible_impl \ - <T BOOST_PP_ENUM_TRAILING_PARAMS(n, P) \ - BOOST_PP_ENUM_TRAILING \ - ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, void) \ - , void> \ - { \ - typedef char yes_type; \ - struct no_type \ - { char padding[2]; }; \ - \ - template<std::size_t N> \ - struct dummy; \ - \ - template<class X> \ - static yes_type test(dummy<sizeof(X(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_DECLVAL, ~)))>*); \ - \ - template<class X> \ - static no_type test(...); \ - \ - static const bool value = sizeof(test<T>(0)) == sizeof(yes_type); \ - }; \ - //! - - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() - - //Finally just inherit from the implementation to define he trait - template< class T - BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > - struct is_constructible - : boost::integral_constant - < bool - , is_constructible_impl - < T - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, P) - , void>::value - > - {}; - - //Finally just inherit from the implementation to define he trait - template <class T - ,class InnerAlloc - BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 2) - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > - struct is_constructible_with_allocator_prefix - : is_constructible - < T, allocator_arg_t, InnerAlloc - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 2), P) - > - {}; -/* - template <class T - ,class InnerAlloc - BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1) - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > - struct is_constructible_with_allocator_suffix - : is_constructible - < T - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1), P) - , InnerAlloc - > - {};*/ - - #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -#else // #if !defined(BOOST_NO_SFINAE_EXPR) +#else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) //Without advanced SFINAE expressions, we can't use is_constructible //so backup to constructible_with_allocator_xxx #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template < class T, class InnerAlloc, class ...Args> + template <class T, class InnerAlloc, class ...Args> struct is_constructible_with_allocator_prefix : constructible_with_allocator_prefix<T> {}; -/* - template < class T, class InnerAlloc, class ...Args> + + template <class T, class InnerAlloc, class ...Args> struct is_constructible_with_allocator_suffix : constructible_with_allocator_suffix<T> - {};*/ + {}; #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template < class T - , class InnerAlloc - BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > + template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9> struct is_constructible_with_allocator_prefix : constructible_with_allocator_prefix<T> {}; -/* - template < class T - , class InnerAlloc - BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS - , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT - , void) - > + + template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9> struct is_constructible_with_allocator_suffix : constructible_with_allocator_suffix<T> - {};*/ + {}; #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -429,13 +327,14 @@ namespace container_detail { #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +// allocator_arg_t template < typename OutermostAlloc , typename InnerAlloc , typename T , class ...Args > inline void dispatch_allocator_prefix_suffix - ( boost::true_type use_alloc_prefix, OutermostAlloc& outermost_alloc + ( true_type use_alloc_prefix, OutermostAlloc& outermost_alloc , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args) ...args) { (void)use_alloc_prefix; @@ -443,13 +342,14 @@ inline void dispatch_allocator_prefix_suffix ( outermost_alloc, p, allocator_arg, inner_alloc, ::boost::forward<Args>(args)...); } +// allocator suffix template < typename OutermostAlloc , typename InnerAlloc , typename T , class ...Args > inline void dispatch_allocator_prefix_suffix - ( boost::false_type use_alloc_prefix, OutermostAlloc& outermost_alloc + ( false_type use_alloc_prefix, OutermostAlloc& outermost_alloc , InnerAlloc &inner_alloc, T* p, BOOST_FWD_REF(Args)...args) { (void)use_alloc_prefix; @@ -463,14 +363,14 @@ template < typename OutermostAlloc , class ...Args > inline void dispatch_uses_allocator - ( boost::true_type uses_allocator, OutermostAlloc& outermost_alloc + ( true_type uses_allocator, OutermostAlloc& outermost_alloc , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args)...args) { (void)uses_allocator; //BOOST_STATIC_ASSERT((is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>::value || // is_constructible_with_allocator_suffix<T, InnerAlloc, Args...>::value )); dispatch_allocator_prefix_suffix - ( is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>() + ( bool_< is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>::value>() , outermost_alloc, inner_alloc, p, ::boost::forward<Args>(args)...); } @@ -480,7 +380,7 @@ template < typename OutermostAlloc , class ...Args > inline void dispatch_uses_allocator - ( boost::false_type uses_allocator, OutermostAlloc & outermost_alloc + ( false_type uses_allocator, OutermostAlloc & outermost_alloc , InnerAlloc & inner_alloc ,T* p, BOOST_FWD_REF(Args)...args) { @@ -491,78 +391,53 @@ inline void dispatch_uses_allocator #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#define BOOST_PP_LOCAL_MACRO(n) \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_allocator_prefix_suffix( \ - boost::true_type use_alloc_prefix, \ - OutermostAlloc& outermost_alloc, \ - InnerAlloc& inner_alloc, \ - T* p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)use_alloc_prefix, \ - allocator_traits<OutermostAlloc>::construct \ - (outermost_alloc, p, allocator_arg, inner_alloc \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ -} \ - \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_allocator_prefix_suffix( \ - boost::false_type use_alloc_prefix, \ - OutermostAlloc& outermost_alloc, \ - InnerAlloc& inner_alloc, \ - T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)use_alloc_prefix; \ - allocator_traits<OutermostAlloc>::construct \ - (outermost_alloc, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \ - , inner_alloc); \ -} \ - \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_uses_allocator(boost::true_type uses_allocator, \ - OutermostAlloc& outermost_alloc, \ - InnerAlloc& inner_alloc, \ - T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)uses_allocator; \ - dispatch_allocator_prefix_suffix \ - (is_constructible_with_allocator_prefix \ - < T, InnerAlloc BOOST_PP_ENUM_TRAILING_PARAMS(n, P)>() \ - , outermost_alloc, inner_alloc, p \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ -} \ - \ -template < typename OutermostAlloc \ - , typename InnerAlloc \ - , typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ -inline void dispatch_uses_allocator(boost::false_type uses_allocator \ - ,OutermostAlloc & outermost_alloc \ - ,InnerAlloc & inner_alloc \ - ,T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ -{ \ - (void)uses_allocator; (void)inner_alloc; \ - allocator_traits<OutermostAlloc>::construct \ - (outermost_alloc, p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ -} \ -//! -#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ +inline void dispatch_allocator_prefix_suffix\ + (true_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\ + InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)use_alloc_prefix,\ + allocator_traits<OutermostAlloc>::construct\ + (outermost_alloc, p, allocator_arg, inner_alloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ +}\ +\ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +inline void dispatch_allocator_prefix_suffix\ + (false_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\ + InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)use_alloc_prefix;\ + allocator_traits<OutermostAlloc>::construct\ + (outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, inner_alloc);\ +}\ +\ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +inline void dispatch_uses_allocator\ + (true_type uses_allocator, OutermostAlloc& outermost_alloc,\ + InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)uses_allocator;\ + dispatch_allocator_prefix_suffix\ + ( bool_< is_constructible_with_allocator_prefix<T, InnerAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::value >()\ + , outermost_alloc, inner_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ +}\ +\ +template < typename OutermostAlloc, typename InnerAlloc, typename T\ + BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +inline void dispatch_uses_allocator\ + (false_type uses_allocator, OutermostAlloc &outermost_alloc,\ + InnerAlloc &inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ +{\ + (void)uses_allocator; (void)inner_alloc;\ + allocator_traits<OutermostAlloc>::construct(outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ +}\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -587,21 +462,22 @@ class scoped_allocator_adaptor_base typedef allocator_traits<inner_allocator_type> inner_traits_type; typedef scoped_allocator_adaptor <OuterAlloc, InnerAllocs...> scoped_allocator_type; - typedef boost::integral_constant< - bool, + typedef container_detail::bool_< outer_traits_type::propagate_on_container_copy_assignment::value || inner_allocator_type::propagate_on_container_copy_assignment::value > propagate_on_container_copy_assignment; - typedef boost::integral_constant< - bool, + typedef container_detail::bool_< outer_traits_type::propagate_on_container_move_assignment::value || inner_allocator_type::propagate_on_container_move_assignment::value > propagate_on_container_move_assignment; - typedef boost::integral_constant< - bool, + typedef container_detail::bool_< outer_traits_type::propagate_on_container_swap::value || inner_allocator_type::propagate_on_container_swap::value > propagate_on_container_swap; + typedef container_detail::bool_< + outer_traits_type::is_always_equal::value && + inner_allocator_type::is_always_equal::value + > is_always_equal; scoped_allocator_adaptor_base() {} @@ -668,23 +544,23 @@ class scoped_allocator_adaptor_base void swap(scoped_allocator_adaptor_base &r) { - boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator()); - boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); + boost::adl_move_swap(this->m_inner, r.inner_allocator()); } friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) { l.swap(r); } - inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT + inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW { return m_inner; } - inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT + inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return m_inner; } - outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT + outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW { return static_cast<outer_allocator_type&>(*this); } - const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT + const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW { return static_cast<const outer_allocator_type&>(*this); } scoped_allocator_type select_on_container_copy_construction() const @@ -704,186 +580,157 @@ class scoped_allocator_adaptor_base //Let's add a dummy first template parameter to allow creating //specializations up to maximum InnerAlloc count -template < - typename OuterAlloc - , bool Dummy - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q) - > +template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9> class scoped_allocator_adaptor_base; //Specializations for the adaptor with InnerAlloc allocators -#define BOOST_PP_LOCAL_MACRO(n) \ -template <typename OuterAlloc \ -BOOST_PP_ENUM_TRAILING_PARAMS(n, class Q) \ -> \ -class scoped_allocator_adaptor_base<OuterAlloc, true \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \ - BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, nat) \ - > \ - : public OuterAlloc \ -{ \ - typedef allocator_traits<OuterAlloc> outer_traits_type; \ - BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) \ - \ - public: \ - template <class OuterA2> \ - struct rebind_base \ - { \ - typedef scoped_allocator_adaptor_base<OuterA2, true BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \ - BOOST_PP_ENUM_TRAILING \ - ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, nat) \ - > other; \ - }; \ - \ - typedef OuterAlloc outer_allocator_type; \ - typedef scoped_allocator_adaptor<BOOST_PP_ENUM_PARAMS(n, Q) \ - BOOST_PP_ENUM_TRAILING \ - ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, nat) \ - > inner_allocator_type; \ - typedef scoped_allocator_adaptor<OuterAlloc, BOOST_PP_ENUM_PARAMS(n, Q) \ - BOOST_PP_ENUM_TRAILING \ - ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, nat) \ - > scoped_allocator_type; \ - typedef allocator_traits<inner_allocator_type> inner_traits_type; \ - typedef boost::integral_constant< \ - bool, \ - outer_traits_type::propagate_on_container_copy_assignment::value || \ - inner_allocator_type::propagate_on_container_copy_assignment::value \ - > propagate_on_container_copy_assignment; \ - typedef boost::integral_constant< \ - bool, \ - outer_traits_type::propagate_on_container_move_assignment::value || \ - inner_allocator_type::propagate_on_container_move_assignment::value \ - > propagate_on_container_move_assignment; \ - typedef boost::integral_constant< \ - bool, \ - outer_traits_type::propagate_on_container_swap::value || \ - inner_allocator_type::propagate_on_container_swap::value \ - > propagate_on_container_swap; \ - \ - scoped_allocator_adaptor_base() \ - {} \ - \ - template <class OuterA2> \ - scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \ - : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \ - , m_inner(BOOST_PP_ENUM_PARAMS(n, q)) \ - {} \ - \ - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) \ - : outer_allocator_type(other.outer_allocator()) \ - , m_inner(other.inner_allocator()) \ - {} \ - \ - scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \ - : outer_allocator_type(::boost::move(other.outer_allocator())) \ - , m_inner(::boost::move(other.inner_allocator())) \ - {} \ - \ - template <class OuterA2> \ - scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base<OuterA2, true \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \ - BOOST_PP_ENUM_TRAILING \ - ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, nat) \ - >& other) \ - : outer_allocator_type(other.outer_allocator()) \ - , m_inner(other.inner_allocator()) \ - {} \ - \ - template <class OuterA2> \ - scoped_allocator_adaptor_base \ - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \ - BOOST_PP_ENUM_TRAILING \ - ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ - , BOOST_CONTAINER_PP_IDENTITY, nat) \ - > BOOST_RV_REF_END other) \ - : outer_allocator_type(other.outer_allocator()) \ - , m_inner(other.inner_allocator()) \ - {} \ - \ - public: \ - struct internal_type_t{}; \ - \ - template <class OuterA2> \ - scoped_allocator_adaptor_base \ - ( internal_type_t \ - , BOOST_FWD_REF(OuterA2) outerAlloc \ - , const inner_allocator_type &inner) \ - : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \ - , m_inner(inner) \ - {} \ - \ - public: \ - scoped_allocator_adaptor_base &operator= \ - (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) \ - { \ - outer_allocator_type::operator=(other.outer_allocator()); \ - m_inner = other.inner_allocator(); \ - return *this; \ - } \ - \ - scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \ - { \ - outer_allocator_type::operator=(boost::move(other.outer_allocator())); \ - m_inner = ::boost::move(other.inner_allocator()); \ - return *this; \ - } \ - \ - void swap(scoped_allocator_adaptor_base &r) \ - { \ - boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator()); \ - boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); \ - } \ - \ - friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) \ - { l.swap(r); } \ - \ - inner_allocator_type& inner_allocator() \ - { return m_inner; } \ - \ - inner_allocator_type const& inner_allocator() const \ - { return m_inner; } \ - \ - outer_allocator_type & outer_allocator() \ - { return static_cast<outer_allocator_type&>(*this); } \ - \ - const outer_allocator_type &outer_allocator() const \ - { return static_cast<const outer_allocator_type&>(*this); } \ - \ - scoped_allocator_type select_on_container_copy_construction() const \ - { \ - return scoped_allocator_type \ - (internal_type_t() \ - ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) \ - ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) \ - ); \ - } \ - private: \ - inner_allocator_type m_inner; \ -}; \ +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\ +template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\ +class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\ + : public OuterAlloc\ +{\ + typedef allocator_traits<OuterAlloc> outer_traits_type;\ + BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\ + \ + public:\ + template <class OuterA2>\ + struct rebind_base\ + {\ + typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\ + };\ + \ + typedef OuterAlloc outer_allocator_type;\ + typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\ + typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\ + typedef allocator_traits<inner_allocator_type> inner_traits_type;\ + typedef container_detail::bool_<\ + outer_traits_type::propagate_on_container_copy_assignment::value ||\ + inner_allocator_type::propagate_on_container_copy_assignment::value\ + > propagate_on_container_copy_assignment;\ + typedef container_detail::bool_<\ + outer_traits_type::propagate_on_container_move_assignment::value ||\ + inner_allocator_type::propagate_on_container_move_assignment::value\ + > propagate_on_container_move_assignment;\ + typedef container_detail::bool_<\ + outer_traits_type::propagate_on_container_swap::value ||\ + inner_allocator_type::propagate_on_container_swap::value\ + > propagate_on_container_swap;\ + \ + typedef container_detail::bool_<\ + outer_traits_type::is_always_equal::value &&\ + inner_allocator_type::is_always_equal::value\ + > is_always_equal;\ + \ + scoped_allocator_adaptor_base(){}\ + \ + template <class OuterA2>\ + scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\ + : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\ + , m_inner(BOOST_MOVE_ARG##N)\ + {}\ + \ + scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + : outer_allocator_type(::boost::move(other.outer_allocator()))\ + , m_inner(::boost::move(other.inner_allocator()))\ + {}\ + \ + template <class OuterA2>\ + scoped_allocator_adaptor_base\ + (const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + template <class OuterA2>\ + scoped_allocator_adaptor_base\ + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + public:\ + struct internal_type_t{};\ + \ + template <class OuterA2>\ + scoped_allocator_adaptor_base\ + ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\ + : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\ + , m_inner(inner)\ + {}\ + \ + public:\ + scoped_allocator_adaptor_base &operator=\ + (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\ + {\ + outer_allocator_type::operator=(other.outer_allocator());\ + m_inner = other.inner_allocator();\ + return *this;\ + }\ + \ + scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + {\ + outer_allocator_type::operator=(boost::move(other.outer_allocator()));\ + m_inner = ::boost::move(other.inner_allocator());\ + return *this;\ + }\ + \ + void swap(scoped_allocator_adaptor_base &r)\ + {\ + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\ + boost::adl_move_swap(this->m_inner, r.inner_allocator());\ + }\ + \ + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\ + { l.swap(r); }\ + \ + inner_allocator_type& inner_allocator()\ + { return m_inner; }\ + \ + inner_allocator_type const& inner_allocator() const\ + { return m_inner; }\ + \ + outer_allocator_type & outer_allocator()\ + { return static_cast<outer_allocator_type&>(*this); }\ + \ + const outer_allocator_type &outer_allocator() const\ + { return static_cast<const outer_allocator_type&>(*this); }\ + \ + scoped_allocator_type select_on_container_copy_construction() const\ + {\ + return scoped_allocator_type\ + (internal_type_t()\ + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\ + ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\ + );\ + }\ + private:\ + inner_allocator_type m_inner;\ +};\ //! -#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) -#include BOOST_PP_LOCAL_ITERATE() +BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9 + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9 +#else + #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs... + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs +#endif + //Specialization for adaptor without any InnerAlloc template <typename OuterAlloc> -class scoped_allocator_adaptor_base - < OuterAlloc - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, nat) - #endif - > +class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> : public OuterAlloc { BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) @@ -894,11 +741,7 @@ class scoped_allocator_adaptor_base { typedef scoped_allocator_adaptor_base <typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat) - #endif - > other; + BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other; }; typedef OuterAlloc outer_allocator_type; @@ -912,6 +755,8 @@ class scoped_allocator_adaptor_base propagate_on_container_move_assignment propagate_on_container_move_assignment; typedef typename outer_traits_type:: propagate_on_container_swap propagate_on_container_swap; + typedef typename outer_traits_type:: + is_always_equal is_always_equal; scoped_allocator_adaptor_base() {} @@ -931,25 +776,13 @@ class scoped_allocator_adaptor_base template <class OuterA2> scoped_allocator_adaptor_base - (const scoped_allocator_adaptor_base< - OuterA2 - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat) - #endif - >& other) + (const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other) : outer_allocator_type(other.outer_allocator()) {} template <class OuterA2> scoped_allocator_adaptor_base - (BOOST_RV_REF_BEG scoped_allocator_adaptor_base< - OuterA2 - #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - , true - BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat) - #endif - > BOOST_RV_REF_END other) + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other) : outer_allocator_type(other.outer_allocator()) {} @@ -976,7 +809,7 @@ class scoped_allocator_adaptor_base void swap(scoped_allocator_adaptor_base &r) { - boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator()); + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); } friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) @@ -1013,78 +846,65 @@ class scoped_allocator_adaptor_base //Scoped allocator #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) +#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - //! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor. - //! The class template scoped_allocator_adaptor is an allocator template that specifies - //! the memory resource (the outer allocator) to be used by a container (as any other - //! allocator does) and also specifies an inner allocator resource to be passed to - //! the constructor of every element within the container. - //! - //! This adaptor is - //! instantiated with one outer and zero or more inner allocator types. If - //! instantiated with only one allocator type, the inner allocator becomes the - //! scoped_allocator_adaptor itself, thus using the same allocator resource for the - //! container and every element within the container and, if the elements themselves - //! are containers, each of their elements recursively. If instantiated with more than - //! one allocator, the first allocator is the outer allocator for use by the container, - //! the second allocator is passed to the constructors of the container's elements, - //! and, if the elements themselves are containers, the third allocator is passed to - //! the elements' elements, and so on. If containers are nested to a depth greater - //! than the number of allocators, the last allocator is used repeatedly, as in the - //! single-allocator case, for any remaining recursions. - //! - //! [<b>Note</b>: The - //! scoped_allocator_adaptor is derived from the outer allocator type so it can be - //! substituted for the outer allocator type in most expressions. -end note] - //! - //! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have - //! an <code>outer_allocator()</code> member function and - //! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is - //! <code>allocator_traits<decltype(OUTERMOST(x))></code>. - //! - //! [<b>Note</b>: <code>OUTERMOST(x)</code> and - //! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon - //! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates. - //! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] - template <typename OuterAlloc, typename ...InnerAllocs> - class scoped_allocator_adaptor +//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor. +//! The class template scoped_allocator_adaptor is an allocator template that specifies +//! the memory resource (the outer allocator) to be used by a container (as any other +//! allocator does) and also specifies an inner allocator resource to be passed to +//! the constructor of every element within the container. +//! +//! This adaptor is +//! instantiated with one outer and zero or more inner allocator types. If +//! instantiated with only one allocator type, the inner allocator becomes the +//! scoped_allocator_adaptor itself, thus using the same allocator resource for the +//! container and every element within the container and, if the elements themselves +//! are containers, each of their elements recursively. If instantiated with more than +//! one allocator, the first allocator is the outer allocator for use by the container, +//! the second allocator is passed to the constructors of the container's elements, +//! and, if the elements themselves are containers, the third allocator is passed to +//! the elements' elements, and so on. If containers are nested to a depth greater +//! than the number of allocators, the last allocator is used repeatedly, as in the +//! single-allocator case, for any remaining recursions. +//! +//! [<b>Note</b>: The +//! scoped_allocator_adaptor is derived from the outer allocator type so it can be +//! substituted for the outer allocator type in most expressions. -end note] +//! +//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have +//! an <code>outer_allocator()</code> member function and +//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is +//! <code>allocator_traits<decltype(OUTERMOST(x))></code>. +//! +//! [<b>Note</b>: <code>OUTERMOST(x)</code> and +//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon +//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates. +//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] +template <typename OuterAlloc, typename ...InnerAllocs> +class scoped_allocator_adaptor - #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) +#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) - template <typename OuterAlloc, typename ...InnerAllocs> - class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...> +template <typename OuterAlloc, typename ...InnerAllocs> +class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...> - #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) +#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -template <typename OuterAlloc - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q) - > +template <typename OuterAlloc, BOOST_MOVE_CLASS9> class scoped_allocator_adaptor #endif + : public container_detail::scoped_allocator_adaptor_base - <OuterAlloc - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , InnerAllocs... - #else - , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - > + <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> { BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor) public: #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef container_detail::scoped_allocator_adaptor_base - <OuterAlloc - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , InnerAllocs... - #else - , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - > base_type; + <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type; typedef typename base_type::internal_type_t internal_type_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef OuterAlloc outer_allocator_type; @@ -1102,19 +922,29 @@ class scoped_allocator_adaptor typedef typename outer_traits_type::const_pointer const_pointer; typedef typename outer_traits_type::void_pointer void_pointer; typedef typename outer_traits_type::const_void_pointer const_void_pointer; - //! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_copy_assignment::value</code> is - //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type. + //! Type: A type with a constant boolean <code>value</code> == true if + //!`allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is + //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise. typedef typename base_type:: propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - //! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_move_assignment::value</code> is - //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type. + //! Type: A type with a constant boolean <code>value</code> == true if + //!`allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is + //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise. typedef typename base_type:: propagate_on_container_move_assignment propagate_on_container_move_assignment; - //! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_swap::value</code> is true for any - //! <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type. + + //! Type: A type with a constant boolean <code>value</code> == true if + //! `allocator_traits<Allocator>::propagate_on_container_swap::value` is + //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise. typedef typename base_type:: propagate_on_container_swap propagate_on_container_swap; + //! Type: A type with a constant boolean <code>value</code> == true if + //!`allocator_traits<Allocator>::is_always_equal::value` is + //! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise. + typedef typename base_type:: + is_always_equal is_always_equal; + //! Type: Rebinds scoped allocator to //! <code>typedef scoped_allocator_adaptor //! < typename outer_traits_type::template portable_rebind_alloc<U>::type @@ -1124,12 +954,7 @@ class scoped_allocator_adaptor { typedef scoped_allocator_adaptor < typename outer_traits_type::template portable_rebind_alloc<U>::type - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - > other; + , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other; }; //! <b>Effects</b>: value-initializes the OuterAlloc base class @@ -1165,17 +990,14 @@ class scoped_allocator_adaptor {} #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - #define BOOST_PP_LOCAL_MACRO(n) \ - template <class OuterA2> \ - scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc \ - BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \ - : base_type(::boost::forward<OuterA2>(outerAlloc) \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, q) \ - ) \ - {} \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\ + template <class OuterA2>\ + scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\ + : base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\ + {}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE) + #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1183,13 +1005,7 @@ class scoped_allocator_adaptor //! //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other. template <class OuterA2> - scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - > &other) + scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other) : base_type(other.base()) {} @@ -1198,13 +1014,8 @@ class scoped_allocator_adaptor //! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator //! rvalue from other. template <class OuterA2> - scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor<OuterA2 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - > BOOST_RV_REF_END other) + scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor + <OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other) : base_type(::boost::move(other.base())) {} @@ -1212,7 +1023,7 @@ class scoped_allocator_adaptor { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); } scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) - { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(static_cast<base_type&>(other)))); } + { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! <b>Effects</b>: swaps *this with r. @@ -1225,33 +1036,31 @@ class scoped_allocator_adaptor //! <b>Returns</b>: //! <code>static_cast<OuterAlloc&>(*this)</code>. - outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT; + outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW; //! <b>Returns</b>: //! <code>static_cast<const OuterAlloc&>(*this)</code>. - const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT; + const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; //! <b>Returns</b>: //! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner. - inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT; + inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW; //! <b>Returns</b>: //! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner. - inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT; + inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; #endif //BOOST_CONTAINER_DOXYGEN_INVOKED //! <b>Returns</b>: //! <code>allocator_traits<OuterAlloc>::max_size(outer_allocator())</code>. - size_type max_size() const BOOST_CONTAINER_NOEXCEPT - { - return outer_traits_type::max_size(this->outer_allocator()); - } + size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return outer_traits_type::max_size(this->outer_allocator()); } //! <b>Effects</b>: //! calls <code>OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)</code>. template <class T> - void destroy(T* p) BOOST_CONTAINER_NOEXCEPT + void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW { allocator_traits<typename outermost_allocator<OuterAlloc>::type> ::destroy(get_outermost_allocator(this->outer_allocator()), p); @@ -1260,27 +1069,21 @@ class scoped_allocator_adaptor //! <b>Returns</b>: //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>. pointer allocate(size_type n) - { - return outer_traits_type::allocate(this->outer_allocator(), n); - } + { return outer_traits_type::allocate(this->outer_allocator(), n); } //! <b>Returns</b>: //! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>. pointer allocate(size_type n, const_void_pointer hint) - { - return outer_traits_type::allocate(this->outer_allocator(), n, hint); - } + { return outer_traits_type::allocate(this->outer_allocator(), n, hint); } //! <b>Effects</b>: //! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>. void deallocate(pointer p, size_type n) - { - outer_traits_type::deallocate(this->outer_allocator(), p, n); - } + { outer_traits_type::deallocate(this->outer_allocator(), p, n); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED - //! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator - //! A in the adaptor is initialized from the result of calling + //! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator + //! Allocator in the adaptor is initialized from the result of calling //! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on //! the corresponding allocator in *this. scoped_allocator_adaptor select_on_container_copy_construction() const; @@ -1331,7 +1134,7 @@ class scoped_allocator_adaptor construct(T* p, BOOST_FWD_REF(Args)...args) { container_detail::dispatch_uses_allocator - ( uses_allocator<T, inner_allocator_type>() + ( container_detail::bool_<uses_allocator<T, inner_allocator_type>::value>() , get_outermost_allocator(this->outer_allocator()) , this->inner_allocator() , p, ::boost::forward<Args>(args)...); @@ -1341,22 +1144,19 @@ class scoped_allocator_adaptor //Disable this overload if the first argument is pair as some compilers have //overload selection problems when the first parameter is a pair. - #define BOOST_PP_LOCAL_MACRO(n) \ - template < typename T \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \ - > \ - typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type \ - construct(T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { \ - container_detail::dispatch_uses_allocator \ - ( uses_allocator<T, inner_allocator_type>() \ - , get_outermost_allocator(this->outer_allocator()) \ - , this->inner_allocator() \ - , p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - } \ - //! - #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) - #include BOOST_PP_LOCAL_ITERATE() + #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \ + template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type\ + construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + container_detail::dispatch_uses_allocator\ + ( container_detail::bool_<uses_allocator<T, inner_allocator_type>::value>()\ + , get_outermost_allocator(this->outer_allocator())\ + , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1427,31 +1227,11 @@ class scoped_allocator_adaptor template <class Pair, class Pair2> void construct_pair(Pair* p, const Pair2& pr) - { - this->construct(container_detail::addressof(p->first), pr.first); - BOOST_TRY{ - this->construct(container_detail::addressof(p->second), pr.second); - } - BOOST_CATCH(...){ - this->destroy(container_detail::addressof(p->first)); - BOOST_RETHROW - } - BOOST_CATCH_END - } + { this->construct_pair(p, pr.first, pr.second); } template <class Pair, class Pair2> void construct_pair(Pair* p, BOOST_RV_REF(Pair2) pr) - { - this->construct(container_detail::addressof(p->first), ::boost::move(pr.first)); - BOOST_TRY{ - this->construct(container_detail::addressof(p->second), ::boost::move(pr.second)); - } - BOOST_CATCH(...){ - this->destroy(container_detail::addressof(p->first)); - BOOST_RETHROW - } - BOOST_CATCH_END - } + { this->construct_pair(p, ::boost::move(pr.first), ::boost::move(pr.second)); } //template <class T1, class T2, class... Args1, class... Args2> //void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y); @@ -1466,66 +1246,29 @@ class scoped_allocator_adaptor #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; -template <typename OuterA1, typename OuterA2 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename... InnerAllocs - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q) - #endif - > -inline bool operator==( - const scoped_allocator_adaptor<OuterA1 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - ,InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - >& a, - const scoped_allocator_adaptor<OuterA2 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - ,InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - >& b) +template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS> +inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a + ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b) { #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) const bool has_zero_inner = sizeof...(InnerAllocs) == 0u; #else - const bool has_zero_inner = - boost::container::container_detail::is_same - <Q0, container_detail::nat>::value; + const bool has_zero_inner = boost::container::container_detail::is_same<P0, void>::value; #endif - - return a.outer_allocator() == b.outer_allocator() - && (has_zero_inner || a.inner_allocator() == b.inner_allocator()); + typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> + ::outer_allocator_type outer_allocator_type; + typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> + ::inner_allocator_type inner_allocator_type; + + return allocator_traits<outer_allocator_type>::equal(a.outer_allocator(), b.outer_allocator()) + && (has_zero_inner || + allocator_traits<inner_allocator_type>::equal(a.inner_allocator(), b.inner_allocator())); } -template <typename OuterA1, typename OuterA2 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - , typename... InnerAllocs - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q) - #endif - > -inline bool operator!=( - const scoped_allocator_adaptor<OuterA1 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - ,InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - >& a, - const scoped_allocator_adaptor<OuterA2 - #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - ,InnerAllocs... - #else - BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q) - #endif - >& b) -{ - return ! (a == b); -} +template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS> +inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a + ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b) +{ return !(a == b); } }} // namespace boost { namespace container { |