$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77479 - in trunk/boost/container: . detail
From: igaztanaga_at_[hidden]
Date: 2012-03-22 14:46:19
Author: igaztanaga
Date: 2012-03-22 14:46:18 EDT (Thu, 22 Mar 2012)
New Revision: 77479
URL: http://svn.boost.org/trac/boost/changeset/77479
Log:
Experimental scoped_allocator support
Added:
   trunk/boost/container/allocator_traits.hpp   (contents, props changed)
   trunk/boost/container/detail/memory_util.hpp   (contents, props changed)
   trunk/boost/container/scoped_allocator.hpp   (contents, props changed)
Added: trunk/boost/container/allocator_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/container/allocator_traits.hpp	2012-03-22 14:46:18 EDT (Thu, 22 Mar 2012)
@@ -0,0 +1,385 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Pablo Halpern 2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
+#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/detail/memory_util.hpp>
+#include <boost/container/detail/memory_util.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/move/move.hpp>
+#include <limits> //numeric_limits<>::max()
+#include <new>    //placement new
+#include <memory> //std::allocator
+#include <boost/container/detail/preprocessor.hpp>
+
+///@cond
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+//workaround needed for C++03 compilers with no construct()
+//supporting rvalue references
+template<class A>
+struct is_std_allocator
+{  static const bool value = false; };
+
+template<class T>
+struct is_std_allocator< std::allocator<T> >
+{  static const bool value = true; };
+
+}  //namespace container_detail {
+
+///@endcond
+
+//! The class template allocator_traits supplies a uniform interface to all allocator types.
+//! This class is a C++03-compatible implementation of std::allocator_traits
+template <typename Alloc>
+struct allocator_traits
+{
+   //allocator_type
+   typedef Alloc allocator_type;
+   //value_type
+   typedef typename Alloc::value_type         value_type;
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //! Alloc::pointer if such a type exists; otherwise, value_type*
+      //! 
+      typedef unspecified pointer;
+      //! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
+      //! 
+      typedef unspecified const_pointer;
+      //! Non-standard extension
+      //! Alloc::reference if such a type exists; otherwise, value_type&
+      typedef unspecified reference;
+      //! Non-standard extension
+      //! Alloc::const_reference if such a type exists ; otherwise, const value_type&
+      typedef unspecified const_reference;
+      //! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
+      //! 
+      typedef unspecified void_pointer;
+      //! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
+      //! 
+      typedef unspecified const_void_pointer;
+      //! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
+      //! 
+      typedef unspecified difference_type;
+      //! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
+      //! 
+      typedef unspecified size_type;
+      //! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
+      //! type with internal constant static member `value` == false.
+      typedef unspecified propagate_on_container_copy_assignment;
+      //! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
+      //! type with internal constant static member `value` == false.
+      typedef unspecified propagate_on_container_move_assignment;
+      //! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
+      //! type with internal constant static member `value` == false.
+      typedef unspecified propagate_on_container_swap;
+      //! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
+      //! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or 
+      //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
+      //! 
+      //! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
+      //! deduced by previously detailed rules.
+      template <class T> using rebind_alloc = unspecified;
+
+      //! In C++03 compilers `rebind_traits` is a struct derived from
+      //! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
+      //! the allocator deduced by rules explained in `rebind_alloc`.
+      template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
+
+      //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
+      //! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
+      template <class T>
+      struct portable_rebind_alloc
+      {  typedef unspecified_type type;  };
+   #else
+      //pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         pointer, value_type*)
+            pointer;
+      //const_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, 
+         const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
+            rebind_pointer<const value_type>)
+               const_pointer;
+      //reference
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         reference, typename container_detail::unvoid<value_type>::type&)
+            reference;
+      //const_reference
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, 
+         const_reference, const typename container_detail::unvoid<value_type>::type&)
+               const_reference;
+      //void_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, 
+         void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
+            rebind_pointer<void>)
+               void_pointer;
+      //const_void_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
+         const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
+            rebind_pointer<const void>)
+               const_void_pointer;
+      //difference_type
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         difference_type, std::ptrdiff_t)
+            difference_type;
+      //size_type
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         size_type, std::size_t)
+            size_type;
+      //propagate_on_container_copy_assignment
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         propagate_on_container_copy_assignment, boost::false_type)
+            propagate_on_container_copy_assignment;
+      //propagate_on_container_move_assignment
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         propagate_on_container_move_assignment, boost::false_type)
+            propagate_on_container_move_assignment;
+      //propagate_on_container_swap
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         propagate_on_container_swap, boost::false_type)
+            propagate_on_container_swap;
+
+      #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+         //C++11
+         template <typename T> using rebind_alloc  = boost::intrusive::detail::type_rebinder<Alloc, T>::type;
+         template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
+      #else    // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+         //Some workaround for C++03 or C++11 compilers with no template aliases
+         template <typename T>
+         struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type
+         {
+            typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base;
+            #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+            template <typename... Args>
+            rebind_alloc(BOOST_FWD_REF(Args)... args)
+               : Base(boost::forward<Args>(args)...)
+            {}
+            #else    // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+            #define BOOST_PP_LOCAL_MACRO(n)                                                        \
+            BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+            rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                       \
+               : Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                       \
+            {}                                                                                     \
+            //
+            #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+            #include BOOST_PP_LOCAL_ITERATE()
+            #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+         };
+
+         template <typename T>
+         struct rebind_traits
+            : allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type>
+         {};
+      #endif   // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+      template <class T>
+      struct portable_rebind_alloc
+      {  typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type;  };
+   #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //! <b>Returns</b>: `a.allocate(n)`
+   //! 
+   static pointer allocate(Alloc &a, size_type n)
+   {  return a.allocate(n);  }
+
+   //! <b>Returns</b>: `a.deallocate(p, n)`
+   //! 
+   //! <b>Throws</b>: Nothing
+   static void deallocate(Alloc &a, pointer p, size_type n)
+   {  return a.deallocate(p, n);  }
+
+   //! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
+   //! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
+   static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
+   {
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_allocate
+            <Alloc, const size_type, const const_void_pointer>::value;
+      ::boost::integral_constant<bool, value> flag;
+      return allocator_traits::priv_allocate(flag, a, n, p);
+   }
+
+   //! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
+   //! otherwise, invokes `p->~T()`.
+   template<class T>
+   static void destroy(Alloc &a, T*p)
+   {
+      typedef T* destroy_pointer;
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_destroy
+            <Alloc, const destroy_pointer>::value;
+      ::boost::integral_constant<bool, value> flag;
+      allocator_traits::priv_destroy(flag, a, p);
+   }
+
+   //! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise,
+   //! `numeric_limits<size_type>::max()`.
+   static size_type max_size(const Alloc &a)
+   {
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_max_size
+            <const Alloc>::value;
+      ::boost::integral_constant<bool, value> flag;
+      return allocator_traits::priv_max_size(flag, a);
+   }
+
+   //! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
+   //! otherwise, a.
+   static Alloc select_on_container_copy_construction(const Alloc &a)
+   {
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_select_on_container_copy_construction
+            <const Alloc>::value;
+      ::boost::integral_constant<bool, value> flag;
+      return allocator_traits::priv_select_on_container_copy_construction(flag, a);
+   }
+
+   #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed; 
+      //! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
+      template <class T, class ...Args>
+      static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
+      {
+         ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;
+         allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
+      }
+   #endif
+   ///@cond
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      private:
+      static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
+      {  return a.allocate(n, p);  }
+
+      static pointer priv_allocate(boost::false_type, Alloc &a, size_type n, const_void_pointer)
+      {  return allocator_traits::allocate(a, n);  }
+
+      template<class T>
+      static void priv_destroy(boost::true_type, Alloc &a, T* p)
+      {  a.destroy(p);  }
+
+      template<class T>
+      static void priv_destroy(boost::false_type, Alloc &, T* p)
+      {  p->~T(); (void)p;  }
+
+      static size_type priv_max_size(boost::true_type, const Alloc &a)
+      {  return a.max_size();  }
+
+      static size_type priv_max_size(boost::false_type, const Alloc &)
+      {  return (std::numeric_limits<size_type>::max)();  }
+
+      static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
+      {  return a.select_on_container_copy_construction();  }
+
+      static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
+      {  return a;  }
+
+      #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+         template<class T, class ...Args>
+         static void priv_construct(boost::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)                    
+         {                                                                                                  
+            const bool value = boost::container::container_detail::
+                  has_member_function_callable_with_construct
+                     < Alloc, T*, Args... >::value;
+            ::boost::integral_constant<bool, value> flag;
+            priv_construct_dispatch2(flag, a, p, ::boost::forward<Args>(args)...);
+         }
+
+         template<class T, class ...Args>
+         static void priv_construct(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
+         {
+            priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward<Args>(args)...);
+         }
+
+         template<class T, class ...Args>
+         static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
+         {  a.construct( p, ::boost::forward<Args>(args)...);  }
+
+         template<class T, class ...Args>
+         static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
+         {  ::new((void*)p) T(::boost::forward<Args>(args)...); }
+      #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+         public:
+         #define BOOST_PP_LOCAL_MACRO(n)                                                              \
+         template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                 \
+         static void construct(Alloc &a, T *p                                                         \
+                              BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            \
+         {                                                                                            \
+            ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;  \
+            allocator_traits::priv_construct(flag, a, 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()
+      
+         private:
+         #define BOOST_PP_LOCAL_MACRO(n)                                                                    \
+         template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      \
+         static void priv_construct(boost::false_type, Alloc &a, T *p                                       \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         \
+         {                                                                                                  \
+            const bool value =                                                                              \
+               boost::container::container_detail::has_member_function_callable_with_construct              \
+                     < Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value;        \
+            ::boost::integral_constant<bool, value> flag;                                                   \
+            priv_construct_dispatch2(flag, a, p                                                             \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                            \
+         }                                                                                                  \
+                                                                                                            \
+         template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      \
+         static void priv_construct(boost::true_type, Alloc &a, T *p                                        \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         \
+         {                                                                                                  \
+            priv_construct_dispatch2(boost::false_type(), a, p                                              \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                            \
+         }                                                                                                  \
+                                                                                                            \
+         template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      \
+         static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p                              \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         \
+         {  a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );  }             \
+                                                                                                            \
+         template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      \
+         static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p                              \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )                       \
+         {  ::new((void*)p) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }                     \
+         //
+         #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+         #include BOOST_PP_LOCAL_ITERATE()
+      #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   ///@endcond
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
Added: trunk/boost/container/detail/memory_util.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/container/detail/memory_util.hpp	2012-03-22 14:46:18 EDT (Thu, 22 Mar 2012)
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
+#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/preprocessor.hpp>
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME select_on_container_copy_construction
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
+#include BOOST_PP_ITERATE()
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP)
Added: trunk/boost/container/scoped_allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/container/scoped_allocator.hpp	2012-03-22 14:46:18 EDT (Thu, 22 Mar 2012)
@@ -0,0 +1,1452 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Pablo Halpern 2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
+#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
+
+#if (defined MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.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/detail/pair.hpp>
+#include <boost/move/move.hpp>
+
+#if defined(BOOST_NO_VARIADIC_TEMPLATES)
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+namespace boost { namespace container {
+
+#if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
+
+#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+template <typename OuterAlloc, typename ...InnerAllocs>
+class scoped_allocator_adaptor;
+
+#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+template <typename ...InnerAllocs>
+class scoped_allocator_adaptor;
+
+template <typename OuterAlloc, typename ...InnerAllocs>
+class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
+
+#endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+
+#else    // #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template <typename OuterAlloc
+BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
+                      , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
+>
+class scoped_allocator_adaptor;
+
+#endif
+
+//! The allocator_arg_t struct is an empty structure type used as a unique type to
+//! disambiguate constructor and function overloading. Specifically, several types
+//! have constructors with allocator_arg_t as the first argument, immediately followed
+//! by an argument of a type that satisfies the Allocator requirements
+struct allocator_arg_t{};
+
+static const allocator_arg_t allocator_arg = allocator_arg_t();
+
+//! <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. 
+//!
+//! <b>Result</b>: derived from true_type if Convertible<Alloc,T::allocator_type> and 
+//! derived from false_type otherwise. 
+template <class T, class Alloc>
+struct uses_allocator; 
+
+//! <b>Remark</b>: if a specialization is derived from true_type, 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, 
+//! 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 
+//! ill-formed. 
+//!
+//! [Example: 
+//!  template <class T, class A = allocator<T> >   
+//!  class Z { 
+//!    public: 
+//!      typedef A allocator_type; 
+//!
+//!    // Default constructor with optional allocator suffix 
+//!    Z(const allocator_type& a = allocator_type()); 
+//!
+//!    // Copy constructor and allocator-extended copy constructor 
+//!    Z(const Z& zz); 
+//!    Z(const Z& zz, const allocator_type& a); 
+//! }; 
+//!
+//! // Specialize trait for class template Z 
+//! template <class T, class A = allocator<T> > 
+//! struct constructible_with_allocator_suffix<Z<T,A> >  
+//!      : ::boost::true_type { };
+//! -- end example] 
+//!
+//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator 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.
+//!
+//! In conforming C++11 compilers or compilers supporting SFINAE expressions
+//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
+//! 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
+{}; 
+
+//! <b>Remark</b>: if a specialization is derived from true_type, 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, 
+//! 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 
+//! a constructor, then the program is ill-formed.
+//!
+//! [Example: 
+//! template <class T, class A = allocator<T> > 
+//! class Y { 
+//!    public: 
+//!       typedef A allocator_type; 
+//!  
+//!       // Default constructor with and allocator-extended default constructor 
+//!       Y(); 
+//!       Y(allocator_arg_t, const allocator_type& a); 
+//!  
+//!       // Copy constructor and allocator-extended copy constructor 
+//!       Y(const Y& yy); 
+//!       Y(allocator_arg_t, const allocator_type& a, const Y& yy); 
+//!  
+//!       // 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); 
+//! }; 
+//!  
+//! // Specialize trait for class template Y 
+//! template <class T, class A = allocator<T> > 
+//! struct constructible_with_allocator_prefix<Y<T,A> >  
+//!       : ::boost::true_type { }; 
+//!  
+//! -- end example]
+//!
+//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator 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.
+//!
+//! In conforming C++11 compilers or compilers supporting SFINAE expressions
+//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
+//! 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
+{};
+
+///@cond
+
+namespace container_detail {
+
+template<typename T, typename Alloc>
+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.
+
+   private:
+   // 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);
+
+   // Match this function if TypeT::allocator_type does not exist or is
+   // not convertible from Alloc.
+   template <typename U>
+   static int test(LowPriorityConversion<int>, LowPriorityConversion<Alloc>);
+
+   static Alloc alloc;  // Declared but not defined
+
+   public:
+   enum { value = sizeof(test<T>(0, alloc)) == sizeof(char) };
+};
+
+}  //namespace container_detail {
+
+template <typename T, typename Alloc>
+struct uses_allocator
+   : boost::integral_constant<bool, container_detail::uses_allocator_imp<T, Alloc>::value>
+{};
+
+namespace container_detail {
+
+template <typename Alloc>
+struct is_scoped_allocator_imp
+{
+   template <typename T>
+   static char test(int, typename T::outer_allocator_type*);
+
+   template <typename T>
+   static int test(LowPriorityConversion<int>, void*);
+
+   static const bool value = (sizeof(char) == sizeof(test<Alloc>(0, 0)));
+};
+
+template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
+struct outermost_allocator_type_impl
+{
+   typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
+   typedef typename outermost_allocator_type_impl<outer_type>::type type;
+};
+
+template<class MaybeScopedAlloc>
+struct outermost_allocator_type_impl<MaybeScopedAlloc, false>
+{
+   typedef MaybeScopedAlloc type;
+};
+
+template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
+struct outermost_allocator_imp
+{
+   typedef MaybeScopedAlloc type;
+
+   static type &get(MaybeScopedAlloc &a)
+   {  return a;  }
+
+   static const type &get(const MaybeScopedAlloc &a)
+   {  return a;  }
+};
+
+template<class MaybeScopedAlloc>
+struct outermost_allocator_imp<MaybeScopedAlloc, true>
+{
+   typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
+   typedef typename outermost_allocator_type_impl<outer_type>::type type;
+
+   static type &get(MaybeScopedAlloc &a)
+   {  return outermost_allocator_imp<outer_type>::get(a.outer_allocator());  }
+
+   static const type &get(const MaybeScopedAlloc &a)
+   {  return outermost_allocator_imp<outer_type>::get(a.outer_allocator());  }
+};
+
+}  //namespace container_detail {
+
+template <typename Alloc>
+struct is_scoped_allocator
+   : boost::integral_constant<bool, container_detail::is_scoped_allocator_imp<Alloc>::value>
+{};
+
+template <typename Alloc>
+struct outermost_allocator
+   : container_detail::outermost_allocator_imp<Alloc>
+{};
+
+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 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);   }
+
+namespace container_detail {
+
+// Check if we can detect is_convertible using advanced SFINAE expressions
+#if !defined(BOOST_NO_SFINAE_EXPR)
+
+   #define BOOST_CONTAINER_IS_CONSTRUCTIBLE_AVAILABLE
+
+   //! 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_VARIADIC_TEMPLATES)
+
+   template<class T, class ...Args>
+   struct is_constructible_impl
+   {
+      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::move_detail::declval<Args>()...))>*);
+
+      template<class X>
+      static no_type test(...);
+
+      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_VARIADIC_TEMPLATES)
+
+   //Without variadic templates, we need to use de 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_VARIADIC_TEMPLATES)
+
+#else    // #if !defined(BOOST_NO_SFINAE_EXPR)
+
+   //Without advanced SFINAE expressions, we can't use is_constructible
+   //so backup to constructible_with_allocator_xxx
+
+   #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+   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>
+   struct is_constructible_with_allocator_suffix
+      : constructible_with_allocator_suffix<T>
+   {};*/
+
+   #else    // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+   template < class T 
+            , class InnerAlloc
+            BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
+                                  , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
+                                  , void)
+            >
+   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)
+            >
+   struct is_constructible_with_allocator_suffix
+      : constructible_with_allocator_suffix<T>
+   {};*/
+
+   #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+#endif   // #if !defined(BOOST_NO_SFINAE_EXPR)
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template < typename OutermostAlloc
+         , typename InnerAlloc
+         , typename T
+         , class ...Args
+         >
+inline void dispatch_allocator_prefix_suffix
+   ( boost::true_type  use_alloc_prefix, OutermostAlloc& outermost_alloc
+   , InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args) ...args)
+{
+   (void)use_alloc_prefix;
+   allocator_traits<OutermostAlloc>::construct
+      ( outermost_alloc, p, allocator_arg, inner_alloc, ::boost::forward<Args>(args)...);
+}
+
+template < typename OutermostAlloc
+         , typename InnerAlloc
+         , typename T
+         , class ...Args
+         >
+inline void dispatch_allocator_prefix_suffix
+   ( boost::false_type use_alloc_prefix, OutermostAlloc& outermost_alloc
+   , InnerAlloc &inner_alloc, T* p, BOOST_FWD_REF(Args)...args)
+{
+   (void)use_alloc_prefix;
+   allocator_traits<OutermostAlloc>::construct
+      (outermost_alloc, p, ::boost::forward<Args>(args)..., inner_alloc);
+}
+
+template < typename OutermostAlloc
+         , typename InnerAlloc
+         , typename T
+         , class ...Args
+         >
+inline void dispatch_uses_allocator
+   ( boost::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...>()
+      , outermost_alloc, inner_alloc, p, ::boost::forward<Args>(args)...);
+}
+
+template < typename OutermostAlloc
+         , typename InnerAlloc
+         , typename T
+         , class ...Args
+         >
+inline void dispatch_uses_allocator
+   ( boost::false_type uses_allocator, OutermostAlloc & outermost_alloc
+   , InnerAlloc & inner_alloc
+   ,T* p, BOOST_FWD_REF(Args)...args)
+{
+   (void)uses_allocator; (void)inner_alloc;
+   allocator_traits<OutermostAlloc>::construct
+      (outermost_alloc, p, ::boost::forward<Args>(args)...);
+}
+
+#else    //#if !defined(BOOST_NO_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()
+
+#endif   //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template <typename OuterAlloc, class ...InnerAllocs>
+class scoped_allocator_adaptor_base
+   : 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, InnerAllocs...> other;
+   };
+
+   typedef OuterAlloc outer_allocator_type;
+   typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_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, const InnerAllocs &...args)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      , inner(args...)
+      {}
+
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
+      : outer_allocator_type(other.outer_allocator())
+      , inner(other.inner_allocator())
+      {}
+
+   scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
+      : outer_allocator_type(::boost::move(other.outer_allocator()))
+      , inner(::boost::move(other.inner_allocator()))
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
+      : outer_allocator_type(other.outer_allocator())
+      , inner(other.inner_allocator())
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (BOOST_RV_REF_BEG scoped_allocator_adaptor_base
+         <OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
+      : outer_allocator_type(other.outer_allocator())
+      , inner(other.inner_allocator())
+      {}
+
+   scoped_allocator_adaptor_base &operator=
+      (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
+   {
+      outer_allocator_type::operator=(other.outer_allocator());
+      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()));
+      inner = ::boost::move(other.inner_allocator());
+      return *this;
+   }
+
+   inner_allocator_type&       inner_allocator()
+      { return inner; }
+
+   inner_allocator_type const& inner_allocator() const
+      { return 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); }
+
+   private:
+   inner_allocator_type inner;
+};
+
+#else //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+//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)
+   >
+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 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))                             \
+      , inner(BOOST_PP_ENUM_PARAMS(n, q))                                                       \
+      {}                                                                                        \
+                                                                                                \
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)                    \
+      : outer_allocator_type(other.outer_allocator())                                           \
+      , inner(other.inner_allocator())                                                          \
+      {}                                                                                        \
+                                                                                                \
+   scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)             \
+      : outer_allocator_type(::boost::move(other.outer_allocator()))                            \
+      , 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())                                           \
+      , 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())                                           \
+      , inner(other.inner_allocator())                                                          \
+      {}                                                                                        \
+                                                                                                \
+   scoped_allocator_adaptor_base &operator=                                                     \
+      (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)                              \
+   {                                                                                            \
+      outer_allocator_type::operator=(other.outer_allocator());                                 \
+      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()));                    \
+      inner = ::boost::move(other.inner_allocator());                                           \
+      return *this;                                                                             \
+   }                                                                                            \
+                                                                                                \
+   inner_allocator_type&       inner_allocator()                                                \
+      { return inner; }                                                                         \
+                                                                                                \
+   inner_allocator_type const& inner_allocator() const                                          \
+      { return 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); }                               \
+                                                                                                \
+   private:                                                                                     \
+   inner_allocator_type inner;                                                                  \
+};                                                                                              \
+//!
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#endif   //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+//Specialization for adaptor without any InnerAlloc
+template <typename OuterAlloc>
+class scoped_allocator_adaptor_base
+   < OuterAlloc
+   #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+      , true
+      BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, nat)
+   #endif
+   >
+   : public OuterAlloc
+{
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
+   public:
+
+   template <class U>
+   struct rebind_base
+   {
+      typedef scoped_allocator_adaptor_base
+         <typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
+         #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+         , true
+         BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
+         #endif
+         > other;
+   };
+
+   typedef OuterAlloc                           outer_allocator_type;
+   typedef allocator_traits<OuterAlloc>         outer_traits_type;
+   typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
+   typedef typename outer_traits_type::
+      propagate_on_container_copy_assignment    propagate_on_container_copy_assignment;
+   typedef typename outer_traits_type::
+      propagate_on_container_move_assignment    propagate_on_container_move_assignment;
+   typedef typename outer_traits_type::
+      propagate_on_container_swap               propagate_on_container_swap;
+
+   scoped_allocator_adaptor_base()
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      {}
+
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
+      : outer_allocator_type(other.outer_allocator())
+      {}
+
+   scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
+      : outer_allocator_type(::boost::move(other.outer_allocator()))
+      {}
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      (const scoped_allocator_adaptor_base<
+         OuterA2
+         #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+         , true
+         BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
+         #endif
+         >& 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_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)
+      : outer_allocator_type(other.outer_allocator())
+      {}
+
+   scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
+   {
+      outer_allocator_type::operator=(other.outer_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()));
+      return *this;
+   }
+
+   inner_allocator_type&       inner_allocator()
+      { return static_cast<inner_allocator_type&>(*this); }
+
+   inner_allocator_type const& inner_allocator() const
+      { return static_cast<const inner_allocator_type&>(*this); }
+
+   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); }
+};
+
+}  //namespace container_detail {
+
+///@endcond
+
+//Scoped allocator
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #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. [Note: 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, `OUTERMOST(x)` is x if x does not have 
+   //! an `outer_allocator()` member function and
+   //! `OUTERMOST(x.outer_allocator())` otherwise; `OUTERMOST_ALLOC_TRAITS(x)` is
+   //! `allocator_traits<decltype(OUTERMOST(x))>`. [Note: `OUTERMOST(x)` and
+   //! `OUTERMOST_ALLOC_TRAITS(x)` are recursive operations. It is incumbent upon 
+   //! the definition of `outer_allocator()` 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)
+
+   template <typename OuterAlloc, typename ...InnerAllocs>
+   class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
+
+   #endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template <typename OuterAlloc
+         BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
+         >
+class scoped_allocator_adaptor
+#endif
+   : public container_detail::scoped_allocator_adaptor_base
+         <OuterAlloc
+         #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+         , InnerAllocs...
+         #else
+         , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
+         #endif
+         >
+{
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
+
+   public:
+   /// @cond
+   typedef container_detail::scoped_allocator_adaptor_base
+      <OuterAlloc
+      #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , InnerAllocs...
+      #else
+      , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
+      #endif
+      >                       base_type;
+   /// @endcond
+   typedef OuterAlloc                                       outer_allocator_type;
+   //! Type: For exposition only
+   //!
+   typedef allocator_traits<OuterAlloc>                     outer_traits_type;
+   //! Type: `scoped_allocator_adaptor<OuterAlloc>` if `sizeof...(InnerAllocs)` is zero; otherwise,
+   //! `scoped_allocator_adaptor<InnerAllocs...>`.
+   typedef typename base_type::inner_allocator_type         inner_allocator_type;
+   typedef typename outer_traits_type::value_type           value_type;
+   typedef typename outer_traits_type::size_type            size_type;
+   typedef typename outer_traits_type::difference_type      difference_type;
+   typedef typename outer_traits_type::pointer              pointer;
+   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: `true_type` if `allocator_traits<A>::propagate_on_container_copy_assignment::value` is
+   //! true for any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
+   typedef typename base_type::
+      propagate_on_container_copy_assignment                propagate_on_container_copy_assignment;
+   //! Type: `true_type` if `allocator_traits<A>::propagate_on_container_move_assignment::value` is
+   //! true for any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
+   typedef typename base_type::
+      propagate_on_container_move_assignment                propagate_on_container_move_assignment;
+   //! Type: `true_type` if `allocator_traits<A>::propagate_on_container_swap::value` is true for any
+   //! `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
+   typedef typename base_type::
+      propagate_on_container_swap                           propagate_on_container_swap;
+
+   //! Type: Rebinds scoped allocator to
+   //!    `typedef scoped_allocator_adaptor
+   //!      < typename outer_traits_type::template portable_rebind_alloc<U>::type
+   //!      , InnerAllocs... >`
+   template <class U>
+   struct rebind
+   {
+      typedef scoped_allocator_adaptor
+         < typename outer_traits_type::template portable_rebind_alloc<U>::type
+         #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+         , InnerAllocs...
+         #else
+         BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
+         #endif
+         > other;
+   };
+
+   //! Effects: value-initializes the OuterAlloc base class
+   //! and the inner allocator object.
+   scoped_allocator_adaptor()
+      {}
+
+   ~scoped_allocator_adaptor()
+      {}
+
+   //! Effects: initializes each allocator within the adaptor with
+   //! the corresponding allocator from other.
+   scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
+      : base_type(other.base())
+      {}
+
+   //! Effects: move constructs each allocator within the adaptor with 
+   //! the corresponding allocator from other.
+   scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
+      : base_type(::boost::move(other.base()))
+      {}
+
+   #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Requires: OuterAlloc shall be constructible from OuterA2.
+   //! Effects: initializes the OuterAlloc base class with boost::forward<OuterA2>(outerAlloc) and inner
+   //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the 
+   //! corresponding allocator from the argument list).
+   template <class OuterA2>
+   scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
+      : base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
+      {}
+   #else // #if !defined(BOOST_NO_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()
+
+   #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Requires: OuterAlloc shall be constructible from OuterA2.
+   //! Effects: 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_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      , InnerAllocs...
+      #else
+      BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
+      #endif
+      > &other)
+      : base_type(other.base())
+      {}
+
+   //! Requires: OuterAlloc shall be constructible from OuterA2.
+   //! Effects: 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_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)
+      : base_type(::boost::move(other.base()))
+      {}
+
+   scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
+   {
+      base_type::operator=(static_cast<const base_type &>(other));
+      return *this;
+   }
+
+   scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
+   {
+      base_type::operator=(boost::move(static_cast<scoped_allocator_adaptor&>(other)));
+      return *this;
+   }
+
+   //! Returns:
+   //!   static_cast<OuterAlloc&>(*this).
+   outer_allocator_type      & outer_allocator()
+      {  return *this; }
+
+   //! Returns:
+   //!   static_cast<const OuterAlloc&>(*this).
+   const outer_allocator_type &outer_allocator() const
+      {  return *this; }
+
+   //! Returns:
+   //!   *this if sizeof...(InnerAllocs) is zero; otherwise, inner.
+   inner_allocator_type&       inner_allocator()
+      {  return base_type::inner_allocator(); }
+
+   //! Returns:
+   //!   *this if sizeof...(InnerAllocs) is zero; otherwise, inner.
+   inner_allocator_type const& inner_allocator() const
+      {  return base_type::inner_allocator(); }
+
+   //! Returns:
+   //!   allocator_traits<OuterAlloc>::max_size(outer_allocator()).
+   size_type max_size() const
+   {
+      return outer_traits_type::max_size(this->outer_allocator());
+   }
+
+   //! Effects: 
+   //!   calls OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p).
+   template <class T>
+   void destroy(T* p)
+   {
+      allocator_traits<typename outermost_allocator<OuterAlloc>::type>
+         ::destroy(get_outermost_allocator(this->outer_allocator()), p);
+   }
+
+   //! Returns: 
+   //! allocator_traits<OuterAlloc>::allocate(outer_allocator(), n).
+   pointer allocate(size_type n)
+   {
+      return outer_traits_type::allocate(this->outer_allocator(), n);
+   }
+
+   //! Returns: 
+   //! allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint).
+   pointer allocate(size_type n, const_void_pointer hint)
+   {
+      return outer_traits_type::allocate(this->outer_allocator(), n, hint);
+   }
+
+   //! Effects:
+   //! allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n);
+   void deallocate(pointer p, size_type n)
+   {
+      outer_traits_type::deallocate(this->outer_allocator(), p, n);
+   }
+
+   //! Returns: A new scoped_allocator_adaptor object where each allocator
+   //! A in the adaptor is initialized from the result of calling 
+   //! allocator_traits<A>::select_on_container_copy_construction() on
+   //! the corresponding allocator in *this.
+   scoped_allocator_adaptor select_on_container_copy_construction() const
+   {
+      return scoped_allocator_adaptor
+         (outer_traits_type::select_on_container_copy_construction(this->outer_allocator()),
+          outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
+         );
+   }
+   /// @cond
+   base_type &base()             { return *this; }
+
+   const base_type &base() const { return *this; }
+   /// @endcond
+
+   #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects:
+   //! 1) If uses_allocator<T, inner_allocator_type>::value is false calls
+   //!    OUTERMOST_ALLOC_TRAITS(*this)::construct
+   //!       (OUTERMOST(*this), p, std::forward<Args>(args)...).
+   //! 
+   //! 2) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and 
+   //!    is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value is true, calls
+   //!    OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
+   //! inner_allocator(), std::forward<Args>(args)...).
+   //! 
+   //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't be,
+   //! implemented so that condition will be replaced by
+   //! constructible_with_allocator_prefix<T>::value. -end note]
+   //!
+   //! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and 
+   //!    is_constructible<T, Args..., inner_allocator_type>::value is true, calls 
+   //!    OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, 
+   //!    std::forward<Args>(args)..., inner_allocator()).
+   //! 
+   //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't be,
+   //! implemented so that condition will be replaced by
+   //! constructible_with_allocator_suffix<T>::value. -end note]
+   //!
+   //! 4) Otherwise, the program is ill-formed. [Note: An error will result if uses_allocator evaluates
+   //! to true but the specific constructor does not take an allocator. This definition prevents a silent
+   //! failure to pass an inner allocator to a contained element. -end note]
+   template < typename T, class ...Args>
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   void
+   #else
+   typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type
+   #endif
+   construct(T* p, BOOST_FWD_REF(Args)...args)
+   {
+      container_detail::dispatch_uses_allocator
+         ( uses_allocator<T, inner_allocator_type>()
+         , get_outermost_allocator(this->outer_allocator())
+         , this->inner_allocator()
+         , p, ::boost::forward<Args>(args)...);
+   }
+
+   #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //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()
+
+   #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   template <class T1, class T2>
+   void construct(std::pair<T1,T2>* p)
+   {  this->construct_pair(p);  }
+
+   template <class T1, class T2>
+   void construct(container_detail::pair<T1,T2>* p)
+   {  this->construct_pair(p);  }
+
+   template <class T1, class T2, class U, class V>
+   void construct(std::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+   {  this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<U>(y));   }
+
+   template <class T1, class T2, class U, class V>
+   void construct(container_detail::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+   {  this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<U>(y));   }
+   
+   template <class T1, class T2, class U, class V>
+   void construct(std::pair<T1, T2>* p, const std::pair<U, V>& x)
+   {  this->construct_pair(p, x);   }
+
+   template <class T1, class T2, class U, class V>
+   void construct( container_detail::pair<T1, T2>* p
+                 , const container_detail::pair<U, V>& x)
+   {  this->construct_pair(p, x);   }
+   
+   template <class T1, class T2, class U, class V>
+   void construct( std::pair<T1, T2>* p
+                 , BOOST_RV_REF_BEG std::pair<U, V> BOOST_RV_REF_END x)
+   {  this->construct_pair(p, x);   }
+
+   template <class T1, class T2, class U, class V>
+   void construct( container_detail::pair<T1, T2>* p
+                 , BOOST_RV_REF_BEG container_detail::pair<U, V> BOOST_RV_REF_END x)
+   {  this->construct_pair(p, x);   }
+
+   /// @cond
+   private:
+   template <class Pair>
+   void construct_pair(Pair* p)
+   {
+      this->construct(container_detail::addressof(p->first));
+      try {
+         this->construct(container_detail::addressof(p->second));
+      }
+      catch (...) {
+         this->destroy(container_detail::addressof(p->first));
+         throw;
+      }
+   }
+
+   template <class Pair, class U, class V>
+   void construct_pair(Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+   {
+      this->construct(container_detail::addressof(p->first), ::boost::forward<U>(x));
+      try {
+         this->construct(container_detail::addressof(p->second), ::boost::forward<V>(y));
+      }
+      catch (...) {
+         this->destroy(container_detail::addressof(p->first));
+         throw;
+      }
+   }
+
+   template <class Pair, class Pair2>
+   void construct_pair(Pair* p, const Pair2& pr)
+   {
+      this->construct(container_detail::addressof(p->first), pr.first);
+      try {
+         this->construct(container_detail::addressof(p->second), pr.second);
+      }
+      catch (...) {
+         this->destroy(container_detail::addressof(p->first));
+         throw;
+      }
+   }
+
+   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));
+      try {
+         this->construct(container_detail::addressof(p->second), ::boost::move(pr.second));
+      }
+      catch (...) {
+         this->destroy(container_detail::addressof(p->first));
+         throw;
+      }
+   }
+
+   //template <class T1, class T2, class... Args1, class... Args2>
+   //void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
+
+   /// @endcond
+};
+
+template <typename OuterA1, typename OuterA2
+   #if !defined(BOOST_NO_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_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_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      ,InnerAllocs...
+      #else
+      BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
+      #endif
+   >& b)
+{
+   #if !defined(BOOST_NO_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;
+   #endif
+
+    return a.outer_allocator() == b.outer_allocator()
+        && (has_zero_inner || a.inner_allocator() == b.inner_allocator());
+}
+
+template <typename OuterA1, typename OuterA2
+   #if !defined(BOOST_NO_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_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_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);
+}
+
+}} // namespace boost { namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //  BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP