diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 4ddc031..8e4eb2b 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost.Container library documentation Jamfile --------------------------------- # -# Copyright Ion Gaztanaga 2009-2011. Use, modification and +# Copyright Ion Gaztanaga 2009-2012. Use, modification and # distribution is subject to 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) @@ -27,6 +27,8 @@ doxygen autodoc "PREDEFINED=\"insert_const_ref_type= const T&\" \\ \"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\ \"BOOST_RV_REF(T)=T &&\" \\ + \"BOOST_RV_REF_BEG=\" \\ + \"BOOST_RV_REF_END=&&\" \\ \"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\ \"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T &&\" \\ \"BOOST_RV_REF_3_TEMPL_ARGS(T,a,b,c)=TT &&\" \\ diff --git a/doc/container.qbk b/doc/container.qbk index 13d34ac..c446e60 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1,5 +1,5 @@ [/ - / Copyright (c) 2009-2011 Ion Gazta\u00F1aga + / Copyright (c) 2009-2012 Ion Gazta\u00F1aga / / 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) @@ -8,7 +8,7 @@ [library Boost.Container [quickbook 1.5] [authors [Gaztanaga, Ion]] - [copyright 2009-2011 Ion Gaztanaga] + [copyright 2009-2012 Ion Gaztanaga] [id container] [dirname container] [purpose Containers library] @@ -37,9 +37,9 @@ In short, what does [*Boost.Container] offer? (they can be safely placed in shared memory). * The library offers new useful containers: * [classref boost::container::flat_map flat_map], - [classref boost::container::flat_map flat_set], - [classref boost::container::flat_map flat_multiset] and - [classref boost::container::flat_map flat_multiset]: drop-in + [classref boost::container::flat_set flat_set], + [classref boost::container::flat_multiset flat_multiset] and + [classref boost::container::flat_multiset flat_multiset]: drop-in replacements for standard associative containers but more memory friendly and with faster searches. * [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid @@ -378,7 +378,7 @@ adequate for your needs, and that you often need to use insert and erase in the should probably use list instead of slist.]] [*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement -insertion and implements it a bit differently for the standard C++11 `forward_list`. `forward_list` has no `size()` +insertion and implements it a bit differently than the standard C++ `forward_list`. `forward_list` has no `size()` method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size with every insertion/erasure, allowing constant-time `splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers @@ -422,10 +422,9 @@ to suppose two allocators of the same type always compare equal (that means that by one allocator object could be deallocated by another instance of the same type) and allocators were not swapped when the container was swapped. -C++11 further improves stateful allocator support through the -[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf -Scoped Allocators model]. [@http://en.cppreference.com/w/cpp/memory/allocator_traits -`std::allocator_traits`] is the protocol between a container and an allocator, and +C++11 further improves stateful allocator support through +[@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`]. +`std::allocator_traits` is the protocol between a container and an allocator, and an allocator writer can customize its behaviour (should the container propagate it in move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container] not only supports this model with C++11 but also [*backports it to C++03]. @@ -437,6 +436,36 @@ not constructed on the fly when auxiliary memory is needed). [endsect] +[section:scoped_allocator Scoped allocators] + +C++11 improves stateful allocators with the introduction of +[@http://http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor `std::scoped_allocator_adaptor`] +class template. `scoped_allocator_adaptor` is instantiated with one outer allocator and zero or more inner +allocators. + +A scoped allocator is a mechanism to automatically propagate the state of the allocator to the subobjects +of a container in a controlled way. 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. + +[*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also +to C++03 compilers]. Due to C++03 limitations, in those compilers +the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions +will be based on traits([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix] +and [classref boost::container::constructible_with_allocator_prefix constructible_with_allocator_prefix]) +proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf +N2554: The Scoped Allocator Model (Rev 2) proposal]. In conforming C++11 compilers or compilers supporting SFINAE +expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules +(`is_constructible::value` and +`is_constructible::value`) +will be used to detect if the allocator must be propagated with suffix or prefix allocator arguments. + +[endsect] + [section:initializer_lists Initializer lists] [*Boost.Container] does not support initializer lists when constructing or assigning containers @@ -585,6 +614,21 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes Release Notes] +[section:release_notes_boost_1_50_00 Boost 1.50 Release] + +* Added Scoped Allocator Model support. + +* Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/6566 #6566], + [@https://svn.boost.org/trac/boost/ticket/6575 #6575], + [@https://svn.boost.org/trac/boost/ticket/6606 #6606], + [@https://svn.boost.org/trac/boost/ticket/6615 #6615], + [@https://svn.boost.org/trac/boost/ticket/6533 #6533], + [@https://svn.boost.org/trac/boost/ticket/6536 #6536], + +[endsect] + + [section:release_notes_boost_1_49_00 Boost 1.49 Release] * Fixed bugs diff --git a/example/doc_emplace.cpp b/example/doc_emplace.cpp index 68e4a66..d494061 100644 --- a/example/doc_emplace.cpp +++ b/example/doc_emplace.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-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) // diff --git a/example/doc_move_containers.cpp b/example/doc_move_containers.cpp index 02e037c..c0fa618 100644 --- a/example/doc_move_containers.cpp +++ b/example/doc_move_containers.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-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) // diff --git a/example/doc_recursive_containers.cpp b/example/doc_recursive_containers.cpp index b184d19..e9e67d5 100644 --- a/example/doc_recursive_containers.cpp +++ b/example/doc_recursive_containers.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-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) // diff --git a/example/doc_type_erasure.cpp b/example/doc_type_erasure.cpp index 04dca80..73c81f1 100644 --- a/example/doc_type_erasure.cpp +++ b/example/doc_type_erasure.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-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) // diff --git a/include/boost/container/allocator/scoped_allocator.hpp b/include/boost/container/allocator/scoped_allocator.hpp deleted file mode 100644 index 03e12d1..0000000 --- a/include/boost/container/allocator/scoped_allocator.hpp +++ /dev/null @@ -1,651 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (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-2011. 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 -#include -#include -#include -#include - -namespace boost { namespace container { - -template -class scoped_allocator_adaptor; - -template -scoped_allocator_adaptor make_scoped(); - -template -class scoped_allocator_adaptor_base : public OuterAlloc -{ - typedef allocator_traits OuterTraits; - -public: - // Workaround for inability of gcc-4.4.1 to expand InnerAllocs... -// typedef scoped_allocator_adaptor inner_allocator_type; - typedef decltype(make_scoped()) inner_allocator_type; - - scoped_allocator_adaptor_base(); - - template - scoped_allocator_adaptor_base(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs); - - template - scoped_allocator_adaptor_base(const scoped_allocator_adaptor& other); - template - scoped_allocator_adaptor_base(scoped_allocator_adaptor&& other); - - inner_allocator_type& inner_allocator() - { return _M_inner_allocs; } - inner_allocator_type const& inner_allocator() const - { return _M_inner_allocs; } - - // Allocator propagation functions. - scoped_allocator_adaptor - select_on_container_copy_construction() const; - - typedef std::integral_constant< - bool, - OuterTraits::propagate_on_container_copy_assignment::value || - inner_allocator_type::propagate_on_container_copy_assignment::value - > propagate_on_container_copy_assignment; - typedef std::integral_constant< - bool, - OuterTraits::propagate_on_container_move_assignment::value || - inner_allocator_type::propagate_on_container_move_assignment::value - > propagate_on_container_move_assignment; - typedef std::integral_constant< - bool, - OuterTraits::propagate_on_container_swap::value || - inner_allocator_type::propagate_on_container_swap::value - > propagate_on_container_swap; - -private: - inner_allocator_type _M_inner_allocs; -}; - -// Specialization with only one parameter. -template -class scoped_allocator_adaptor_base : public OuterAlloc -{ - typedef allocator_traits OuterTraits; -public: - typedef scoped_allocator_adaptor inner_allocator_type; - - scoped_allocator_adaptor_base(); - - template - scoped_allocator_adaptor_base(OuterA2&& outerAlloc); - - template - scoped_allocator_adaptor_base(const scoped_allocator_adaptor& other); - template - scoped_allocator_adaptor_base(scoped_allocator_adaptor&& other); - - inner_allocator_type& inner_allocator() - { return static_cast(*this); } - - inner_allocator_type const& inner_allocator() const - { return static_cast(*this); } - - // Allocator propagation functions. - scoped_allocator_adaptor - select_on_container_copy_construction() const; - - typedef typename OuterTraits::propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - typedef typename OuterTraits::propagate_on_container_move_assignment propagate_on_container_move_assignment; - typedef typename OuterTraits::propagate_on_container_swap propagate_on_container_swap; -}; - -template -class scoped_allocator_adaptor - : public scoped_allocator_adaptor_base -{ - typedef scoped_allocator_adaptor_base _Base; - typedef allocator_traits _Traits; - -public: - typedef OuterAlloc outer_allocator_type; - typedef typename _Base::inner_allocator_type inner_allocator_type; - - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename allocator_traits::void_pointer void_pointer; - typedef typename allocator_traits::const_void_pointer const_void_pointer; - typedef typename allocator_traits::value_type value_type; - - template - struct rebind { - typedef typename allocator_traits::template rebind_traits rebound_traits; - typedef typename rebound_traits::allocator_type rebound_outer; // exposition only - typedef scoped_allocator_adaptor other; - }; - - scoped_allocator_adaptor(); - scoped_allocator_adaptor(const scoped_allocator_adaptor& other); - - template - scoped_allocator_adaptor(const scoped_allocator_adaptor& other); - template - scoped_allocator_adaptor(scoped_allocator_adaptor&& other); - - template - scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs); - - ~scoped_allocator_adaptor(); - - inner_allocator_type & inner_allocator() - { return _Base::inner_allocator(); } - inner_allocator_type const& inner_allocator() const - { return _Base::inner_allocator(); } - outer_allocator_type & outer_allocator() - { return *this; } - outer_allocator_type const& outer_allocator() const - { return *this; } - - pointer allocate(size_type n); - pointer allocate(size_type n, const_void_pointer hint); - void deallocate(pointer p, size_type n); - size_type max_size() const; - - template - void construct(T* p, Args&&... args); - - // Specializations to pass inner_allocator to pair::first and pair::second - template - void construct(std::pair* p); - template - void construct(std::pair* p, U&& x, V&& y); - template - void construct(std::pair* p, const std::pair& pr); - template - void construct(std::pair* p, std::pair&& pr); - - template - void destroy(T* p); -}; - -template -inline -bool operator==(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b); - -template -inline -bool operator!=(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b); - -/////////////////////////////////////////////////////////////////////////////// -// Implementation of scoped_allocator_adaptor_base -/////////////////////////////////////////////////////////////////////////////// - -template -inline -scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base() -{ -} - -template - template - scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base(OuterA2&& outerAlloc, - const InnerAllocs&... innerAllocs) - : OuterAlloc(std::forward(outerAlloc)) - , _M_inner_allocs(innerAllocs...) -{ -} - -template - template - scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base( - const scoped_allocator_adaptor& other) - : OuterAlloc(other.outer_allocator()) - , _M_inner_allocs(other.inner_allocator()) -{ -} - -template - template - scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base( - scoped_allocator_adaptor&& other) - : OuterAlloc(std::move(other.outer_allocator())) - , _M_inner_allocs(std::move(other.inner_allocator())) -{ -} - -template -inline -scoped_allocator_adaptor -scoped_allocator_adaptor_base:: - select_on_container_copy_construction() const -{ - return scoped_allocator_adaptor( - allocator_traits::select_on_container_copy_construction( - this->outer_allocator()), - allocator_traits::select_on_container_copy_construction( - this->inner_allocator())); -} - -/////////////////////////////////////////////////////////////////////////////// -// Implementation of scoped_allocator_adaptor_base specialization -/////////////////////////////////////////////////////////////////////////////// - -template -inline -scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base() -{ -} - -template - template - scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base(OuterA2&& outerAlloc) - : OuterAlloc(std::forward(outerAlloc)) -{ -} - -template - template - scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base( - const scoped_allocator_adaptor& other) - : OuterAlloc(other.outer_allocator()) -{ -} - -template - template - scoped_allocator_adaptor_base:: - scoped_allocator_adaptor_base( - scoped_allocator_adaptor&& other) - : OuterAlloc(std::move(other.outer_allocator())) -{ -} - -// template -// inline -// scoped_allocator_adaptor& -// scoped_allocator_adaptor_base::inner_allocator() -// { -// return *this; -// } - -// template -// inline -// scoped_allocator_adaptor const& -// scoped_allocator_adaptor_base::inner_allocator() cosnt -// { -// return *this; -// } - -template -inline -scoped_allocator_adaptor -scoped_allocator_adaptor_base:: -select_on_container_copy_construction() const -{ - return - allocator_traits::select_on_container_copy_construction( - this->outer_allocator()); -} - -/////////////////////////////////////////////////////////////////////////////// -// Implementation of scoped_allocator_adaptor details -/////////////////////////////////////////////////////////////////////////////// - -namespace __details { - - // Overload resolution for __has_ctor resolves to this function - // when _Tp is constructible with _Args. Returns true_type(). - - static void* __void_p; // Declared but not defined - - template - inline - auto __has_ctor(int, _Args&&... __args) -> - decltype((new (__void_p) _Tp(__args...), std::true_type())) - { return std::true_type(); } - - // Overload resolution for __has_ctor resolves to this function - // when _Tp is not constructible with _Args. Returns false_type(). - template - auto __has_ctor(_LowPriorityConversion, _Args&&...) -> - std::false_type - { return std::false_type(); } - - template - struct __is_scoped_allocator_imp { - template - static char test(int, typename T::outer_allocator_type*); - template - static int test(_LowPriorityConversion, void*); - static const bool value = (1 == sizeof(test<_Alloc>(0, 0))); - }; - - template - struct __is_scoped_allocator - : std::integral_constant::value> - { - }; - -#if 0 - // Called when outer_allocator_type is not a scoped allocator - // (recursion stop). - template - inline - auto __outermost_alloc(_LowPriorityConversion, _Alloc& __a) -> - _Alloc& - { - return __a; - } - - // Called when outer_allocator_type is a scoped allocator to - // return the outermost allocator type. - template - inline auto __outermost_alloc(int, _Alloc& __a) -> - decltype(__outermost_alloc(0,__a.outer_allocator())) - { - return __a.outer_allocator(); - } -#endif - - template - inline void __dispatch_scoped_construct(std::false_type __uses_alloc, - _Ignore __use_alloc_prefix, - _OuterAlloc& __outer_alloc, - _InnerAlloc& __inner_alloc, - _Tp* __p, _Args&&... __args) - { - // _Tp doesn't use allocators. Construct without an - // allocator argument. - allocator_traits<_OuterAlloc>::construct(__outer_alloc, __p, - std::forward<_Args>(__args)...); - } - - template - inline void __dispatch_scoped_construct(std::true_type __uses_alloc, - std::true_type __use_alloc_prefix, - _OuterAlloc& __outer_alloc, - _InnerAlloc& __inner_alloc, - _Tp* __p, _Args&&... __args) - { - // _Tp doesn't use allocators. Construct without an - // allocator argument. - allocator_traits<_OuterAlloc>::construct(__outer_alloc, __p, - allocator_arg, __inner_alloc, - std::forward<_Args>(__args)...); - } - - template - inline void __dispatch_scoped_construct(std::true_type __uses_alloc, - std::false_type __use_alloc_prefix, - _OuterAlloc& __outer_alloc, - _InnerAlloc& __inner_alloc, - _Tp* __p, _Args&&... __args) - { - // If _Tp uses an allocator compatible with _InnerAlloc, - // but the specific constructor does not have a variant that - // takes an allocator argument, then program is malformed. -// static_assert(has_constructor<_Tp, _Args...>::value, -// "Cannot pass inner allocator to this constructor"); - - allocator_traits<_OuterAlloc>::construct( - __outer_alloc, __p, std::forward<_Args>(__args)..., - __inner_alloc); - } - - template - inline void __do_scoped_construct(std::false_type __scoped_outer, - _OuterAlloc& __outer_alloc, - _InnerAlloc& __inner_alloc, - _Tp* __p, _Args&&... __args) - { - // Dispatch construction to the correct __dispatch_scoped_construct() - // function based on whether _Tp uses an allocator of type - // _InnerAlloc and, if so, whether there exists the following - // constructor: - // _Tp(allocator_arg_t, _InnerAlloc, Args...). - auto __uses_alloc = uses_allocator<_Tp, _InnerAlloc>(); - auto __use_alloc_prefix = __has_ctor<_Tp>(0, allocator_arg, - __inner_alloc, - std::forward<_Args>(__args)...); - __dispatch_scoped_construct(__uses_alloc, __use_alloc_prefix, - __outer_alloc, - __inner_alloc, - __p, std::forward<_Args>(__args)...); - } - - template - void __do_scoped_construct(std::true_type __scoped_outer, - _OuterAlloc& __outer_alloc, - _InnerAlloc& __inner_alloc, - _Tp* __p, _Args&&... __args) - { - // Use outermost allocator if __outer_alloc is scoped - typedef typename _OuterAlloc::outer_allocator_type outerouter; - __do_scoped_construct(__is_scoped_allocator(), - __outer_alloc.outer_allocator(), - __inner_alloc, - __p, std::forward<_Args>(__args)...); - } - -} // end namespace __details - -/////////////////////////////////////////////////////////////////////////////// -// Implementation of scoped_allocator_adaptor -/////////////////////////////////////////////////////////////////////////////// - -template -scoped_allocator_adaptor:: - scoped_allocator_adaptor() -{ -} - -template -scoped_allocator_adaptor:: - scoped_allocator_adaptor(const scoped_allocator_adaptor& other) - : _Base(other) -{ -} - -template - template - scoped_allocator_adaptor:: - scoped_allocator_adaptor(const scoped_allocator_adaptor& other) - : _Base(other) -{ -} - -template - template - scoped_allocator_adaptor:: - scoped_allocator_adaptor(scoped_allocator_adaptor&& other) - : _Base(std::move(other)) -{ -} - -template - template - scoped_allocator_adaptor:: - scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs) - : _Base(std::forward(outerAlloc), innerAllocs...) -{ -} - -template -scoped_allocator_adaptor:: - ~scoped_allocator_adaptor() -{ -} - -template -inline typename allocator_traits::pointer -scoped_allocator_adaptor:: - allocate(size_type n) -{ - return allocator_traits::allocate(outer_allocator(), n); -} - -template -inline typename allocator_traits::pointer -scoped_allocator_adaptor:: - allocate(size_type n, const_void_pointer hint) -{ - return allocator_traits::allocate(outer_allocator(), n, hint); -} - -template -inline void scoped_allocator_adaptor:: - deallocate(pointer p, size_type n) -{ - allocator_traits::deallocate(outer_allocator(), p, n); -} - -template -inline typename allocator_traits::size_type -scoped_allocator_adaptor::max_size() const -{ - return allocator_traits::max_size(outer_allocator()); -} - -template - template - inline void scoped_allocator_adaptor:: - destroy(T* p) -{ - allocator_traits::destroy(outer_allocator(), p); -} - -template - template - inline - void scoped_allocator_adaptor::construct(T* p, - Args&&... args) -{ - __do_scoped_construct(__details::__is_scoped_allocator(), - this->outer_allocator(), this->inner_allocator(), - p, std::forward(args)...); -} - -template - template - void scoped_allocator_adaptor::construct( - std::pair* p) -{ - construct(addressof(p->first)); - try { - construct(addressof(p->second)); - } - catch (...) { - destroy(addressof(p->first)); - throw; - } -} - -template - template - void scoped_allocator_adaptor::construct( - std::pair* p, U&& x, V&& y) -{ - construct(addressof(p->first), std::forward(x)); - try { - construct(addressof(p->second), std::forward(y)); - } - catch (...) { - destroy(addressof(p->first)); - throw; - } -} - -template - template - void scoped_allocator_adaptor::construct( - std::pair* p, const std::pair& pr) -{ - construct(addressof(p->first), pr.first); - try { - construct(addressof(p->second), pr.second); - } - catch (...) { - destroy(addressof(p->first)); - throw; - } -} - -template - template - void scoped_allocator_adaptor::construct( - std::pair* p, std::pair&& pr) -{ - construct(addressof(p->first), std::move(pr.first)); - try { - construct(addressof(p->second), std::move(pr.second)); - } - catch (...) { - destroy(addressof(p->first)); - throw; - } -} - -template -inline -bool operator==(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) -{ - return a.outer_allocator() == b.outer_allocator() - && a.inner_allocator() == b.inner_allocator(); -} - -template -inline -bool operator==(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) -{ - return a.outer_allocator() == b.outer_allocator(); -} - -template -inline -bool operator!=(const scoped_allocator_adaptor& a, - const scoped_allocator_adaptor& b) -{ - return ! (a == b); -} - -}} // namespace boost { namespace container { - -#include - -#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP diff --git a/include/boost/container/allocator/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp similarity index 77% rename from include/boost/container/allocator/allocator_traits.hpp rename to include/boost/container/allocator_traits.hpp index 0192161..b253cde 100644 --- a/include/boost/container/allocator/allocator_traits.hpp +++ b/include/boost/container/allocator_traits.hpp @@ -6,7 +6,7 @@ // ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost +// (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) // @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -53,6 +54,8 @@ struct is_std_allocator< std::allocator > ///@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 struct allocator_traits { @@ -62,54 +65,54 @@ struct allocator_traits typedef typename Alloc::value_type value_type; #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //!Alloc::pointer if such a type exists; otherwise, value_type* - //! + //! Alloc::pointer if such a type exists; otherwise, value_type* + //! typedef unspecified pointer; - //!Alloc::const_pointer if such a type exists ; otherwise, pointer_traits::rebind::rebind::rebind. - //! + //! 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::rebind. + //! typedef unspecified void_pointer; - //!Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits::rebind::rebind::difference_type. - //! + //! Alloc::difference_type if such a type exists ; otherwise, pointer_traits::difference_type. + //! typedef unspecified difference_type; - //!Alloc::size_type if such a type exists ; otherwise, make_unsigned::type - //! + //! Alloc::size_type if such a type exists ; otherwise, make_unsigned::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. + //! 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. + //! 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. + //! 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::other if such a type exists; otherwise, Alloc - //!if Alloc is a class template instantiation of the form Alloc, 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. + //! Defines an allocator: Alloc::rebind::other if such a type exists; otherwise, Alloc + //! if Alloc is a class template instantiation of the form Alloc, 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 using rebind_alloc = unspecified; - //!In C++03 compilers
rebind_traits
is a struct derived from - //!
allocator_traits
, where `OtherAlloc` is
-      //!the allocator deduced by rules explained in `rebind_alloc`.
+      //! In C++03 compilers `rebind_traits` is a struct derived from
+      //! `allocator_traits`, where `OtherAlloc` is
+      //! the allocator deduced by rules explained in `rebind_alloc`.
       template  using rebind_traits = allocator_traits >;
 
-      //!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`.
+      //! 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 
       struct portable_rebind_alloc
       {  typedef unspecified_type type;  };
@@ -164,9 +167,9 @@ struct allocator_traits
 
       #if !defined(BOOST_NO_TEMPLATE_ALIASES)
          //C++11
-         template  using rebind_alloc  = boost::intrusive::detail::type_rebinder::type;
+         template  using rebind_alloc  = typename boost::intrusive::detail::type_rebinder::type;
          template  using rebind_traits = allocator_traits< rebind_alloc >;
-      #else    //!defined(BOOST_NO_TEMPLATE_ALIASES)
+      #else    // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
          //Some workaround for C++03 or C++11 compilers with no template aliases
          template 
          struct rebind_alloc : boost::intrusive::detail::type_rebinder::type
@@ -174,10 +177,10 @@ struct allocator_traits
             typedef typename boost::intrusive::detail::type_rebinder::type Base;
             #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
             template 
-            rebind_alloc(Args&&... args)
+            rebind_alloc(BOOST_FWD_REF(Args)... args)
                : Base(boost::forward(args)...)
             {}
-            #else    //!defined(BOOST_NO_VARIADIC_TEMPLATES)
+            #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, _))                       \
@@ -186,32 +189,32 @@ struct allocator_traits
             //
             #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
             #include BOOST_PP_LOCAL_ITERATE()
-            #endif   //!defined(BOOST_NO_VARIADIC_TEMPLATES)
+            #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
          };
 
          template 
          struct rebind_traits
             : allocator_traits::type>
          {};
-      #endif   //!defined(BOOST_NO_TEMPLATE_ALIASES)
+      #endif   // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
       template 
       struct portable_rebind_alloc
       {  typedef typename boost::intrusive::detail::type_rebinder::type type;  };
    #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
 
-   //!Returns: a.allocate(n)
-   //!
+   //! Returns: `a.allocate(n)`
+   //! 
    static pointer allocate(Alloc &a, size_type n)
    {  return a.allocate(n);  }
 
-   //!Returns: a.deallocate(p, n)
-   //!
-   //!Throws: Nothing
+   //! Returns: `a.deallocate(p, n)`
+   //! 
+   //! Throws: Nothing
    static void deallocate(Alloc &a, pointer p, size_type n)
    {  return a.deallocate(p, n);  }
 
-   //!Effects: calls `a.construct(p, std::forward(args)...)` if that call is well-formed;
-   //!otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)`
+   //! Effects: calls `a.construct(p, std::forward(args)...)` if that call is well-formed;
+   //! otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)`
    static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
    {
       const bool value = boost::container::container_detail::
@@ -221,8 +224,8 @@ struct allocator_traits
       return allocator_traits::priv_allocate(flag, a, n, p);
    }
 
-   //!Effects: calls a.destroy(p) if that call is well-formed;
-   //!otherwise, invokes `p->~T()`.
+   //! Effects: calls `a.destroy(p)` if that call is well-formed;
+   //! otherwise, invokes `p->~T()`.
    template
    static void destroy(Alloc &a, T*p)
    {
@@ -234,8 +237,8 @@ struct allocator_traits
       allocator_traits::priv_destroy(flag, a, p);
    }
 
-   //!Returns: a.max_size() if that expression is well-formed; otherwise,
-   //!`numeric_limits::max()`.
+   //! Returns: `a.max_size()` if that expression is well-formed; otherwise,
+   //! `numeric_limits::max()`.
    static size_type max_size(const Alloc &a)
    {
       const bool value = boost::container::container_detail::
@@ -245,8 +248,8 @@ struct allocator_traits
       return allocator_traits::priv_max_size(flag, a);
    }
 
-   //!Returns: a.select_on_container_copy_construction() if that expres sion is well- formed;
-   //!otherwise, a.
+   //! Returns: `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::
@@ -256,17 +259,17 @@ struct allocator_traits
       return allocator_traits::priv_select_on_container_copy_construction(flag, a);
    }
 
-   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-      //!Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; 
-      //!otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)`
+   #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //! Effects: calls `a.construct(p, std::forward(args)...)` if that call is well-formed; 
+      //! otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)`
       template 
-      static void construct(Alloc & a, T* p, Args&&... args)
+      static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
       {
          ::boost::integral_constant::value> flag;
          allocator_traits::priv_construct(flag, a, p, ::boost::forward(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)
@@ -295,9 +298,9 @@ struct allocator_traits
       static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
       {  return a;  }
 
-      #if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
+      #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
          template
-         static void priv_construct(boost::false_type, Alloc &a, T *p, Args && ...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
@@ -307,19 +310,19 @@ struct allocator_traits
          }
 
          template
-         static void priv_construct(boost::true_type, Alloc &a, T *p, Args && ...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)...);
          }
 
          template
-         static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, Args && ...args)
+         static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
          {  a.construct( p, ::boost::forward(args)...);  }
 
          template
-         static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, Args && ...args)
+         static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
          {  ::new((void*)p) T(::boost::forward(args)...); }
-      #else
+      #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
          public:
          #define BOOST_PP_LOCAL_MACRO(n)                                                              \
          template                                 \
@@ -368,7 +371,7 @@ struct allocator_traits
          //
          #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
          #include BOOST_PP_LOCAL_ITERATE()
-      #endif   //BOOST_CONTAINER_PERFECT_FORWARDING
+      #endif   // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
    #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    ///@endcond
diff --git a/include/boost/container/container_fwd.hpp b/include/boost/container/container_fwd.hpp
index da325e4..cf8d6e6 100644
--- a/include/boost/container/container_fwd.hpp
+++ b/include/boost/container/container_fwd.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -132,26 +132,22 @@ class basic_string;
 
 //! Type used to tag that the input range is
 //! guaranteed to be ordered
-struct ordered_range_impl_t {};
+struct ordered_range_t
+{};
 
 //! Type used to tag that the input range is
 //! guaranteed to be ordered and unique
-struct ordered_unique_range_impl_t{};
-
-/// @cond
-
-typedef ordered_range_impl_t * ordered_range_t;
-typedef ordered_unique_range_impl_t *ordered_unique_range_t;
-
-/// @endcond
+struct ordered_unique_range_t
+   : public ordered_range_t
+{};
 
 //! Value used to tag that the input range is
 //! guaranteed to be ordered
-static const ordered_range_t ordered_range = 0;
+static const ordered_range_t ordered_range = ordered_range_t();
 
 //! Value used to tag that the input range is
 //! guaranteed to be ordered and unique
-static const ordered_unique_range_t ordered_unique_range = 0;
+static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
 
 /// @cond
 
diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp
index 9ee0ee1..92bf0d4 100644
--- a/include/boost/container/deque.hpp
+++ b/include/boost/container/deque.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -44,7 +44,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -896,6 +896,46 @@ class deque : protected deque_base
       :  Base(boost::move(static_cast(x)))
    {  this->swap_members(x);   }
 
+   //! Effects: Copy constructs a vector using the specified allocator.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocation
+   //!   throws or T's copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   deque(const deque& x, const allocator_type &a)
+      :  Base(a)
+   {
+      if(x.size()){
+         this->priv_initialize_map(x.size());
+         boost::container::uninitialized_copy_alloc
+            (this->alloc(), x.begin(), x.end(), this->members_.m_start);
+      }
+   }
+
+   //! Effects: Move constructor using the specified allocator.
+   //!                 Moves mx's resources to *this if a == allocator_type().
+   //!                 Otherwise copies values from x to *this.
+   //!
+   //! Throws: If allocation or T's copy constructor throws.
+   //! 
+   //! Complexity: Constant if a == mx.get_allocator(), linear otherwise.
+   deque(BOOST_RV_REF(deque) mx, const allocator_type &a) 
+      :  Base(a)
+   {
+      if(mx.alloc() == a){
+         this->swap_members(mx);
+      }
+      else{
+         if(mx.size()){
+            this->priv_initialize_map(mx.size());
+            boost::container::uninitialized_copy_alloc
+               (this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
+         }
+      }
+   }
+
    //! Effects: Constructs a deque that will use a copy of allocator a
    //!   and inserts a copy of the range [first, last) in the deque.
    //!
diff --git a/include/boost/container/detail/adaptive_node_pool_impl.hpp b/include/boost/container/detail/adaptive_node_pool_impl.hpp
index 3649579..92b6133 100644
--- a/include/boost/container/detail/adaptive_node_pool_impl.hpp
+++ b/include/boost/container/detail/adaptive_node_pool_impl.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/advanced_insert_int.hpp b/include/boost/container/detail/advanced_insert_int.hpp
index 58199c7..0d198b0 100644
--- a/include/boost/container/detail/advanced_insert_int.hpp
+++ b/include/boost/container/detail/advanced_insert_int.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-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)
 //
@@ -17,7 +17,9 @@
 
 #include "config_begin.hpp"
 #include 
-#include 
+#include 
+#include 
+#include 
 #include 
 #include   //std::iterator_traits
 #include 
@@ -41,7 +43,6 @@ template
 struct advanced_insert_aux_proxy
    :  public advanced_insert_aux_int
 {
-   typedef boost::container::allocator_traits alloc_traits;
    typedef typename allocator_traits::size_type size_type;
    typedef typename allocator_traits::value_type value_type;
    typedef typename advanced_insert_aux_int::difference_type difference_type;
@@ -54,36 +55,36 @@ struct advanced_insert_aux_proxy
    {}
 
    virtual void copy_remaining_to(Iterator p)
-   {  ::boost::copy_or_move(first_, last_, p);  }
+   {  ::boost::copy_or_move(this->first_, this->last_, p);  }
 
    virtual void uninitialized_copy_remaining_to(Iterator p)
-   {  ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p);  }
+   {  ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p);  }
 
    virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
-      FwdIt mid = first_;
+      FwdIt mid = this->first_;
       std::advance(mid, division_count);
       if(first_n){
-         ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
-         first_ = mid;
+         ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
+         this->first_ = mid;
       }
       else{
-         ::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
-         last_ = mid;
+         ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
+         this->last_ = mid;
       }
    }
 
    virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
-      FwdIt mid = first_;
+      FwdIt mid = this->first_;
       std::advance(mid, division_count);
       if(first_n){
-         ::boost::copy_or_move(first_, mid, pos);
-         first_ = mid;
+         ::boost::copy_or_move(this->first_, mid, pos);
+         this->first_ = mid;
       }
       else{
-         ::boost::copy_or_move(mid, last_, pos);
-         last_ = mid;
+         ::boost::copy_or_move(mid, this->last_, pos);
+         this->last_ = mid;
       }
    }
    A &a_;
@@ -95,7 +96,7 @@ template
 struct default_construct_aux_proxy
    :  public advanced_insert_aux_int
 {
-   typedef boost::container::allocator_traits alloc_traits;
+   typedef ::boost::container::allocator_traits alloc_traits;
    typedef typename allocator_traits::size_type size_type;
    typedef typename allocator_traits::value_type value_type;
    typedef typename advanced_insert_aux_int::difference_type difference_type;
@@ -109,11 +110,11 @@ struct default_construct_aux_proxy
 
    virtual void copy_remaining_to(Iterator)
    {  //This should never be called with any count
-      BOOST_ASSERT(count_ == 0);
+      BOOST_ASSERT(this->count_ == 0);
    }
 
    virtual void uninitialized_copy_remaining_to(Iterator p)
-   {  this->priv_uninitialized_copy(p, count_); }
+   {  this->priv_uninitialized_copy(p, this->count_); }
 
    virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
@@ -122,22 +123,22 @@ struct default_construct_aux_proxy
          new_count = division_count;
       }
       else{
-         BOOST_ASSERT(difference_type(count_)>= division_count);
-         new_count = count_ - division_count;
+         BOOST_ASSERT(difference_type(this->count_)>= division_count);
+         new_count = this->count_ - division_count;
       }
       this->priv_uninitialized_copy(pos, new_count);
    }
 
    virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
    {
-      BOOST_ASSERT(count_ == 0);
+      BOOST_ASSERT(this->count_ == 0);
       size_type new_count;
       if(first_n){
          new_count = division_count;
       }
       else{
-         BOOST_ASSERT(difference_type(count_)>= division_count);
-         new_count = count_ - division_count;
+         BOOST_ASSERT(difference_type(this->count_)>= division_count);
+         new_count = this->count_ - division_count;
       }
       //This function should never called with a count different to zero
       BOOST_ASSERT(new_count == 0);
@@ -147,21 +148,21 @@ struct default_construct_aux_proxy
    private:
    void priv_uninitialized_copy(Iterator p, const size_type n)
    {
-      BOOST_ASSERT(n <= count_);
+      BOOST_ASSERT(n <= this->count_);
       Iterator orig_p = p;
       size_type i = 0;
       try{
          for(; i < n; ++i, ++p){
-            alloc_traits::construct(a_, container_detail::to_raw_pointer(&*p));
+            alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
          }
       }
       catch(...){
          while(i--){
-            alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
+            alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
          }
          throw;
       }
-      count_ -= n;
+      this->count_ -= n;
    }
    A &a_;
    size_type count_;
@@ -223,13 +224,13 @@ struct advanced_insert_aux_non_movable_emplace
    {
       BOOST_ASSERT(division_count <=1);
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){
-         if(!used_){
-            alloc_traits::construct( a_
+         if(!this->used_){
+            alloc_traits::construct( this->a_
                                    , container_detail::to_raw_pointer(&*p)
                                    , ::boost::container::container_detail::
-                                       stored_ref::forward(get(args_))...
+                                       stored_ref::forward(get(this->args_))...
                                    );
-            used_ = true;
+            this->used_ = true;
          }
       }
    }
@@ -237,13 +238,13 @@ struct advanced_insert_aux_non_movable_emplace
    template
    void priv_uninitialized_copy_remaining_to(const index_tuple&, Iterator p)
    {
-      if(!used_){
-         alloc_traits::construct( a_
+      if(!this->used_){
+         alloc_traits::construct( this->a_
                                 , container_detail::to_raw_pointer(&*p)
                                 , ::boost::container::container_detail::
-                                    stored_ref::forward(get(args_))...
+                                    stored_ref::forward(get(this->args_))...
                                 );
-         used_ = true;
+         this->used_ = true;
       }
    }
 
@@ -260,12 +261,13 @@ struct advanced_insert_aux_emplace
    :  public advanced_insert_aux_non_movable_emplace
 {
    typedef advanced_insert_aux_non_movable_emplace base_t;
+   typedef boost::container::allocator_traits alloc_traits;
    typedef typename base_t::value_type       value_type;
    typedef typename base_t::difference_type  difference_type;
    typedef typename base_t::index_tuple_t    index_tuple_t;
 
    explicit advanced_insert_aux_emplace(A &a, Args&&... args)
-      : base_t(a, boost::forward(args)...)
+      : base_t(a, ::boost::forward(args)...)
    {}
 
    ~advanced_insert_aux_emplace()
@@ -283,8 +285,13 @@ struct advanced_insert_aux_emplace
    void priv_copy_remaining_to(const index_tuple&, Iterator p)
    {
       if(!this->used_){
-         *p = boost::move(value_type (
-            ::boost::container::container_detail::stored_ref::forward(get(this->args_))...));
+         aligned_storage::value> v;
+         value_type *vp = static_cast(static_cast(&v));
+         alloc_traits::construct(this->a_, vp,
+            ::boost::container::container_detail::stored_ref::forward(get(this->args_))...);
+         scoped_destructor d(this->a_, vp);
+         *p = ::boost::move(*vp);
+         d.release();
          this->used_ = true;
       }
    }
@@ -295,8 +302,17 @@ struct advanced_insert_aux_emplace
       BOOST_ASSERT(division_count <=1);
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){
          if(!this->used_){
-            *p = boost::move(value_type(
-               ::boost::container::container_detail::stored_ref::forward(get(this->args_))...));
+            aligned_storage::value> v;
+            value_type *vp = static_cast(static_cast(&v));
+            alloc_traits::construct(this->a_, vp,
+               ::boost::container::container_detail::stored_ref::forward(get(this->args_))...);
+            try {
+               *p = ::boost::move(*vp);
+            } catch (...) {
+               alloc_traits::destroy(this->a_, vp);
+               throw;
+            }
+            alloc_traits::destroy(this->a_, vp);
             this->used_ = true;
          }
       }
@@ -337,13 +353,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), ar
                                                                                     \
    virtual void uninitialized_copy_remaining_to(Iterator p)                         \
    {                                                                                \
-      if(!used_){                                                                   \
+      if(!this->used_){                                                             \
          alloc_traits::construct                                                    \
-            ( a_                                                                    \
+            ( this->a_                                                              \
             , container_detail::to_raw_pointer(&*p)                                 \
             BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)         \
             );                                                                      \
-         used_ = true;                                                              \
+         this->used_ = true;                                                        \
       }                                                                             \
    }                                                                                \
                                                                                     \
@@ -352,13 +368,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), ar
    {                                                                                \
       BOOST_ASSERT(division_count <=1);                                             \
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){    \
-         if(!used_){                                                                \
+         if(!this->used_){                                                          \
             alloc_traits::construct                                                 \
-               ( a_                                                                 \
+               ( this->a_                                                           \
                , container_detail::to_raw_pointer(&*p)                              \
                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)      \
                );                                                                   \
-            used_ = true;                                                           \
+            this->used_ = true;                                                     \
          }                                                                          \
       }                                                                             \
    }                                                                                \
@@ -382,6 +398,7 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
           base_t;                 \
    typedef typename base_t::value_type       value_type;                            \
    typedef typename base_t::difference_type  difference_type;                       \
+   typedef boost::container::allocator_traits alloc_traits;                      \
                                                                                     \
    BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)                  \
       ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )          \
@@ -391,10 +408,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
    virtual void copy_remaining_to(Iterator p)                                       \
    {                                                                                \
       if(!this->used_){                                                             \
-         value_type v BOOST_PP_LPAREN_IF(n)                                         \
-            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)                  \
-            BOOST_PP_RPAREN_IF(n);                                                  \
-         *p = boost::move(v);                                                       \
+         aligned_storage::value> v;    \
+         value_type *vp = static_cast(static_cast(&v));       \
+         alloc_traits::construct(this->a_, vp                                       \
+            BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _));       \
+         scoped_destructor d(this->a_, vp);                                      \
+         *p = ::boost::move(*vp);                                                     \
+         d.release();                                                               \
          this->used_ = true;                                                        \
       }                                                                             \
    }                                                                                \
@@ -405,10 +425,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
       BOOST_ASSERT(division_count <=1);                                             \
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){    \
          if(!this->used_){                                                          \
-            value_type v BOOST_PP_LPAREN_IF(n)                                      \
-                  BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)            \
-                BOOST_PP_RPAREN_IF(n);                                              \
-            *p = boost::move(v);                                                    \
+            aligned_storage::value> v; \
+            value_type *vp = static_cast(static_cast(&v));    \
+            alloc_traits::construct(this->a_, vp                                    \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _));    \
+            scoped_destructor d(this->a_, vp);                                   \
+            *p = ::boost::move(*vp);                                                  \
+            d.release();                                                            \
             this->used_ = true;                                                     \
          }                                                                          \
       }                                                                             \
diff --git a/include/boost/container/detail/algorithms.hpp b/include/boost/container/detail/algorithms.hpp
index a2713f5..5735f4d 100644
--- a/include/boost/container/detail/algorithms.hpp
+++ b/include/boost/container/detail/algorithms.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/container/detail/allocation_type.hpp b/include/boost/container/detail/allocation_type.hpp
index edad487..3988fda 100644
--- a/include/boost/container/detail/allocation_type.hpp
+++ b/include/boost/container/detail/allocation_type.hpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/config_begin.hpp b/include/boost/container/detail/config_begin.hpp
index bd44daa..83c2cfe 100644
--- a/include/boost/container/detail/config_begin.hpp
+++ b/include/boost/container/detail/config_begin.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -45,4 +45,5 @@
                                     //    with /GR-; unpredictable behavior may result
    #pragma warning (disable : 4673) //  throwing '' the following types will not be considered at the catch site
    #pragma warning (disable : 4671) //  the copy constructor is inaccessible
+   #pragma warning (disable : 4584) //  X is already a base-class of Y
 #endif   //BOOST_MSVC
diff --git a/include/boost/container/detail/config_end.hpp b/include/boost/container/detail/config_end.hpp
index b71fabc..3451371 100644
--- a/include/boost/container/detail/config_end.hpp
+++ b/include/boost/container/detail/config_end.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/destroyers.hpp b/include/boost/container/detail/destroyers.hpp
index 26ae089..55b811d 100644
--- a/include/boost/container/detail/destroyers.hpp
+++ b/include/boost/container/detail/destroyers.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -21,7 +21,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 namespace boost {
 namespace container { 
@@ -85,6 +85,9 @@ struct scoped_destructor_n
 
    void increment_size(size_type inc)
    {  m_n += inc;   }
+
+   void increment_size_backwards(size_type inc)
+   {  m_n += inc;   m_p -= inc;  }
    
    ~scoped_destructor_n()
    {
@@ -115,10 +118,38 @@ struct null_scoped_destructor_n
    void increment_size(size_type)
    {}
 
+   void increment_size_backwards(size_type)
+   {}
+
    void release()
    {}
 };
 
+template
+class scoped_destructor
+{
+   typedef boost::container::allocator_traits AllocTraits;
+   public:
+   typedef typename A::value_type value_type;
+   scoped_destructor(A &a, value_type *pv)
+      : pv_(pv), a_(a)
+   {}
+
+   ~scoped_destructor()
+   {
+      if(pv_){
+         AllocTraits::destroy(a_, pv_);
+      }
+   }
+
+   void release()
+   {  pv_ = 0; }
+
+   private:
+   value_type *pv_;
+   A &a_;
+};
+
 template 
 class allocator_destroyer
 {
diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp
index 4443838..960a491 100644
--- a/include/boost/container/detail/flat_tree.hpp
+++ b/include/boost/container/detail/flat_tree.hpp
@@ -1,6 +1,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -102,11 +102,19 @@ class flat_tree
       {}
 
       Data(const Data &d)
-         : value_compare(d), m_vect(d.m_vect)
+         : value_compare(static_cast(d)), m_vect(d.m_vect)
       {}
 
       Data(BOOST_RV_REF(Data) d)
-         : value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
+         : value_compare(boost::move(static_cast(d))), m_vect(boost::move(d.m_vect))
+      {}
+
+      Data(const Data &d, const A &a)
+         : value_compare(static_cast(d)), m_vect(d.m_vect, a)
+      {}
+
+      Data(BOOST_RV_REF(Data) d, const A &a)
+         : value_compare(boost::move(static_cast(d))), m_vect(boost::move(d.m_vect), a)
       {}
 
       Data(const Compare &comp) 
@@ -185,6 +193,14 @@ class flat_tree
       :  m_data(boost::move(x.m_data))
    { }
 
+   flat_tree(const flat_tree& x, const allocator_type &a) 
+      :  m_data(x.m_data, a)
+   { }
+
+   flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
+      :  m_data(boost::move(x.m_data), a)
+   { }
+
    template 
    flat_tree( ordered_range_t, InputIterator first, InputIterator last
             , const Compare& comp     = Compare()
@@ -285,7 +301,6 @@ class flat_tree
       return ret;
    }
 
-
    iterator insert_equal(const value_type& val)
    {
       iterator i = this->upper_bound(KeyOfValue()(val));
@@ -323,14 +338,14 @@ class flat_tree
    iterator insert_equal(const_iterator pos, const value_type& val)
    {
       insert_commit_data data;
-      priv_insert_equal_prepare(pos, val, data);
+      this->priv_insert_equal_prepare(pos, val, data);
       return priv_insert_commit(data, val);
    }
 
    iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
    {
       insert_commit_data data;
-      priv_insert_equal_prepare(pos, mval, data);
+      this->priv_insert_equal_prepare(pos, mval, data);
       return priv_insert_commit(data, boost::move(mval));
    }
 
@@ -346,7 +361,15 @@ class flat_tree
    {
       typedef typename 
          std::iterator_traits::iterator_category ItCat;
-      priv_insert_equal(first, last, ItCat());
+      this->priv_insert_equal(first, last, ItCat());
+   }
+
+   template 
+   void insert_equal(ordered_range_t, InIt first, InIt last)
+   {
+      typedef typename 
+         std::iterator_traits::iterator_category ItCat;
+      this->priv_insert_equal(ordered_range_t(), first, last, ItCat());
    }
 
    #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -390,7 +413,7 @@ class flat_tree
    {
       value_type &&val = value_type(boost::forward(args)...);
       insert_commit_data data;
-      priv_insert_equal_prepare(hint, val, data);
+      this->priv_insert_equal_prepare(hint, val, data);
       return priv_insert_commit(data, boost::move(val));
    }
 
@@ -450,7 +473,7 @@ class flat_tree
             BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
       value_type &val = vval;                                                             \
       insert_commit_data data;                                                            \
-      priv_insert_equal_prepare(hint, val, data);                                         \
+      this->priv_insert_equal_prepare(hint, val, data);                                   \
       return priv_insert_commit(data, boost::move(val));                                  \
    }                                                                                      \
    //!
@@ -730,10 +753,39 @@ class flat_tree
       return std::pair(first, first);
    }
 
-   template 
-   void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
+   template 
+   void priv_insert_equal(ordered_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
    {
       size_type len = static_cast(std::distance(first, last));
+      const size_type BurstSize = 16;
+      size_type positions[BurstSize];
+
+      while(len){
+         const size_type burst = len < BurstSize ? len : BurstSize;
+         len -= burst;
+         const iterator beg(this->cbegin());
+         iterator pos;
+         for(size_type i = 0; i != burst; ++i){
+            pos = this->upper_bound(KeyOfValue()(*first));
+            positions[i] = static_cast(pos - beg);
+            ++first;
+         }
+         this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
+      }
+   }
+
+   template 
+   void priv_insert_equal_forward(ordered_range_t, FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {  this->priv_insert_equal(first, last, std::forward_iterator_tag());   }
+
+   template 
+   void priv_insert_equal(ordered_range_t, InIt first, InIt last, std::input_iterator_tag)
+   {  this->priv_insert_equal(first, last, std::input_iterator_tag());  }
+
+   template 
+   void priv_insert_equal_forward(FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {
+      const size_type len = static_cast(std::distance(first, last));
       this->reserve(this->size()+len);
       this->priv_insert_equal(first, last, std::input_iterator_tag());
    }
diff --git a/include/boost/container/detail/function_detector.hpp b/include/boost/container/detail/function_detector.hpp
index c37c766..c30ed81 100644
--- a/include/boost/container/detail/function_detector.hpp
+++ b/include/boost/container/detail/function_detector.hpp
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga  2009-2011.
+// (C) Copyright Ion Gaztanaga  2009-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 //    (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/container/detail/iterators.hpp b/include/boost/container/detail/iterators.hpp
index 899cbe4..53a3ef5 100644
--- a/include/boost/container/detail/iterators.hpp
+++ b/include/boost/container/detail/iterators.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
@@ -21,7 +21,7 @@
 #include "config_begin.hpp"
 #include 
 #include 
-#include 
+#include 
 
 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 #include 
@@ -513,7 +513,7 @@ struct emplace_functor
    container_detail::tuple args_;
 };
 
-#else
+#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 
 #define BOOST_PP_LOCAL_MACRO(n)                                                        \
    BOOST_PP_EXPR_IF(n, template <)                                                     \
@@ -522,16 +522,16 @@ struct emplace_functor
    struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                          \
    {                                                                                   \
       BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                              \
-         ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )                       \
-      BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){}    \
+         ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )                        \
+      BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){}      \
                                                                                        \
       template                                                       \
       void operator()(A &a, T *ptr)                                                    \
       {                                                                                \
          allocator_traits::construct                                                \
-            (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
+            (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
       }                                                                                \
-      BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _)                         \
+      BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _)                           \
    };                                                                                  \
    //!
 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
diff --git a/include/boost/container/detail/math_functions.hpp b/include/boost/container/detail/math_functions.hpp
index 4613573..609e1d4 100644
--- a/include/boost/container/detail/math_functions.hpp
+++ b/include/boost/container/detail/math_functions.hpp
@@ -1,7 +1,7 @@
 //////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Stephen Cleary 2000.
-// (C) Copyright Ion Gaztanaga 2007-2011.
+// (C) Copyright Ion Gaztanaga 2007-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 //    (See accompanying file LICENSE_1_0.txt or copy at 
diff --git a/include/boost/container/allocator/memory_util.hpp b/include/boost/container/detail/memory_util.hpp
similarity index 98%
rename from include/boost/container/allocator/memory_util.hpp
rename to include/boost/container/detail/memory_util.hpp
index ea4bc05..c00172c 100644
--- a/include/boost/container/allocator/memory_util.hpp
+++ b/include/boost/container/detail/memory_util.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
+// (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)
 //
diff --git a/include/boost/container/detail/mpl.hpp b/include/boost/container/detail/mpl.hpp
index c2d0ce4..032110a 100644
--- a/include/boost/container/detail/mpl.hpp
+++ b/include/boost/container/detail/mpl.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/container/detail/multiallocation_chain.hpp b/include/boost/container/detail/multiallocation_chain.hpp
index a67fd77..c995253 100644
--- a/include/boost/container/detail/multiallocation_chain.hpp
+++ b/include/boost/container/detail/multiallocation_chain.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp
index 9b0a0a5..022a54f 100644
--- a/include/boost/container/detail/node_alloc_holder.hpp
+++ b/include/boost/container/detail/node_alloc_holder.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -27,7 +27,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -36,6 +36,7 @@
 #endif
 
 #include 
+#include 
 
 
 namespace boost {
@@ -259,47 +260,21 @@ struct node_alloc_holder
 
    void deallocate_one(const NodePtr &p, allocator_v2)
    {  this->node_alloc().deallocate_one(p);   }
-/*
-   template
-   static void construct(A &a, const NodePtr &ptr,
-      BOOST_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
-   {
-      typedef typename Node::hook_type                hook_type;
-      typedef typename Node::value_type::first_type   first_type;
-      typedef typename Node::value_type::second_type  second_type;
-      Node *nodeptr = container_detail::to_raw_pointer(ptr);
 
-      //Hook constructor does not throw
-      allocator_traits::construct(a, static_cast(nodeptr));
-
-      //Now construct pair members_holder
-      value_type *valueptr = &nodeptr->get_data();
-      allocator_traits::construct(a, &valueptr->first, boost::move(value.first));
-      BOOST_TRY{
-         allocator_traits::construct(a, &valueptr->second, boost::move(value.second));
-      }
-      BOOST_CATCH(...){
-         allocator_traits::destroy(a, &valueptr->first);
-         BOOST_RETHROW
-      }
-      BOOST_CATCH_END
-   }
-*/
    #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-/*
-   template
-   static void construct(A &a, const NodePtr &ptr, Args &&...args)
-   {  
-   }
-*/
+
    template
    NodePtr create_node(Args &&...args)
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
       allocator_traits::construct
-         (this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward(args)...);
+         ( this->node_alloc()
+         , container_detail::addressof(p->m_data), boost::forward(args)...);
       node_deallocator.release();
+      //This does not throw
+      typedef typename Node::hook_type hook_type;
+      ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type;
       return (p);
    }
 
@@ -313,9 +288,11 @@ struct node_alloc_holder
       NodePtr p = this->allocate_one();                                                   \
       Deallocator node_deallocator(p, this->node_alloc());                                \
       allocator_traits::construct                                              \
-         (this->node_alloc(), container_detail::to_raw_pointer(p)                         \
+         (this->node_alloc(), container_detail::addressof(p->m_data)                      \
             BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));              \
       node_deallocator.release();                                                         \
+      typedef typename Node::hook_type hook_type;                                         \
+      ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type;      \
       return (p);                                                                         \
    }                                                                                      \
    //!
@@ -329,8 +306,11 @@ struct node_alloc_holder
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
-      ::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
+      ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
       node_deallocator.release();
+      //This does not throw
+      typedef typename Node::hook_type hook_type;
+      ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type;
       return (p);
    }
 
@@ -364,8 +344,11 @@ struct node_alloc_holder
                mem.pop_front();
                //This can throw
                constructed = 0;
-               boost::container::construct_in_place(this->node_alloc(), p, beg);
+               boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
                ++constructed;
+               //This does not throw
+               typedef typename Node::hook_type hook_type;
+               ::new(static_cast(container_detail::to_raw_pointer(p))) hook_type;
                //This can throw in some containers (predicate might throw)
                inserter(*p);
             }
diff --git a/include/boost/container/detail/node_pool_impl.hpp b/include/boost/container/detail/node_pool_impl.hpp
index 9ee9e31..b7fb511 100644
--- a/include/boost/container/detail/node_pool_impl.hpp
+++ b/include/boost/container/detail/node_pool_impl.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp
index 1aeff91..af32d6a 100644
--- a/include/boost/container/detail/pair.hpp
+++ b/include/boost/container/detail/pair.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,8 @@
 #include "config_begin.hpp"
 #include 
 
+#include 
+#include 
 #include 
 #include 
 
@@ -62,6 +64,33 @@ struct pair_nat;
 struct piecewise_construct_t { };
 static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
 
+/*
+template 
+struct pair
+{
+    template  pair(pair&& p);
+    template 
+        pair(piecewise_construct_t, tuple first_args,
+             tuple second_args);
+
+    template  pair& operator=(const pair& p);
+    pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable::value &&
+                                       is_nothrow_move_assignable::value);
+    template  pair& operator=(pair&& p);
+
+    void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
+                                noexcept(swap(second, p.second)));
+};
+
+template  bool operator==(const pair&, const pair&);
+template  bool operator!=(const pair&, const pair&);
+template  bool operator< (const pair&, const pair&);
+template  bool operator> (const pair&, const pair&);
+template  bool operator>=(const pair&, const pair&);
+template  bool operator<=(const pair&, const pair&);
+*/
+
+
 template 
 struct pair
 {
@@ -79,47 +108,40 @@ struct pair
    pair()
       : first(), second()
    {}
-/*
-   //pair from two values
-   pair(const T1 &t1, const T2 &t2)
-      : first(t1)
-      , second(t2)
-   {}
-
-
-   //pair from two values
-   pair(BOOST_RV_REF(T1) t1, BOOST_RV_REF(T2) t2)
-      : first(::boost::move(t1))
-      , second(::boost::move(t2))
-   {}
-*/
-   template
-   pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
-      : first(::boost::forward(u))
-      , second(::boost::forward(v))
-   {}
 
    //pair copy assignment
    pair(const pair& x)
       : first(x.first), second(x.second)
    {}
 
-   template 
-   pair(const pair &p)
-      : first(p.first), second(p.second)
-   {}
-
    //pair move constructor
    pair(BOOST_RV_REF(pair) p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
    template 
-   pair(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+   pair(const pair &p)
+      : first(p.first), second(p.second)
+   {}
+
+   template 
+   pair(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
-   //std::pair copy constructor
+   //pair from two values
+   pair(const T1 &t1, const T2 &t2)
+      : first(t1)
+      , second(t2)
+   {}
+
+   template
+   pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
+      : first(::boost::forward(u))
+      , second(::boost::forward(v))
+   {}
+
+   //And now compatibility with std::pair
    pair(const std::pair& x)
       : first(x.first), second(x.second)
    {}
@@ -129,17 +151,20 @@ struct pair
       : first(p.first), second(p.second)
    {}
 
-   //std::pair move constructor
-   template 
-   pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+   pair(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
-   pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+   template 
+   pair(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
    //piecewise_construct missing
+   //template  pair(pair&& p);
+   //template 
+   //   pair(piecewise_construct_t, tuple first_args,
+   //        tuple second_args);
 /*
    //Variadic versions
    template
@@ -179,14 +204,6 @@ struct pair
       return *this;
    }
 
-   template 
-   pair& operator=(const pair&p)
-   {
-      first  = p.first;
-      second = p.second;
-      return *this;
-   }
-
    //pair move assignment
    pair& operator=(BOOST_RV_REF(pair) p)
    {
@@ -196,7 +213,23 @@ struct pair
    }
 
    template 
-   pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+   typename ::boost::container::container_detail::enable_if_c
+      < !(::boost::container::container_detail::is_same::value &&
+          ::boost::container::container_detail::is_same::value)
+      , pair &>::type
+      operator=(const pair&p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   template 
+   typename ::boost::container::container_detail::enable_if_c
+      < !(::boost::container::container_detail::is_same::value &&
+          ::boost::container::container_detail::is_same::value)
+      , pair &>::type
+      operator=(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p)
    {
       first  = ::boost::move(p.first);
       second = ::boost::move(p.second);
@@ -220,7 +253,7 @@ struct pair
    }
 
    //std::pair move assignment
-   pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+   pair& operator=(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p)
    {
       first  = ::boost::move(p.first);
       second = ::boost::move(p.second);
@@ -228,7 +261,7 @@ struct pair
    }
 
    template 
-   pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+   pair& operator=(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p)
    {
       first  = ::boost::move(p.first);
       second = ::boost::move(p.second);
diff --git a/include/boost/container/detail/pool_common.hpp b/include/boost/container/detail/pool_common.hpp
index c66e2cd..500b912 100644
--- a/include/boost/container/detail/pool_common.hpp
+++ b/include/boost/container/detail/pool_common.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/preprocessor.hpp b/include/boost/container/detail/preprocessor.hpp
index 9916fba..051c17a 100644
--- a/include/boost/container/detail/preprocessor.hpp
+++ b/include/boost/container/detail/preprocessor.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-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)
 //
@@ -62,6 +62,10 @@
    //!
 #endif   //#ifndef BOOST_NO_RVALUE_REFERENCES
 
+#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
+const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
+//!
+
 #ifndef BOOST_NO_RVALUE_REFERENCES
    #define BOOST_CONTAINER_PP_PARAM(U, u) \
    U && u \
@@ -74,17 +78,16 @@
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
 
-   #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
 
-      #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
-      BOOST_PP_CAT(m_p, n) (boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ))           \
-      //!
+   #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+   BOOST_PP_CAT(m_p, n) (static_cast( BOOST_PP_CAT(p, n) ))           \
 
-   #else    //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   #else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
 
-      #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
-      BOOST_PP_CAT(m_p, n) (static_cast( BOOST_PP_CAT(p, n) ))           \
-      //!
+   #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+   BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ))           \
+   //!
 
    #endif   //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
 
@@ -127,7 +130,7 @@
 #else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
 
    #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
-   boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
+   ::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
    //!
 
 #endif   //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
@@ -140,11 +143,11 @@
 
 
 #define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
-boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
 //!
 
 #define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
-boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
+::boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
 //!
 
 #define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
@@ -152,7 +155,11 @@ BOOST_PP_CAT(*this->m_p, n) \
 //!
 
 #define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data)   \
-  BOOST_PP_CAT(class P, n) = void                                      \
+  BOOST_PP_CAT(class P, n) = void                                    \
+//!
+
+#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
+  BOOST_PP_CAT(class P, n) = default_type                                  \
 //!
 
 #define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
diff --git a/include/boost/container/detail/stored_ref.hpp b/include/boost/container/detail/stored_ref.hpp
index df0faa8..80fda89 100644
--- a/include/boost/container/detail/stored_ref.hpp
+++ b/include/boost/container/detail/stored_ref.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-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)
 //
diff --git a/include/boost/container/detail/transform_iterator.hpp b/include/boost/container/detail/transform_iterator.hpp
index 17eca9e..bc558ba 100644
--- a/include/boost/container/detail/transform_iterator.hpp
+++ b/include/boost/container/detail/transform_iterator.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp
index 6cd91ed..178c29d 100644
--- a/include/boost/container/detail/tree.hpp
+++ b/include/boost/container/detail/tree.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -27,7 +27,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
 #include 
 #endif
@@ -90,70 +90,38 @@ struct rbtree_hook
       >::type  type;
 };
 
+//This trait is used to type-pun std::pair because in C++03
+//compilers std::pair is useless for C++11 features
 template
-struct rbtree_type
+struct rbtree_internal_data_type
 {
    typedef T type;
 };
 
 template
-struct rbtree_type< std::pair >
+struct rbtree_internal_data_type< std::pair >
 {
    typedef pair type;
 };
 
+
+//The node to be store in the tree
 template 
 struct rbtree_node
    :  public rbtree_hook::type
 {
    private:
-   BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
+   //BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
+   rbtree_node();
 
    public:
    typedef typename rbtree_hook::type hook_type;
 
    typedef T value_type;
-   typedef typename rbtree_type::type internal_type;
+   typedef typename rbtree_internal_data_type::type internal_type;
 
    typedef rbtree_node node_type;
 
-   rbtree_node()
-      : m_data()
-   {}
-
-   rbtree_node(const rbtree_node &other)
-      : m_data(other.m_data)
-   {}
-
-   rbtree_node(BOOST_RV_REF(rbtree_node) other)
-      : m_data(boost::move(other.m_data))
-   {}
-
-   #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
-   #define BOOST_PP_LOCAL_MACRO(n)                                           \
-   template                                \
-   rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))           \
-      : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))        \
-   {}                                                                        \
-   //!
-   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-   #include BOOST_PP_LOCAL_ITERATE()
-
-   #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
-   template
-   rbtree_node(Args &&...args)
-      : m_data(boost::forward(args)...)
-   {}
-   #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
-   rbtree_node &operator=(const rbtree_node &other)
-   {  do_assign(other.m_data);   return *this;  }
-
-   rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
-   {  do_move(other.m_data);   return *this;  }
-
    T &get_data()
    {
       T* ptr = reinterpret_cast(&this->m_data);
@@ -166,7 +134,6 @@ struct rbtree_node
       return *ptr;
    }
 
-   private:
    internal_type m_data;
 
    template
@@ -188,22 +155,22 @@ struct rbtree_node
    {  m_data = v; }
 
    template
-   void do_move(std::pair &p)
+   void do_move_assign(std::pair &p)
    {
-      const_cast(m_data.first) = boost::move(p.first);
-      m_data.second  = boost::move(p.second);
+      const_cast(m_data.first) = ::boost::move(p.first);
+      m_data.second = ::boost::move(p.second);
    }
 
    template
-   void do_move(pair &p)
+   void do_move_assign(pair &p)
    {
-      const_cast(m_data.first) = boost::move(p.first);
-      m_data.second  = boost::move(p.second);
+      const_cast(m_data.first) = ::boost::move(p.first);
+      m_data.second  = ::boost::move(p.second);
    }
 
    template
-   void do_move(V &v)
-   {  m_data = boost::move(v); }
+   void do_move_assign(V &v)
+   {  m_data = ::boost::move(v); }
 };
 
 }//namespace container_detail {
@@ -282,7 +249,7 @@ class rbtree
             //First recycle a node (this can't throw)
             try{
                //This can throw
-               *p = other;
+               p->do_assign(other.m_data);
                return p;
             }
             catch(...){
@@ -295,7 +262,7 @@ class rbtree
             }
          }
          else{
-            return m_holder.create_node(other);
+            return m_holder.create_node(other.m_data);
          }
       }
 
@@ -319,7 +286,7 @@ class rbtree
             //First recycle a node (this can't throw)
             try{
                //This can throw
-               *p = boost::move(other);
+               p->do_move_assign(const_cast(other).m_data);
                return p;
             }
             catch(...){
@@ -332,7 +299,7 @@ class rbtree
             }
          }
          else{
-            return m_holder.create_node(other);
+            return m_holder.create_node(other.m_data);
          }
       }
 
@@ -478,8 +445,10 @@ class rbtree
       iterator(){}
 
       //Pointer like operators
-      reference operator*()  const {  return  this->m_it->get_data();  }
-      pointer   operator->() const {  return  pointer(&this->m_it->get_data());  }
+      reference operator*()  const
+         {  return this->m_it->get_data();  }
+      pointer   operator->() const
+         {  return boost::intrusive::pointer_traits::pointer_to(this->m_it->get_data());  }
 
       //Increment / Decrement
       iterator& operator++()  
@@ -532,9 +501,28 @@ class rbtree
    }
 
    rbtree(BOOST_RV_REF(rbtree) x) 
-      :  AllocHolder(boost::move(static_cast(x)), x.key_comp())
+      :  AllocHolder(::boost::move(static_cast(x)), x.key_comp())
    {}
 
+   rbtree(const rbtree& x, const allocator_type &a) 
+      :  AllocHolder(a, x.key_comp())
+   {
+      this->icont().clone_from
+         (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+   }
+
+   rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
+      :  AllocHolder(a, x.key_comp())
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->icont().swap(x.icont());
+      }
+      else{
+         this->icont().clone_from
+            (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+      }
+   }
+
    ~rbtree()
    {} //AllocHolder clears the tree
 
@@ -552,7 +540,7 @@ class rbtree
          //Transfer all the nodes to a temporary tree
          //If anything goes wrong, all the nodes will be destroyed
          //automatically
-         Icont other_tree(boost::move(this->icont()));
+         Icont other_tree(::boost::move(this->icont()));
 
          //Now recreate the source tree reusing nodes stored by other_tree
          this->icont().clone_from
@@ -578,7 +566,7 @@ class rbtree
          if(this_alloc == x_alloc){
             //Destroy and swap pointers
             this->clear();
-            this->icont() = boost::move(x.icont());
+            this->icont() = ::boost::move(x.icont());
             //Move allocator if needed
             this->AllocHolder::move_assign_alloc(x);
          }
@@ -587,7 +575,7 @@ class rbtree
             //Transfer all the nodes to a temporary tree
             //If anything goes wrong, all the nodes will be destroyed
             //automatically
-            Icont other_tree(boost::move(this->icont()));
+            Icont other_tree(::boost::move(this->icont()));
 
             //Now recreate the source tree reusing nodes stored by other_tree
             this->icont().clone_from
@@ -872,9 +860,9 @@ class rbtree
       if(this->empty()){
          //Insert with end hint, to achieve linear
          //complexity if [first, last) is ordered
-         const_iterator end(this->end());
+         const_iterator hint(this->cend());
          for( ; first != last; ++first)
-            this->insert_unique(end, *first);
+            hint = this->insert_unique(hint, *first);
       }
       else{
          for( ; first != last; ++first)
@@ -913,9 +901,9 @@ class rbtree
    {
       //Insert with end hint, to achieve linear
       //complexity if [first, last) is ordered
-      const_iterator end(this->cend());
+      const_iterator hint(this->cend());
       for( ; first != last; ++first)
-         this->insert_equal(end, *first);
+         hint = this->insert_equal(hint, *first);
    }
 
    iterator erase(const_iterator position)
diff --git a/include/boost/container/detail/type_traits.hpp b/include/boost/container/detail/type_traits.hpp
index 6a0b3ed..2940f72 100644
--- a/include/boost/container/detail/type_traits.hpp
+++ b/include/boost/container/detail/type_traits.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,13 @@ namespace container_detail {
 
 struct nat{};
 
+template 
+struct LowPriorityConversion
+{
+   // Convertible from T with user-defined-conversion rank.
+   LowPriorityConversion(const U&) { }
+};
+
 //boost::alignment_of yields to 10K lines of preprocessed code, so we
 //need an alternative
 template  struct alignment_of;
diff --git a/include/boost/container/detail/utilities.hpp b/include/boost/container/detail/utilities.hpp
index ee0fe99..57ce356 100644
--- a/include/boost/container/detail/utilities.hpp
+++ b/include/boost/container/detail/utilities.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -21,13 +21,23 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 namespace boost {
 namespace container {
 namespace container_detail {
 
+template 
+inline T* addressof(T& obj)
+{
+   return static_cast(
+	   static_cast(
+	      const_cast(
+            &reinterpret_cast(obj)
+   )));
+}
+
 template
 const T &max_value(const T &a, const T &b)
 {  return a > b ? a : b;   }
@@ -262,6 +272,7 @@ F uninitialized_copy_or_move_alloc
    return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
 }
 
+
 }  //namespace container {
 }  //namespace boost {
 
diff --git a/include/boost/container/detail/value_init.hpp b/include/boost/container/detail/value_init.hpp
index afbc9c1..f164d21 100644
--- a/include/boost/container/detail/value_init.hpp
+++ b/include/boost/container/detail/value_init.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/container/detail/variadic_templates_tools.hpp b/include/boost/container/detail/variadic_templates_tools.hpp
index f21f972..e24a2e0 100644
--- a/include/boost/container/detail/variadic_templates_tools.hpp
+++ b/include/boost/container/detail/variadic_templates_tools.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-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)
 //
diff --git a/include/boost/container/detail/version_type.hpp b/include/boost/container/detail/version_type.hpp
index 46344fa..aac704f 100644
--- a/include/boost/container/detail/version_type.hpp
+++ b/include/boost/container/detail/version_type.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp
index 45ab2f2..c444074 100644
--- a/include/boost/container/detail/workaround.hpp
+++ b/include/boost/container/detail/workaround.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -26,6 +26,11 @@
    #define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
 #endif
 
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
+    && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
+   #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
+#endif
+
 #include 
 
 #endif   //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp
index 2d4515b..f2b8e34 100644
--- a/include/boost/container/flat_map.hpp
+++ b/include/boost/container/flat_map.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -165,8 +165,13 @@ class flat_map
       get_flat_tree_iterators
          ::const_reverse_iterator                  const_reverse_iterator;
    typedef A                                                allocator_type;
+   
+   //!Standard extension
    typedef A                                                stored_allocator_type;
 
+   //!Standard extension for C++03 compilers with non-movable std::pair
+   typedef impl_value_type                                  movable_value_type;
+
    public:
    //! Effects: Default constructs an empty flat_map.
    //! 
@@ -209,23 +214,38 @@ class flat_map
    //! Effects: Copy constructs a flat_map.
    //! 
    //! Complexity: Linear in x.size().
-   flat_map(const flat_map& x) 
+   flat_map(const flat_map& x) 
       : m_flat_tree(x.m_flat_tree) {}
 
    //! Effects: Move constructs a flat_map.
    //!   Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    flat_map(BOOST_RV_REF(flat_map) x) 
       : m_flat_tree(boost::move(x.m_flat_tree))
    {}
 
+   //! Effects: Copy constructs a flat_map using the specified allocator.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_map(const flat_map& x, const allocator_type &a)
+      : m_flat_tree(x.m_flat_tree, a)
+   {}
+
+   //! Effects: Move constructs a flat_map using the specified allocator.
+   //!   Constructs *this using x's resources.
+   //! 
+   //! Complexity: Constant if x.get_allocator() == a, linear otherwise.
+   flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a) 
+      : m_flat_tree(boost::move(x.m_flat_tree), a)
+   {}
+
    //! Effects: Makes *this a copy of x.
    //! 
    //! Complexity: Linear in x.size().
-   flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
+   flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
    {  m_flat_tree = x.m_flat_tree;   return *this;  }
 
    //! Effects: Move constructs a flat_map.
@@ -234,7 +254,7 @@ class flat_map
    //! Complexity: Construct.
    //! 
    //! Postcondition: x is emptied.
-   flat_map& operator=(BOOST_RV_REF(flat_map) mx)
+   flat_map& operator=(BOOST_RV_REF(flat_map) mx)
    {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
 
    //! Effects: Returns the comparison object out
@@ -484,7 +504,7 @@ class flat_map
    //!   to the elements with bigger keys than x.
    //!
    //! Note: If an element is inserted it might invalidate elements.
-   std::pair insert(BOOST_RV_REF(impl_value_type) x) 
+   std::pair insert(BOOST_RV_REF(movable_value_type) x) 
    {
       return container_detail::force >
       (m_flat_tree.insert_unique(boost::move(x)));
@@ -515,8 +535,11 @@ class flat_map
    //!
    //! Note: If an element is inserted it might invalidate elements.
    iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
-      { return container_detail::force_copy
-         (m_flat_tree.insert_unique(container_detail::force(position), boost::move(container_detail::force(x)))); }
+   {
+      return container_detail::force_copy
+         (m_flat_tree.insert_unique( container_detail::force(position)
+                                   , boost::move(container_detail::force(x))));
+   }
 
    //! Effects: Inserts an element move constructed from x in the container.
    //!   p is a hint pointing to where the insert should start to search.
@@ -527,7 +550,7 @@ class flat_map
    //!   right before p) plus insertion linear to the elements with bigger keys than x.
    //!
    //! Note: If an element is inserted it might invalidate elements.
-   iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
+   iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
    {
       return container_detail::force_copy(
          m_flat_tree.insert_unique(container_detail::force(position), boost::move(x)));
@@ -704,13 +727,13 @@ class flat_map
    //!
    //! Complexity: Logarithmic
    std::pair equal_range(const key_type& x) 
-      {  return container_detail::force >(m_flat_tree.equal_range(x)); }
+      {  return container_detail::force_copy >(m_flat_tree.equal_range(x)); }
 
    //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
    //!
    //! Complexity: Logarithmic
    std::pair equal_range(const key_type& x) const 
-      {  return container_detail::force >(m_flat_tree.equal_range(x)); }
+      {  return container_detail::force_copy >(m_flat_tree.equal_range(x)); }
 
    //! Effects: Number of elements for which memory has been allocated.
    //!   capacity() is always greater than or equal to size().
@@ -916,6 +939,8 @@ class flat_multimap
    typedef A                                                allocator_type;
    //Non-standard extension
    typedef A                                                stored_allocator_type;
+   //!Standard extension for C++03 compilers with non-movable std::pair
+   typedef impl_value_type                                  movable_value_type;
 
    //! Effects: Default constructs an empty flat_map.
    //! 
@@ -960,28 +985,43 @@ class flat_multimap
    //! Effects: Copy constructs a flat_multimap.
    //! 
    //! Complexity: Linear in x.size().
-   flat_multimap(const flat_multimap& x) 
+   flat_multimap(const flat_multimap& x) 
       : m_flat_tree(x.m_flat_tree) { }
 
    //! Effects: Move constructs a flat_multimap. Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    flat_multimap(BOOST_RV_REF(flat_multimap) x) 
       : m_flat_tree(boost::move(x.m_flat_tree))
    { }
 
+   //! Effects: Copy constructs a flat_multimap using the specified allocator.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multimap(const flat_multimap& x, const allocator_type &a) 
+      : m_flat_tree(x.m_flat_tree, a)
+   {}
+
+   //! Effects: Move constructs a flat_multimap using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise.
+   flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a) 
+      : m_flat_tree(boost::move(x.m_flat_tree), a)
+   { }
+
    //! Effects: Makes *this a copy of x.
    //! 
    //! Complexity: Linear in x.size().
-   flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x) 
+   flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x) 
       {  m_flat_tree = x.m_flat_tree;   return *this;  }
 
    //! Effects: this->swap(x.get()).
    //! 
    //! Complexity: Constant.
-   flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx) 
+   flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx) 
       {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
 
    //! Effects: Returns the comparison object out
@@ -1359,14 +1399,14 @@ class flat_multimap
    //!
    //! Complexity: Logarithmic
    std::pair equal_range(const key_type& x) 
-      {  return container_detail::force_copy >(m_flat_tree.equal_range(x));   }
+      {  return container_detail::force >(m_flat_tree.equal_range(x));   }
 
    //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
    //!
    //! Complexity: Logarithmic
    std::pair 
       equal_range(const key_type& x) const 
-      {  return container_detail::force_copy >(m_flat_tree.equal_range(x));   }
+      {  return container_detail::force >(m_flat_tree.equal_range(x));   }
 
    //! Effects: Number of elements for which memory has been allocated.
    //!   capacity() is always greater than or equal to size().
diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp
index f367309..e10e7be 100644
--- a/include/boost/container/flat_set.hpp
+++ b/include/boost/container/flat_set.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -100,14 +100,14 @@ class flat_set
    typedef typename tree_t::allocator_type         allocator_type;
    typedef typename tree_t::stored_allocator_type  stored_allocator_type;
 
-   //! Effects: Defatuls constructs an empty flat_map.
+   //! Effects: Default constructs an empty flat_set.
    //! 
    //! Complexity: Constant.
    explicit flat_set()
       : m_flat_tree()
    {}
 
-   //! Effects: Constructs an empty flat_map using the specified
+   //! Effects: Constructs an empty flat_set using the specified
    //! comparison object and allocator.
    //! 
    //! Complexity: Constant.
@@ -116,7 +116,7 @@ class flat_set
       : m_flat_tree(comp, a)
    {}
 
-   //! Effects: Constructs an empty map using the specified comparison object and 
+   //! Effects: Constructs an empty set using the specified comparison object and 
    //! allocator, and inserts elements from the range [first ,last ).
    //! 
    //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
@@ -143,31 +143,47 @@ class flat_set
       : m_flat_tree(ordered_range, first, last, comp, a) 
    {}
 
-   //! Effects: Copy constructs a map.
+   //! Effects: Copy constructs a set.
    //! 
    //! Complexity: Linear in x.size().
-   flat_set(const flat_set& x) 
-      : m_flat_tree(x.m_flat_tree) {}
+   flat_set(const flat_set& x) 
+      : m_flat_tree(x.m_flat_tree)
+   {}
 
-   //! Effects: Move constructs a map. Constructs *this using x's resources.
+   //! Effects: Move constructs a set. Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    flat_set(BOOST_RV_REF(flat_set) mx) 
       : m_flat_tree(boost::move(mx.m_flat_tree))
    {}
 
-   //! Effects: Makes *this a copy of x.
+   //! Effects: Copy constructs a set using the specified allocator.
    //! 
    //! Complexity: Linear in x.size().
-   flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
-      {  m_flat_tree = x.m_flat_tree;   return *this;  }
+   flat_set(const flat_set& x, const allocator_type &a)
+      : m_flat_tree(x.m_flat_tree, a)
+   {}
+
+   //! Effects: Move constructs a set using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //! 
+   //! Complexity: Constant if a == mx.get_allocator(), linear otherwise
+   flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a) 
+      : m_flat_tree(boost::move(mx.m_flat_tree), a)
+   {}
 
    //! Effects: Makes *this a copy of x.
    //! 
    //! Complexity: Linear in x.size().
-   flat_set& operator=(BOOST_RV_REF(flat_set) mx)
+   flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
+      {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   //! Effects: Makes *this a copy of the previous value of xx.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_set& operator=(BOOST_RV_REF(flat_set) mx)
    {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
 
    //! Effects: Returns the comparison object out
@@ -729,7 +745,7 @@ class flat_multiset
    typedef typename tree_t::allocator_type         allocator_type;
    typedef typename tree_t::stored_allocator_type  stored_allocator_type;
 
-   //! Effects: Defatuls constructs an empty flat_map.
+   //! Effects: Default constructs an empty flat_multiset.
    //! 
    //! Complexity: Constant.
    explicit flat_multiset()
@@ -761,17 +777,47 @@ class flat_multiset
       : m_flat_tree(ordered_range, first, last, comp, a) 
    {}
 
-   flat_multiset(const flat_multiset& x) 
-      : m_flat_tree(x.m_flat_tree) {}
-
-   flat_multiset(BOOST_RV_REF(flat_multiset) x) 
-      : m_flat_tree(boost::move(x.m_flat_tree))
+   //! Effects: Copy constructs a flat_multiset.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multiset(const flat_multiset& x) 
+      : m_flat_tree(x.m_flat_tree)
    {}
 
-   flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x) 
+   //! Effects: Move constructs a flat_multiset. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Postcondition: x is emptied.
+   flat_multiset(BOOST_RV_REF(flat_multiset) mx) 
+      : m_flat_tree(boost::move(mx.m_flat_tree))
+   {}
+
+   //! Effects: Copy constructs a flat_multiset using the specified allocator.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multiset(const flat_multiset& x, const allocator_type &a)
+      : m_flat_tree(x.m_flat_tree, a)
+   {}
+
+   //! Effects: Move constructs a flat_multiset using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //! 
+   //! Complexity: Constant if a == mx.get_allocator(), linear otherwise
+   flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a) 
+      : m_flat_tree(boost::move(mx.m_flat_tree), a)
+   {}
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x) 
       {  m_flat_tree = x.m_flat_tree;   return *this;  }
 
-   flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) 
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) 
    {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
 
    //! Effects: Returns the comparison object out
diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp
index 6df999b..744ddff 100644
--- a/include/boost/container/list.hpp
+++ b/include/boost/container/list.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -65,30 +65,7 @@ template 
 struct list_node
    :  public list_hook::type
 {
-
-   list_node()
-      : m_data()
-   {}
-   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
-   template
-   list_node(Args &&...args)
-      : m_data(boost::forward(args)...)
-   {}
-
-   #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
-   #define BOOST_PP_LOCAL_MACRO(n)                                                           \
-   template                                                \
-   list_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                          \
-      : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                     \
-   {}                                                                                        \
-   //!
-   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-   #include BOOST_PP_LOCAL_ITERATE()
-
-   #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
+   typedef typename list_hook::type hook_type;
    T m_data;
 };
 
@@ -374,6 +351,34 @@ class list
       : AllocHolder(boost::move(static_cast(x)))
    {}
 
+   //! Effects: Copy constructs a list using the specified allocator.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocator_type's default constructor or copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   list(const list& x, const allocator_type &a) 
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), x.begin(), x.end());   }
+
+   //! Effects: Move constructor sing the specified allocator.
+   //!                 Moves mx's resources to *this.
+   //!
+   //! Throws: If allocation or value_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise.
+   list(BOOST_RV_REF(list) x, const allocator_type &a)
+      : AllocHolder(a)
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->icont().swap(x.icont());
+      }
+      else{
+         this->insert(this->cbegin(), x.begin(), x.end());
+      }
+   }
+
    //! Effects: Constructs a list that will use a copy of allocator a
    //!   and inserts a copy of the range [first, last) in the list.
    //!
diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp
index 8f7ecd4..25403e0 100644
--- a/include/boost/container/map.hpp
+++ b/include/boost/container/map.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -158,7 +158,7 @@ class map
       : m_tree(first, last, comp, a, true) 
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Constructs an empty map using the specified comparison object and 
@@ -175,29 +175,52 @@ class map
       : m_tree(ordered_range, first, last, comp, a) 
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Copy constructs a map.
    //! 
    //! Complexity: Linear in x.size().
-   map(const map& x) 
+   map(const map& x) 
       : m_tree(x.m_tree)
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Move constructs a map. Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    map(BOOST_RV_REF(map) x) 
       : m_tree(boost::move(x.m_tree))
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Copy constructs a map using the specified allocator.
+   //! 
+   //! Complexity: Linear in x.size().
+   map(const map& x, const allocator_type &a) 
+      : m_tree(x.m_tree, a)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Move constructs a map using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! Complexity: Constant if x == x.get_allocator(), linear otherwise.
+   //! 
+   //! Postcondition: x is emptied.
+   map(BOOST_RV_REF(map) x, const allocator_type &a) 
+      : m_tree(boost::move(x.m_tree), a)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Makes *this a copy of x.
@@ -833,7 +856,7 @@ class multimap
       : m_tree(comp, a)
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Constructs an empty multimap using the specified comparison object
@@ -848,7 +871,7 @@ class multimap
       : m_tree(first, last, comp, a, false) 
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Constructs an empty multimap using the specified comparison object and 
@@ -864,27 +887,48 @@ class multimap
       : m_tree(ordered_range, first, last, comp, a) 
    {}
 
-
    //! Effects: Copy constructs a multimap.
    //! 
    //! Complexity: Linear in x.size().
-   multimap(const multimap& x) 
+   multimap(const multimap& x) 
       : m_tree(x.m_tree)
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Move constructs a multimap. Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    multimap(BOOST_RV_REF(multimap) x) 
       : m_tree(boost::move(x.m_tree))
    {
       //Allocator type must be std::pair
-      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Copy constructs a multimap.
+   //! 
+   //! Complexity: Linear in x.size().
+   multimap(const multimap& x, const allocator_type &a) 
+      : m_tree(x.m_tree, a)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Move constructs a multimap using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise.
+   //! 
+   //! Postcondition: x is emptied.
+   multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
+      : m_tree(boost::move(x.m_tree), a)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
    }
 
    //! Effects: Makes *this a copy of x.
diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp
new file mode 100644
index 0000000..d9023f8
--- /dev/null
+++ b/include/boost/container/scoped_allocator.hpp
@@ -0,0 +1,1462 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if defined(BOOST_NO_VARIADIC_TEMPLATES)
+#include 
+#endif
+
+namespace boost { namespace container {
+
+#if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
+
+#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+template 
+class scoped_allocator_adaptor;
+
+#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+template 
+class scoped_allocator_adaptor;
+
+template 
+class scoped_allocator_adaptor;
+
+#endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+
+#else    // #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template 
+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{};
+
+//! A instance of type allocator_arg_t
+//!
+static const allocator_arg_t allocator_arg = allocator_arg_t();
+
+//! Remark: 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. 
+//!
+//! Requires: 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 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  > 
+//! struct constructible_with_allocator_suffix >  
+//!      : ::boost::true_type { };
+//! -- end example] 
+//!
+//! Note: 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 
+struct constructible_with_allocator_suffix
+   : ::boost::false_type
+{}; 
+
+//! Remark: 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.
+//!
+//! Requires: 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 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 Y(Args&& args...); 
+//!       template  
+//!       Y(allocator_arg_t, const allocator_type& a, Args&&... args); 
+//! }; 
+//!  
+//! // Specialize trait for class template Y 
+//! template  > 
+//! struct constructible_with_allocator_prefix >  
+//!       : ::boost::true_type { }; 
+//!  
+//! -- end example]
+//!
+//! Note: 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 
+struct constructible_with_allocator_prefix 
+    : ::boost::false_type
+{};
+
+///@cond
+
+namespace container_detail {
+
+template
+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 
+   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 
+   static int test(LowPriorityConversion, LowPriorityConversion);
+
+   static Alloc alloc;  // Declared but not defined
+
+   public:
+   enum { value = sizeof(test(0, alloc)) == sizeof(char) };
+};
+
+}  //namespace container_detail {
+
+///@endcond
+
+//! Remark: 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. 
+//!
+//! Result: derived from true_type if Convertible and 
+//! derived from false_type otherwise.
+template 
+struct uses_allocator
+   : boost::integral_constant::value>
+{};
+
+///@cond
+
+namespace container_detail {
+
+template 
+struct is_scoped_allocator_imp
+{
+   template 
+   static char test(int, typename T::outer_allocator_type*);
+
+   template 
+   static int test(LowPriorityConversion, void*);
+
+   static const bool value = (sizeof(char) == sizeof(test(0, 0)));
+};
+
+template::value >
+struct outermost_allocator_type_impl
+{
+   typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
+   typedef typename outermost_allocator_type_impl::type type;
+};
+
+template
+struct outermost_allocator_type_impl
+{
+   typedef MaybeScopedAlloc type;
+};
+
+template::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
+struct outermost_allocator_imp
+{
+   typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
+   typedef typename outermost_allocator_type_impl::type type;
+
+   static type &get(MaybeScopedAlloc &a)
+   {  return outermost_allocator_imp::get(a.outer_allocator());  }
+
+   static const type &get(const MaybeScopedAlloc &a)
+   {  return outermost_allocator_imp::get(a.outer_allocator());  }
+};
+
+}  //namespace container_detail {
+
+template 
+struct is_scoped_allocator
+   : boost::integral_constant::value>
+{};
+
+template 
+struct outermost_allocator
+   : container_detail::outermost_allocator_imp
+{};
+
+template 
+typename container_detail::outermost_allocator_imp::type &
+   get_outermost_allocator(Alloc &a)
+{  return container_detail::outermost_allocator_imp::get(a);   }
+
+template 
+const typename container_detail::outermost_allocator_imp::type &
+   get_outermost_allocator(const Alloc &a)
+{  return container_detail::outermost_allocator_imp::get(a);   }
+
+namespace container_detail {
+
+// Check if we can detect is_convertible using advanced SFINAE expressions
+#if !defined(BOOST_NO_SFINAE_EXPR)
+
+   //! 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
+   struct is_constructible_impl
+   {
+      typedef char yes_type;
+      struct no_type
+      { char padding[2]; };
+
+      template
+      struct dummy;
+
+      template
+      static yes_type test(dummy()...))>*);
+
+      template
+      static no_type test(...);
+
+      static const bool value = sizeof(test(0)) == sizeof(yes_type);
+   };
+
+   template
+   struct is_constructible
+      : boost::integral_constant::value>
+   {};
+
+   template 
+   struct is_constructible_with_allocator_prefix
+      : is_constructible
+   {};
+
+   #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
+   struct is_constructible_impl;
+
+   //Generate N specializations, from 0 to
+   //BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS parameters
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   template                                     \
+   struct is_constructible_impl                                                                    \
+                                                                                            \
+   {                                                                                               \
+      typedef char yes_type;                                                                       \
+      struct no_type                                                                               \
+      { char padding[2]; };                                                                        \
+                                                                                                   \
+      template                                                                      \
+      struct dummy;                                                                                \
+                                                                                                   \
+      template                                                                            \
+      static yes_type test(dummy*);    \
+                                                                                                   \
+      template                                                                            \
+      static no_type test(...);                                                                    \
+                                                                                                   \
+      static const bool value = sizeof(test(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 
+   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 
+   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
+   {};
+/*
+   template < class T, class InnerAlloc, class ...Args>
+   struct is_constructible_with_allocator_suffix
+      : constructible_with_allocator_suffix
+   {};*/
+
+   #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
+   {};
+/*
+   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
+   {};*/
+
+   #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::construct
+      ( outermost_alloc, p, allocator_arg, inner_alloc, ::boost::forward(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::construct
+      (outermost_alloc, p, ::boost::forward(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::value ||
+   //                     is_constructible_with_allocator_suffix::value ));
+   dispatch_allocator_prefix_suffix
+      ( is_constructible_with_allocator_prefix()
+      , outermost_alloc, inner_alloc, p, ::boost::forward(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::construct
+      (outermost_alloc, p, ::boost::forward(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::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::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::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 
+class scoped_allocator_adaptor_base
+   : public OuterAlloc
+{
+   typedef allocator_traits outer_traits_type;
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
+
+   public:
+   template 
+   struct rebind_base
+   {
+      typedef scoped_allocator_adaptor_base other;
+   };
+
+   typedef OuterAlloc outer_allocator_type;
+   typedef scoped_allocator_adaptor 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 
+   scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
+      : outer_allocator_type(::boost::forward(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 
+   scoped_allocator_adaptor_base
+      (const scoped_allocator_adaptor_base& other)
+      : outer_allocator_type(other.outer_allocator())
+      , inner(other.inner_allocator())
+      {}
+
+   template 
+   scoped_allocator_adaptor_base
+      (BOOST_RV_REF_BEG scoped_allocator_adaptor_base
+          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(*this); }
+
+   const outer_allocator_type &outer_allocator() const
+      { return static_cast(*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                                                                                                \
+class scoped_allocator_adaptor_base                                                                                            \
+   : public OuterAlloc                                                                          \
+{                                                                                               \
+   typedef allocator_traits outer_traits_type;                                      \
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)                                    \
+                                                                                                \
+   public:                                                                                      \
+   template                                                                      \
+   struct rebind_base                                                                           \
+   {                                                                                            \
+      typedef scoped_allocator_adaptor_base other;                                                                               \
+   };                                                                                           \
+                                                                                                \
+   typedef OuterAlloc outer_allocator_type;                                                     \
+   typedef scoped_allocator_adaptor 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                                                                      \
+   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(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                                                                      \
+   scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)                                                                              \
+      : outer_allocator_type(other.outer_allocator())                                           \
+      , inner(other.inner_allocator())                                                          \
+      {}                                                                                        \
+                                                                                                \
+   template                                                                      \
+   scoped_allocator_adaptor_base                                                                \
+      (BOOST_RV_REF_BEG scoped_allocator_adaptor_base 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(*this); }                                     \
+                                                                                                \
+   const outer_allocator_type &outer_allocator() const                                          \
+      { return static_cast(*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 
+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 
+   struct rebind_base
+   {
+      typedef scoped_allocator_adaptor_base
+         ::template portable_rebind_alloc::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         outer_traits_type;
+   typedef scoped_allocator_adaptor 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 
+   scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
+      : outer_allocator_type(::boost::forward(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 
+   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 
+   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(*this); }
+
+   inner_allocator_type const& inner_allocator() const
+      { return static_cast(*this); }
+
+   outer_allocator_type      & outer_allocator()
+      { return static_cast(*this); }
+
+   const outer_allocator_type &outer_allocator() const
+      { return static_cast(*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`.
+   //!
+   //! [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 
+   class scoped_allocator_adaptor
+
+   #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+   template 
+   class scoped_allocator_adaptor
+
+   #endif   // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template 
+class scoped_allocator_adaptor
+#endif
+   : public container_detail::scoped_allocator_adaptor_base
+         
+{
+   BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
+
+   public:
+   /// @cond
+   typedef container_detail::scoped_allocator_adaptor_base
+                             base_type;
+   /// @endcond
+   typedef OuterAlloc                                       outer_allocator_type;
+   //! Type: For exposition only
+   //!
+   typedef allocator_traits                     outer_traits_type;
+   //! Type: `scoped_allocator_adaptor` if `sizeof...(InnerAllocs)` is zero; otherwise,
+   //! `scoped_allocator_adaptor`.
+   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::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::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::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::type
+   //!      , InnerAllocs... >`
+   template 
+   struct rebind
+   {
+      typedef scoped_allocator_adaptor
+         < typename outer_traits_type::template portable_rebind_alloc::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(outerAlloc) and inner
+   //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the 
+   //! corresponding allocator from the argument list).
+   template 
+   scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
+      : base_type(::boost::forward(outerAlloc), innerAllocs...)
+      {}
+   #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                              \
+   template                                                                      \
+   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(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 
+   scoped_allocator_adaptor(const scoped_allocator_adaptor &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 
+   scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor 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(other));
+      return *this;
+   }
+
+   scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
+   {
+      base_type::operator=(boost::move(static_cast(other)));
+      return *this;
+   }
+
+   //! Returns:
+   //!   `static_cast(*this)`.
+   outer_allocator_type      & outer_allocator()
+      {  return *this; }
+
+   //! Returns:
+   //!   `static_cast(*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::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 
+   void destroy(T* p)
+   {
+      allocator_traits::type>
+         ::destroy(get_outermost_allocator(this->outer_allocator()), p);
+   }
+
+   //! Returns: 
+   //! `allocator_traits::allocate(outer_allocator(), n)`.
+   pointer allocate(size_type n)
+   {
+      return outer_traits_type::allocate(this->outer_allocator(), n);
+   }
+
+   //! Returns: 
+   //! `allocator_traits::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::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::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::value` is false calls
+   //!    `OUTERMOST_ALLOC_TRAITS(*this)::construct
+   //!       (OUTERMOST(*this), p, std::forward(args)...)`.
+   //! 
+   //! 2) Otherwise, if `uses_allocator::value` is true and 
+   //!    `is_constructible::value` is true, calls
+   //!    `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
+   //!    inner_allocator(), std::forward(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::value. -end note]
+   //!
+   //! 3) Otherwise, if uses_allocator::value is true and 
+   //!    `is_constructible::value` is true, calls 
+   //!    `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, 
+   //!    std::forward(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::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::value, void>::type
+   #endif
+   construct(T* p, BOOST_FWD_REF(Args)...args)
+   {
+      container_detail::dispatch_uses_allocator
+         ( uses_allocator()
+         , get_outermost_allocator(this->outer_allocator())
+         , this->inner_allocator()
+         , p, ::boost::forward(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::value, void>::type     \
+      construct(T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))               \
+   {                                                                                            \
+      container_detail::dispatch_uses_allocator                                                 \
+         ( uses_allocator()                                            \
+         , 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 
+   void construct(std::pair* p)
+   {  this->construct_pair(p);  }
+
+   template 
+   void construct(container_detail::pair* p)
+   {  this->construct_pair(p);  }
+
+   template 
+   void construct(std::pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+   {  this->construct_pair(p, ::boost::forward(x), ::boost::forward(y));   }
+
+   template 
+   void construct(container_detail::pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+   {  this->construct_pair(p, ::boost::forward(x), ::boost::forward(y));   }
+   
+   template 
+   void construct(std::pair* p, const std::pair& x)
+   {  this->construct_pair(p, x);   }
+
+   template 
+   void construct( container_detail::pair* p
+                 , const container_detail::pair& x)
+   {  this->construct_pair(p, x);   }
+   
+   template 
+   void construct( std::pair* p
+                 , BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END x)
+   {  this->construct_pair(p, x);   }
+
+   template 
+   void construct( container_detail::pair* p
+                 , BOOST_RV_REF_BEG container_detail::pair BOOST_RV_REF_END x)
+   {  this->construct_pair(p, x);   }
+
+   /// @cond
+   private:
+   template 
+   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 
+   void construct_pair(Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
+   {
+      this->construct(container_detail::addressof(p->first), ::boost::forward(x));
+      try {
+         this->construct(container_detail::addressof(p->second), ::boost::forward(y));
+      }
+      catch (...) {
+         this->destroy(container_detail::addressof(p->first));
+         throw;
+      }
+   }
+
+   template 
+   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 
+   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 
+   //void construct(pair* p, piecewise_construct_t, tuple x, tuple y);
+
+   /// @endcond
+};
+
+template 
+inline bool operator==(
+   const scoped_allocator_adaptor& a,
+   const scoped_allocator_adaptor& 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
+         ::value;
+   #endif
+
+    return a.outer_allocator() == b.outer_allocator()
+        && (has_zero_inner || a.inner_allocator() == b.inner_allocator());
+}
+
+template 
+inline bool operator!=(
+   const scoped_allocator_adaptor& a,
+   const scoped_allocator_adaptor& b)
+{
+    return ! (a == b);
+}
+
+}} // namespace boost { namespace container {
+
+#include 
+
+#endif //  BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp
index b25e701..ef3d989 100644
--- a/include/boost/container/set.hpp
+++ b/include/boost/container/set.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -144,16 +144,31 @@ class set
 
    //! Effects: Move constructs a set. Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    set(BOOST_RV_REF(set) x) 
       : m_tree(boost::move(x.m_tree))
    {}
 
-   //! Effects: Makes *this a copy of x.
+   //! Effects: Copy constructs a set using the specified allocator.
    //! 
    //! Complexity: Linear in x.size().
+   set(const set& x, const allocator_type &a) 
+      : m_tree(x.m_tree, a)
+   {}
+
+   //! Effects: Move constructs a set using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //!
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise.
+   set(BOOST_RV_REF(set) x, const allocator_type &a) 
+      : m_tree(boost::move(x.m_tree), a)
+   {}
+
+   //! Effects: Makes *this a copy of x.
+   //!
+   //! Complexity: Linear in x.size().
    set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
    {  m_tree = x.m_tree;   return *this;  }
 
@@ -716,13 +731,30 @@ class multiset
 
    //! Effects: Move constructs a multiset. Constructs *this using x's resources.
    //! 
-   //! Complexity: Construct.
+   //! Complexity: Constant.
    //! 
    //! Postcondition: x is emptied.
    multiset(BOOST_RV_REF(multiset) x) 
       : m_tree(boost::move(x.m_tree))
    {}
 
+   //! Effects: Copy constructs a multiset using the specified allocator.
+   //! 
+   //! Complexity: Linear in x.size().
+   multiset(const multiset& x, const allocator_type &a) 
+      : m_tree(x.m_tree, a)
+   {}
+
+   //! Effects: Move constructs a multiset using the specified allocator.
+   //!                 Constructs *this using x's resources.
+   //! 
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise.
+   //! 
+   //! Postcondition: x is emptied.
+   multiset(BOOST_RV_REF(multiset) x, const allocator_type &a) 
+      : m_tree(boost::move(x.m_tree), a)
+   {}
+
    //! Effects: Makes *this a copy of x.
    //! 
    //! Complexity: Linear in x.size().
diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp
index 1cdcdf1..70a2cbb 100644
--- a/include/boost/container/slist.hpp
+++ b/include/boost/container/slist.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
@@ -65,31 +65,7 @@ template 
 struct slist_node
    :  public slist_hook::type
 {
-
-   slist_node()
-      : m_data()
-   {}
-
-   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
-   template
-   slist_node(Args &&...args)
-      : m_data(boost::forward(args)...)
-   {}
-
-   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
-   #define BOOST_PP_LOCAL_MACRO(n)                                      \
-   template                           \
-   slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))       \
-      : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))   \
-   {}                                                                   \
-   //!
-   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-   #include BOOST_PP_LOCAL_ITERATE()
-
-   #endif//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
+   typedef typename slist_hook::type hook_type;
    T m_data;
 };
 
@@ -391,6 +367,34 @@ class slist
       : AllocHolder(boost::move(static_cast(x)))
    {}
 
+   //! Effects: Copy constructs a list using the specified allocator.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocator_type's default constructor or copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   slist(const slist& x, const allocator_type &a) 
+      : AllocHolder(a)
+   { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+
+   //! Effects: Move constructor using the specified allocator.
+   //!                 Moves x's resources to *this.
+   //!
+   //! Throws: If allocation or value_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise.
+   slist(BOOST_RV_REF(slist) x, const allocator_type &a)
+      : AllocHolder(a)
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->icont().swap(x.icont());
+      }
+      else{
+         this->insert(this->cbegin(), x.begin(), x.end());
+      }
+   }
+
    //! Effects: Makes *this contain the same elements as x.
    //!
    //! Postcondition: this->size() == x.size(). *this contains a copy 
diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp
index 851b5f2..3f29a86 100644
--- a/include/boost/container/stable_vector.hpp
+++ b/include/boost/container/stable_vector.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-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)
 //
@@ -34,7 +34,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include 
@@ -78,10 +78,6 @@ struct smart_ptr_type
    {  return ptr;}
 };
 
-template
-inline typename smart_ptr_type::pointer to_raw_pointer(const Ptr &ptr)
-{  return smart_ptr_type::get(ptr);   }
-
 template 
 class clear_on_destroy
 {
@@ -110,13 +106,10 @@ class clear_on_destroy
 
 template
 struct node_type_base
-{/*
-   node_type_base(VoidPtr p)
-      : up(p)
-   {}*/
+{
    node_type_base()
    {}
-   void set_pointer(VoidPtr p)
+   void set_pointer(const VoidPtr &p)
    {  up = p; }
 
    VoidPtr up;
@@ -126,33 +119,6 @@ template
 struct node_type
    : public node_type_base
 {
-   node_type()
-      : value()
-   {}
-
-   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
-   template
-   node_type(Args &&...args)
-      : value(boost::forward(args)...)
-   {}
-
-   #else //BOOST_CONTAINER_PERFECT_FORWARDING
-
-   #define BOOST_PP_LOCAL_MACRO(n)                                                           \
-   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
-   node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                             \
-      : value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                         \
-   {}                                                                                        \
-   //!
-   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-   #include BOOST_PP_LOCAL_ITERATE()
-
-   #endif//BOOST_CONTAINER_PERFECT_FORWARDING
-   
-   void set_pointer(VoidPointer p)
-   {  node_type_base::set_pointer(p); }
-
    T value;
 };
 
@@ -206,17 +172,17 @@ class iterator
    private:
    static node_type_ptr_t node_ptr_cast(const void_ptr &p)
    {
-      return node_type_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+      return node_type_ptr_t(static_cast(container_detail::to_raw_pointer(p)));
    }
 
    static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
    {
-      return const_node_type_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+      return const_node_type_ptr_t(static_cast(container_detail::to_raw_pointer(p)));
    }
 
    static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
    {
-      return void_ptr_ptr(static_cast(stable_vector_detail::to_raw_pointer(p)));
+      return void_ptr_ptr(static_cast(container_detail::to_raw_pointer(p)));
    }
 
    reference dereference() const
@@ -353,35 +319,37 @@ BOOST_JOIN(check_invariant_,__LINE__).touch();
 
 /// @endcond
 
-//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
-//!drop-in replacement implemented as a node container, offering iterator and reference
-//!stability.
+//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
+//! drop-in replacement implemented as a node container, offering iterator and reference
+//! stability.
 //!
-//!More details taken the author's blog: ( Introducing stable_vector)
+//! More details taken the author's blog:
+//! ( 
+//! Introducing stable_vector)
 //!
-//!We present stable_vector, a fully STL-compliant stable container that provides
-//!most of the features of std::vector except element contiguity. 
+//! We present stable_vector, a fully STL-compliant stable container that provides
+//! most of the features of std::vector except element contiguity. 
 //!
-//!General properties: stable_vector satisfies all the requirements of a container,
-//!a reversible container and a sequence and provides all the optional operations
-//!present in std::vector. Like std::vector,  iterators are random access.
-//!stable_vector does not provide element contiguity; in exchange for this absence,
-//!the container is stable, i.e. references and iterators to an element of a stable_vector
-//!remain valid as long as the element is not erased, and an iterator that has been
-//!assigned the return value of end() always remain valid until the destruction of
-//!the associated  stable_vector.
+//! General properties: stable_vector satisfies all the requirements of a container,
+//! a reversible container and a sequence and provides all the optional operations
+//! present in std::vector. Like std::vector,  iterators are random access.
+//! stable_vector does not provide element contiguity; in exchange for this absence,
+//! the container is stable, i.e. references and iterators to an element of a stable_vector
+//! remain valid as long as the element is not erased, and an iterator that has been
+//! assigned the return value of end() always remain valid until the destruction of
+//! the associated  stable_vector.
 //!
-//!Operation complexity: The big-O complexities of stable_vector operations match
-//!exactly those of std::vector. In general, insertion/deletion is constant time at
-//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
-//!does not internally perform any value_type destruction, copy or assignment
-//!operations other than those exactly corresponding to the insertion of new
-//!elements or deletion of stored elements, which can sometimes compensate in terms
-//!of performance for the extra burden of doing more pointer manipulation and an
-//!additional allocation per element.
+//! Operation complexity: The big-O complexities of stable_vector operations match
+//! exactly those of std::vector. In general, insertion/deletion is constant time at
+//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
+//! does not internally perform any value_type destruction, copy or assignment
+//! operations other than those exactly corresponding to the insertion of new
+//! elements or deletion of stored elements, which can sometimes compensate in terms
+//! of performance for the extra burden of doing more pointer manipulation and an
+//! additional allocation per element.
 //!
-//!Exception safety: As stable_vector does not internally copy elements around, some
-//!operations provide stronger exception safety guarantees than in std::vector:
+//! Exception safety: As stable_vector does not internally copy elements around, some
+//! operations provide stronger exception safety guarantees than in std::vector:
 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 template  >
 #else
@@ -524,7 +492,7 @@ class stable_vector
    //! Throws: If allocator_type's copy constructor throws.
    //! 
    //! Complexity: Constant.
-   explicit stable_vector(const A& al)
+   explicit stable_vector(const allocator_type& al)
       : internal_data(al),impl(al)
    {
       STABLE_VECTOR_CHECK_INVARIANT;
@@ -538,7 +506,7 @@ class stable_vector
    //! 
    //! Complexity: Linear to n.
    explicit stable_vector(size_type n)
-      : internal_data(A()),impl(A())
+      : internal_data(),impl()
    {
       stable_vector_detail::clear_on_destroy cod(*this);
       this->resize(n);
@@ -553,7 +521,7 @@ class stable_vector
    //!   throws or T's default or copy constructor throws.
    //! 
    //! Complexity: Linear to n.
-   stable_vector(size_type n, const T& t, const A& al=A())
+   stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
       : internal_data(al),impl(al)
    {
       stable_vector_detail::clear_on_destroy cod(*this);
@@ -570,7 +538,7 @@ class stable_vector
    //!
    //! Complexity: Linear to the range [first, last).
    template 
-   stable_vector(InputIterator first,InputIterator last,const A& al=A())
+   stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
       : internal_data(al),impl(al)
    {
       stable_vector_detail::clear_on_destroy cod(*this);
@@ -607,6 +575,40 @@ class stable_vector
       this->priv_swap_members(x);
    }
 
+   //! Effects: Copy constructs a stable_vector using the specified allocator.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   stable_vector(const stable_vector& x, const allocator_type &a)
+      : internal_data(a), impl(a)
+   {
+      stable_vector_detail::clear_on_destroy cod(*this);
+      this->insert(this->cbegin(), x.begin(), x.end());
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! Effects: Move constructor using the specified allocator.
+   //!                 Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant if a == x.get_allocator(), linear otherwise
+   stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
+      : internal_data(a), impl(a)
+   {
+      if(this->node_alloc() == x.node_alloc()){
+         this->priv_swap_members(x);
+      }
+      else{
+         stable_vector_detail::clear_on_destroy cod(*this);
+         this->insert(this->cbegin(), x.begin(), x.end());
+         STABLE_VECTOR_CHECK_INVARIANT;
+         cod.release();
+      }
+   }
+
    //! Effects: Destroys the stable_vector. All stored values are destroyed
    //!   and used memory is deallocated.
    //!
@@ -709,7 +711,7 @@ class stable_vector
    //! Throws: If allocator's copy constructor throws.
    //! 
    //! Complexity: Constant.
-   allocator_type get_allocator()const  {return node_alloc();}
+   allocator_type get_allocator()const  {return this->node_alloc();}
 
    //! Effects: Returns a reference to the internal allocator.
    //! 
@@ -1137,7 +1139,7 @@ class stable_vector
    void emplace_back(Args &&...args)
    {
       typedef emplace_functor         EmplaceFunctor;
-      typedef emplace_iterator EmplaceIterator;
+      typedef emplace_iterator EmplaceIterator;
       EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...);
       this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
    }
@@ -1157,7 +1159,7 @@ class stable_vector
       //Just call more general insert(pos, size, value) and return iterator
       size_type pos_n = position - cbegin();
       typedef emplace_functor         EmplaceFunctor;
-      typedef emplace_iterator EmplaceIterator;
+      typedef emplace_iterator EmplaceIterator;
       EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...);
       this->insert(position, EmplaceIterator(ef), EmplaceIterator());
       return iterator(this->begin() + pos_n);
@@ -1172,7 +1174,7 @@ class stable_vector
       typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                               \
          BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >)               \
             EmplaceFunctor;                                                                     \
-      typedef emplace_iterator  EmplaceIterator;  \
+      typedef emplace_iterator  EmplaceIterator;   \
       EmplaceFunctor ef BOOST_PP_LPAREN_IF(n)                                                   \
                         BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)                   \
                         BOOST_PP_RPAREN_IF(n);                                                  \
@@ -1186,7 +1188,7 @@ class stable_vector
       typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                               \
          BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >)               \
             EmplaceFunctor;                                                                     \
-      typedef emplace_iterator  EmplaceIterator;  \
+      typedef emplace_iterator  EmplaceIterator;   \
       EmplaceFunctor ef BOOST_PP_LPAREN_IF(n)                                                   \
                         BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)                   \
                         BOOST_PP_RPAREN_IF(n);                                                  \
@@ -1482,12 +1484,12 @@ class stable_vector
 
    static node_type_ptr_t node_ptr_cast(const void_ptr &p)
    {
-      return node_type_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+      return node_type_ptr_t(static_cast(container_detail::to_raw_pointer(p)));
    }
 
    static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
    {
-      return node_type_base_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+      return node_type_base_ptr_t(static_cast(container_detail::to_raw_pointer(p)));
    }
 
    static value_type& value(const void_ptr &p)
@@ -1529,7 +1531,9 @@ class stable_vector
    {
       node_type_ptr_t p = this->allocate_one();
       try{
-         boost::container::construct_in_place(this->node_alloc(), &*p, it);
+         boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), it);
+         //This does not throw
+         ::new(static_cast(container_detail::to_raw_pointer(p))) node_type_base_t;
          p->set_pointer(up);
       }
       catch(...){
@@ -1621,7 +1625,9 @@ class stable_vector
             p = mem.front();
             mem.pop_front();
             //This can throw
-            boost::container::construct_in_place(this->node_alloc(), &*p, first);
+            boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+            //This does not throw
+            ::new(static_cast(container_detail::to_raw_pointer(p))) node_type_base_t;
             p->set_pointer(void_ptr_ptr(&it[i]));
             ++first;
             it[i] = p;
@@ -1650,7 +1656,9 @@ class stable_vector
                break;
             }
             //This can throw
-            boost::container::construct_in_place(this->node_alloc(), &*p, first);
+            boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+            //This does not throw
+            ::new(static_cast(container_detail::to_raw_pointer(p))) node_type_base_t;
             p->set_pointer(void_ptr_ptr(&it[i]));
             ++first;
             it[i]=p;
diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp
index 3a9c55a..5821f02 100644
--- a/include/boost/container/string.hpp
+++ b/include/boost/container/string.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -43,7 +43,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -620,12 +620,12 @@ class basic_string
    //!
    //! Postcondition: x == *this.
    //! 
-   //! Throws: If allocator_type's default constructor or copy constructor throws.
+   //! Throws: If allocator_type's default constructor throws.
    basic_string(const basic_string& s) 
       :  base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
    { this->priv_range_initialize(s.begin(), s.end()); }
 
-   //! Effects: Move constructor. Moves mx's resources to *this.
+   //! Effects: Move constructor. Moves s's resources to *this.
    //!
    //! Throws: If allocator_type's copy constructor throws.
    //! 
@@ -634,6 +634,32 @@ class basic_string
       : base_t(boost::move((base_t&)s))
    {}
 
+   //! Effects: Copy constructs a basic_string using the specified allocator.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocation throws.
+   basic_string(const basic_string& s, const allocator_type &a) 
+      :  base_t(a)
+   { this->priv_range_initialize(s.begin(), s.end()); }
+
+   //! Effects: Move constructor using the specified allocator.
+   //!                 Moves s's resources to *this.
+   //!
+   //! Throws: If allocation throws.
+   //! 
+   //! Complexity: Constant if a == s.get_allocator(), linear otherwise.
+   basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a) 
+      : base_t(a)
+   {
+      if(a == this->alloc()){
+         this->swap_data(s);
+      }
+      else{
+         this->priv_range_initialize(s.begin(), s.end());
+      }
+   }
+
    //! Effects: Constructs a basic_string taking the allocator as parameter,
    //!   and is initialized by a specific number of characters of the s string. 
    basic_string(const basic_string& s, size_type pos, size_type n = npos,
diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp
index 742d00d..6b590fb 100644
--- a/include/boost/container/vector.hpp
+++ b/include/boost/container/vector.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -38,7 +38,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace boost {
 namespace container {
@@ -540,6 +541,40 @@ class vector : private container_detail::vector_alloc_holder
       :  base_t(boost::move(mx.alloc()))
    {  this->swap_members(mx);   }
 
+   //! Effects: Copy constructs a vector using the specified allocator.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocation
+   //!   throws or T's copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   vector(const vector &x, const allocator_type &a) 
+      :  base_t(a)
+   {
+      this->assign( container_detail::to_raw_pointer(x.members_.m_start)
+                  , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
+   }
+
+   //! Effects: Move constructor using the specified allocator.
+   //!                 Moves mx's resources to *this if a == allocator_type().
+   //!                 Otherwise copies values from x to *this.
+   //!
+   //! Throws: If allocation or T's copy constructor throws.
+   //! 
+   //! Complexity: Constant if a == mx.get_allocator(), linear otherwise.
+   vector(BOOST_RV_REF(vector) mx, const allocator_type &a)
+      :  base_t(a)
+   {
+      if(mx.alloc() == a){
+         this->swap_members(mx);
+      }
+      else{
+         this->assign( container_detail::to_raw_pointer(mx.members_.m_start)
+                     , container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size));
+      }
+   }
+
    //! Effects: Constructs a vector that will use a copy of allocator a
    //!   and inserts a copy of the range [first, last) in the vector.
    //!
@@ -1428,6 +1463,146 @@ class vector : private container_detail::vector_alloc_holder
       }
    }
 
+   public:
+   //Absolutely experimental. This function might change, disappear or simply crash!
+   template
+   void insert_ordered_at(size_type element_count, BiDirPosIt last_position_it, BiDirValueIt last_value_it)
+   {
+      const size_type old_size_pos = this->size();
+      this->reserve(old_size_pos + element_count);
+      T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
+      size_type insertions_left = element_count;
+      size_type next_pos = old_size_pos;
+      size_type hole_size = element_count;
+
+      //Exception rollback. If any copy throws before the hole is filled, values
+      //already inserted/copied at the end of the buffer will be destroyed.
+      typename value_traits::ArrayDestructor past_hole_values_destroyer
+         (begin_ptr + old_size_pos + element_count, this->alloc(), size_type(0u));
+      //Loop for each insertion backwards, first moving the elements after the insertion point,
+      //then inserting the element.
+      while(insertions_left){
+         const size_type pos = static_cast(*(--last_position_it));
+         BOOST_ASSERT(pos <= old_size_pos);
+         //Shift the range after the insertion point, function will take care if the shift
+         //crosses the size() boundary, using copy/move or uninitialized copy/move if necessary.
+         size_type new_hole_size = insert_ordered_at_shift_range(pos, next_pos, this->size(), insertions_left);
+         if(new_hole_size > 0){
+            //The hole was reduced by insert_ordered_at_shift_range so expand exception rollback range backwards
+            past_hole_values_destroyer.increment_size_backwards(next_pos - pos);
+            //Insert the new value in the hole
+            allocator_traits_type::construct(this->alloc(), begin_ptr + pos + insertions_left - 1, *(--last_value_it));
+            --new_hole_size;
+            if(new_hole_size == 0){
+               //Hole was just filled, disable exception rollback and change vector size
+               past_hole_values_destroyer.release();
+               this->members_.m_size += element_count;
+            }
+            else{
+               //The hole was reduced by the new insertion by one
+               past_hole_values_destroyer.increment_size_backwards(size_type(1u));
+            }
+         }
+         else{
+            if(hole_size){
+               //Hole was just filled by insert_ordered_at_shift_range, disable exception rollback and change vector size
+               past_hole_values_destroyer.release();
+               this->members_.m_size += element_count;
+            }
+            //Insert the new value in the already constructed range
+            begin_ptr[pos + insertions_left - 1] = *(--last_value_it);
+         }
+         --insertions_left;
+         hole_size = new_hole_size;
+         next_pos = pos;
+      }
+   }
+
+   //Takes the range pointed by [first_pos, last_pos) and shifts it to the right
+   //by 'shift_count'. 'limit_pos' marks the end of constructed elements.
+   //
+   //Precondition: first_pos <= last_pos <= limit_pos
+   //
+   //The shift operation might cross limit_pos so elements to moved beyond limit_pos
+   //are uninitialized_moved with an allocator. Other elements are moved.
+   //
+   //The shift operation might left uninitialized elements after limit_pos
+   //and the number of uninitialized elements is returned by the function.
+   //
+   //Old situation:
+   //       first_pos   last_pos         old_limit
+   //             |       |                  |  
+   // ____________V_______V__________________V_____________
+   //|   prefix   | range |     suffix       |raw_mem      ~
+   //|____________|_______|__________________|_____________~
+   //
+   //New situation in Case A (hole_size == 0):
+   // range is moved through move assignments
+   //
+   //       first_pos   last_pos         old_limit
+   //             |       |                  |  
+   // ____________V_______V__________________V_____________
+   //|   prefix'  |       |  | range |suffix'|raw_mem      ~
+   //|________________+______|___^___|_______|_____________~
+   //                 |          |
+   //                 |_>_>_>_>_>^                     
+   //
+   //
+   //New situation in Case B (hole_size >= 0):
+   // range is moved through uninitialized moves
+   //
+   //       first_pos   last_pos         old_limit
+   //             |       |                  |  
+   // ____________V_______V__________________V________________ 
+   //|    prefix' |       |                  | [hole] | range |
+   //|_______________________________________|________|___^___|
+   //                 |                                   |
+   //                 |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^
+   //
+   //New situation in Case C (hole_size == 0):
+   // range is moved through move assignments and uninitialized moves
+   //
+   //       first_pos   last_pos         old_limit
+   //             |       |                  |  
+   // ____________V_______V__________________V___ 
+   //|   prefix'  |       |              | range |
+   //|___________________________________|___^___|
+   //                 |                      |
+   //                 |_>_>_>_>_>_>_>_>_>_>_>^
+   size_type insert_ordered_at_shift_range(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
+   {
+      BOOST_ASSERT(first_pos <= last_pos);
+      BOOST_ASSERT(last_pos <= limit_pos);
+      //
+      T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
+
+      size_type hole_size = 0;
+      //Case A:
+      if((last_pos + shift_count) <= limit_pos){
+         //All move assigned
+         boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count);
+      }
+      //Case B:
+      else if((first_pos + shift_count) >= limit_pos){
+         //All uninitialized_moved
+         ::boost::container::uninitialized_move_alloc
+            (this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count);
+         hole_size = last_pos + shift_count - limit_pos;
+      }
+      //Case C:
+      else{
+         //Some uninitialized_moved
+         T* const limit_ptr    = begin_ptr + limit_pos;
+         T* const boundary_ptr = limit_ptr - shift_count;
+         ::boost::container::uninitialized_move_alloc
+            (this->alloc(), boundary_ptr, begin_ptr + last_pos, limit_ptr);
+         //The rest is move assigned
+         boost::move_backward(begin_ptr + first_pos, boundary_ptr, limit_ptr + shift_count);
+      }
+      return hole_size;
+   }
+
+   private:
    void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
    {
       //n can't be 0, because there is nothing to do in that case
diff --git a/index.html b/index.html
index ad39f65..1251783 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,5 @@
 
diff --git a/proj/to-do.txt b/proj/to-do.txt
index d82bd8a..1152393 100644
--- a/proj/to-do.txt
+++ b/proj/to-do.txt
@@ -1,10 +1,10 @@
 ->Change "insert" and "push_back"/"push_front" to catch non-const rvalues
 ->Add an example with stateful allocators
 ->Add test to check convertible types in push_back/insert
+->Add SCARY iterators.
 
 
 Review allocator traits
--> Explicit instantiation of simple allocator & std::allocator to detect missing allocator_traits calls
 -> Avoid any rebind<>::other
 -> Review select_on_container_copy_xxx
 -> Review propagate_on_xxx
@@ -12,13 +12,13 @@ Review allocator traits
 -> Default + swap move constructors correct?
 -> Review container documentation in swap/copy/move regarding allocators
 
-Check all move constructors: swap might not be a valid idiom, allocators must be move constructed, intrusive containers are now movable
+Check all move constructors: swap might not be a valid idiom, allocators must be move constructed,
+intrusive containers are now movable
 
 Add and test:
 
 Test different propagation values and with inequal allocators
 
-
 propagate_on_container_move_assignment
 select_on_container_copy_construction
 propagate_on_container_swap
@@ -28,19 +28,12 @@ Test move constructors with data values and unequal allocators
 
 An allocator should use a smart allocator not constructible from raw pointers to catch missing pointer_traits calls
 
-Review all internal container swap's to check allocator propagation is correct
-
 Add initializer lists
 
 Write forward_list
 
-Review all move constructors to test if allocator is move constructed
-
 check move if noexcept conditions in vector, deque and stable_vector
 
-Add new allocator propagation copy constructors
+Detect always equal or unequal allocators at compiler time. operator== returns true_type or false_type
 
-Review all destructors (search for "~") to detect placement destruction and replace it with allocator_traits::destroy
-
-All functions from base classes like vector_base, node_alloc_holder, etc., should be named with underscore or
-similar to avoid namespace pollution.
\ No newline at end of file
+change virtual functions with pointers to avoid template instantiation for every type
\ No newline at end of file
diff --git a/proj/vc7ide/container.sln b/proj/vc7ide/container.sln
index 38cb19d..591f0fc 100644
--- a/proj/vc7ide/container.sln
+++ b/proj/vc7ide/container.sln
@@ -43,6 +43,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_test.vcpr
 	ProjectSection(ProjectDependencies) = postProject
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_adaptor_test", "scoped_allocator_adaptor.vcproj", "{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_usage_test", "scoped_allocator_usage_test.vcproj", "{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfiguration) = preSolution
 		Debug = Debug
@@ -95,6 +103,14 @@ Global
 		{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
 		{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
 		{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.ActiveCfg = Debug|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.ActiveCfg = Debug|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
+		{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	EndGlobalSection
diff --git a/proj/vc7ide/container.vcproj b/proj/vc7ide/container.vcproj
index 7588d88..50610a6 100644
--- a/proj/vc7ide/container.vcproj
+++ b/proj/vc7ide/container.vcproj
@@ -179,6 +179,9 @@
 		
+			
+			
 			
 			
@@ -197,6 +200,9 @@
 			
 			
+			
+			
 			
 			
@@ -215,19 +221,6 @@
 			
 			
-			
-				
-				
-				
-				
-				
-				
-			
 			
@@ -264,6 +257,9 @@
 				
 				
+				
+				
 				
 				
diff --git a/proj/vc7ide/scoped_allocator_adaptor.vcproj b/proj/vc7ide/scoped_allocator_adaptor.vcproj
new file mode 100644
index 0000000..f38106c
--- /dev/null
+++ b/proj/vc7ide/scoped_allocator_adaptor.vcproj
@@ -0,0 +1,139 @@
+
+
+	
+		
+	
+	
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+	
+	
+	
+	
+		
+			
+			
+		
+		
+		
+	
+	
+	
+
diff --git a/proj/vc7ide/scoped_allocator_usage_test.vcproj b/proj/vc7ide/scoped_allocator_usage_test.vcproj
new file mode 100644
index 0000000..a19b214
--- /dev/null
+++ b/proj/vc7ide/scoped_allocator_usage_test.vcproj
@@ -0,0 +1,139 @@
+
+
+	
+		
+	
+	
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+	
+	
+	
+	
+		
+			
+			
+		
+		
+		
+	
+	
+	
+
diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp
index 36e5a9e..65ce8f3 100644
--- a/test/allocator_traits_test.cpp
+++ b/test/allocator_traits_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
+// (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)
 //
@@ -9,7 +9,7 @@
 //////////////////////////////////////////////////////////////////////////////
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
diff --git a/test/deque_test.cpp b/test/deque_test.cpp
index bc8bf9e..7190e0a 100644
--- a/test/deque_test.cpp
+++ b/test/deque_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp
index 719d0ca..394b5a9 100644
--- a/test/dummy_test_allocator.hpp
+++ b/test/dummy_test_allocator.hpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -112,10 +112,10 @@ class dummy_test_allocator
    {}
 
    pointer address(reference value) 
-   {  return pointer(addressof(value));  }
+   {  return pointer(container_detail::addressof(value));  }
 
    const_pointer address(const_reference value) const
-   {  return const_pointer(addressof(value));  }
+   {  return const_pointer(container_detail::addressof(value));  }
 
    pointer allocate(size_type, cvoid_ptr = 0)
    {  return 0; }
diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp
index 67aea9d..3f499d2 100644
--- a/test/expand_bwd_test_allocator.hpp
+++ b/test/expand_bwd_test_allocator.hpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
@@ -86,10 +86,10 @@ class expand_bwd_test_allocator
       , m_offset(other.m_offset),  m_allocations(0){ }
 
    pointer address(reference value)
-   {  return pointer(addressof(value));  }
+   {  return pointer(container_detail::addressof(value));  }
 
    const_pointer address(const_reference value) const
-   {  return const_pointer(addressof(value));  }
+   {  return const_pointer(container_detail::addressof(value));  }
 
    pointer allocate(size_type , cvoid_ptr hint = 0)
    {  (void)hint; return 0; }
diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp
index 4203704..645a124 100644
--- a/test/flat_tree_test.cpp
+++ b/test/flat_tree_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
@@ -228,17 +228,17 @@ class recursive_flat_multiset
 {
    public:
    recursive_flat_multiset(const recursive_flat_multiset &c)
-      : id_(c.id_), flat_set_(c.flat_set_)
+      : id_(c.id_), flat_multiset_(c.flat_multiset_)
    {}
 
    recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
    {
       id_ = c.id_;
-      flat_set_= c.flat_set_;
+      flat_multiset_= c.flat_multiset_;
       return *this;
    }
    int id_;
-   flat_multiset flat_set_;
+   flat_multiset flat_multiset_;
    friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
    {  return a.id_ < b.id_;   }
 };
diff --git a/test/heap_allocator_v1.hpp b/test/heap_allocator_v1.hpp
index 32b46b5..10437b5 100644
--- a/test/heap_allocator_v1.hpp
+++ b/test/heap_allocator_v1.hpp
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-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)
 //
diff --git a/test/list_test.cpp b/test/list_test.cpp
index 602f547..b3fe6b2 100644
--- a/test/list_test.cpp
+++ b/test/list_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/map_test.hpp b/test/map_test.hpp
index 5eee229..45efc31 100644
--- a/test/map_test.hpp
+++ b/test/map_test.hpp
@@ -387,10 +387,17 @@ int map_test ()
                return 1;
             if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
                return 1;
-            {
-               IntType i1(i);
-               IntType i2(i);
-               new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+            {  //Check equal_range
+               std::pair bret =
+                  boostmultimap->equal_range(boostmultimap->begin()->first);
+
+               std::pair   sret =
+                  stdmultimap->equal_range(stdmultimap->begin()->first);
+         
+               if( std::distance(bret.first, bret.second) !=
+                   std::distance(sret.first, sret.second) ){
+                  return 1;
+               }
             }
             {
                IntType i1(i);
diff --git a/test/pair_test.cpp b/test/pair_test.cpp
index c44b9d5..6b75b01 100644
--- a/test/pair_test.cpp
+++ b/test/pair_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
+// (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)
 //
diff --git a/test/print_container.hpp b/test/print_container.hpp
index 9300c3c..f34a9f3 100644
--- a/test/print_container.hpp
+++ b/test/print_container.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/scoped_allocator_adaptor_test.cpp b/test/scoped_allocator_adaptor_test.cpp
new file mode 100644
index 0000000..cecfade
--- /dev/null
+++ b/test/scoped_allocator_adaptor_test.cpp
@@ -0,0 +1,1404 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace boost::container;
+
+
+template
+class test_allocator
+{
+   BOOST_COPYABLE_AND_MOVABLE(test_allocator)
+   public:
+
+   template
+   struct rebind
+   {
+      typedef test_allocator other;
+   };
+
+   typedef container_detail::bool_  propagate_on_container_copy_assignment;
+   typedef container_detail::bool_  propagate_on_container_move_assignment;
+   typedef container_detail::bool_  propagate_on_container_swap;
+   typedef T value_type;
+
+   test_allocator()
+   {}
+
+   test_allocator(const test_allocator&)
+   {}
+
+   test_allocator(BOOST_RV_REF(test_allocator) )
+   {}
+
+   template
+   test_allocator(BOOST_RV_REF_BEG test_allocator BOOST_RV_REF_END)
+   {}
+
+   template
+   test_allocator(const test_allocator &)
+   {}
+
+   test_allocator & operator=(BOOST_COPY_ASSIGN_REF(test_allocator))
+   {  return *this;  }
+
+   test_allocator & operator=(BOOST_RV_REF(test_allocator))
+   {  return *this;  }
+
+   std::size_t max_size() const
+   {  return std::size_t(Id);  }
+
+   T* allocate(std::size_t n)
+   {  return (T*)::new char[n*sizeof(T)];  }
+
+   void deallocate(T*p, std::size_t)
+   {  delete []static_cast(static_cast(p));  }
+};
+
+template 
+bool operator==( const test_allocator&
+               , const test_allocator&)
+{  return true;   }
+
+template 
+bool operator!=( const test_allocator&
+               , const test_allocator&)
+{  return false;   }
+
+
+template
+struct tagged_integer
+{};
+
+struct mark_on_destructor
+{
+   mark_on_destructor()
+      : destroyed(false)
+   {}
+
+   ~mark_on_destructor()
+   {
+      destroyed = true;
+   }
+
+   bool destroyed;
+};
+
+//This enum lists the construction options
+//for an allocator-aware type
+enum ConstructionTypeEnum
+{
+   ConstructiblePrefix,
+   ConstructibleSuffix,
+   NotUsesAllocator,
+};
+
+//This base class provices types for
+//the derived class to implement each construction
+//type. If a construction type does not apply
+//the typedef is set to an internal nat
+//so that the class is not constructible from
+//the user arguments.
+template
+struct uses_allocator_base;
+
+template
+struct uses_allocator_base
+{
+   typedef test_allocator allocator_type;
+   typedef allocator_type allocator_constructor_type;
+   struct nat{};
+   typedef nat allocator_arg_type;
+};
+
+template
+struct uses_allocator_base
+{
+   typedef test_allocator allocator_type;
+   typedef allocator_type allocator_constructor_type;
+   typedef allocator_arg_t allocator_arg_type;
+};
+
+template
+struct uses_allocator_base
+{
+   struct nat{};
+   typedef nat allocator_constructor_type;
+   typedef nat allocator_arg_type;
+};
+
+template
+struct mark_on_scoped_allocation
+   : uses_allocator_base
+{
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(mark_on_scoped_allocation)
+
+   public:
+
+   typedef uses_allocator_base base_type;
+
+   //0 user argument constructors
+   mark_on_scoped_allocation()
+      : construction_type(NotUsesAllocator), value(0)
+   {}
+
+   explicit mark_on_scoped_allocation
+      (typename base_type::allocator_constructor_type)
+      : construction_type(ConstructibleSuffix), value(0)
+   {}
+
+   explicit mark_on_scoped_allocation
+      (typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type)
+      : construction_type(ConstructiblePrefix), value(0)
+   {}
+
+   //1 user argument constructors
+   explicit mark_on_scoped_allocation(int i)
+      : construction_type(NotUsesAllocator), value(i)
+   {}
+
+   mark_on_scoped_allocation
+      (int i, typename base_type::allocator_constructor_type)
+      : construction_type(ConstructibleSuffix), value(i)
+   {}
+
+   mark_on_scoped_allocation
+      ( typename base_type::allocator_arg_type
+      , typename base_type::allocator_constructor_type
+      , int i)
+      : construction_type(ConstructiblePrefix), value(i)
+   {}
+
+   //Copy constructors
+   mark_on_scoped_allocation(const mark_on_scoped_allocation &other)
+      : construction_type(NotUsesAllocator), value(other.value)
+   {}
+
+   mark_on_scoped_allocation( const mark_on_scoped_allocation &other
+                            , typename base_type::allocator_constructor_type)
+      : construction_type(ConstructibleSuffix), value(other.value)
+   {}
+
+   mark_on_scoped_allocation( typename base_type::allocator_arg_type
+                            , typename base_type::allocator_constructor_type
+                            , const mark_on_scoped_allocation &other)
+      : construction_type(ConstructiblePrefix), value(other.value)
+   {}
+
+   //Move constructors
+   mark_on_scoped_allocation(BOOST_RV_REF(mark_on_scoped_allocation) other)
+      : construction_type(NotUsesAllocator), value(other.value)
+   {  other.value = 0;  other.construction_type = NotUsesAllocator;  }
+
+   mark_on_scoped_allocation( BOOST_RV_REF(mark_on_scoped_allocation) other
+                            , typename base_type::allocator_constructor_type)
+      : construction_type(ConstructibleSuffix), value(other.value)
+   {  other.value = 0;  other.construction_type = ConstructibleSuffix;  }
+
+   mark_on_scoped_allocation( typename base_type::allocator_arg_type
+                            , typename base_type::allocator_constructor_type
+                            , BOOST_RV_REF(mark_on_scoped_allocation) other)
+      : construction_type(ConstructiblePrefix), value(other.value)
+   {  other.value = 0;  other.construction_type = ConstructiblePrefix;  }
+
+   ConstructionTypeEnum construction_type;
+   int                  value;
+};
+
+namespace boost {
+namespace container {
+
+template
+struct constructible_with_allocator_prefix
+   < ::mark_on_scoped_allocation >
+   : ::boost::true_type
+{};
+
+template
+struct constructible_with_allocator_suffix
+   < ::mark_on_scoped_allocation >
+   : ::boost::true_type
+{};
+
+}  //namespace container {
+}  //namespace boost {
+
+
+int main()
+{
+   typedef test_allocator, 0>   OuterAlloc;
+   typedef test_allocator, 10>  Outer10IdAlloc;
+   typedef test_allocator, 0>   Rebound9OuterAlloc;
+   typedef test_allocator, 1>   InnerAlloc1;
+   typedef test_allocator, 2>   InnerAlloc2;
+   typedef test_allocator, 11>  Inner11IdAlloc1;
+   typedef test_allocator, 12>  Inner12IdAlloc2;
+
+   typedef test_allocator, 0, false>      OuterAllocFalsePropagate;
+   typedef test_allocator, 0, true>       OuterAllocTruePropagate;
+   typedef test_allocator, 1, false>      InnerAlloc1FalsePropagate;
+   typedef test_allocator, 1, true>       InnerAlloc1TruePropagate;
+   typedef test_allocator, 2, false>      InnerAlloc2FalsePropagate;
+   typedef test_allocator, 2, true>       InnerAlloc2TruePropagate;
+
+   //
+   typedef scoped_allocator_adaptor< OuterAlloc  >          Scoped0Inner;
+   typedef scoped_allocator_adaptor< OuterAlloc
+                                   , InnerAlloc1 >          Scoped1Inner;
+   typedef scoped_allocator_adaptor< OuterAlloc
+                                   , InnerAlloc1
+                                   , InnerAlloc2 >          Scoped2Inner;
+   typedef scoped_allocator_adaptor
+      < scoped_allocator_adaptor
+         
+      >                                                     ScopedScoped0Inner;
+   typedef scoped_allocator_adaptor
+      < scoped_allocator_adaptor
+         
+      , InnerAlloc1
+      >                                                     ScopedScoped1Inner;
+   typedef scoped_allocator_adaptor
+      < scoped_allocator_adaptor
+         
+      , InnerAlloc1, InnerAlloc2
+      >                                                     ScopedScoped2Inner;
+   typedef scoped_allocator_adaptor< Rebound9OuterAlloc  >  Rebound9Scoped0Inner;
+   typedef scoped_allocator_adaptor< Rebound9OuterAlloc
+                                   , InnerAlloc1 >          Rebound9Scoped1Inner;
+   typedef scoped_allocator_adaptor< Rebound9OuterAlloc
+                                   , InnerAlloc1
+                                   , InnerAlloc2 >          Rebound9Scoped2Inner;
+
+   //outer_allocator_type
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< OuterAlloc
+                       , Scoped0Inner::outer_allocator_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< OuterAlloc
+                       , Scoped1Inner::outer_allocator_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< OuterAlloc
+                       , Scoped2Inner::outer_allocator_type>::value ));
+   //value_type
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::value_type
+                       , Scoped0Inner::value_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::value_type
+                       , Scoped1Inner::value_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::value_type
+                       , Scoped2Inner::value_type>::value ));
+   //size_type
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::size_type
+                       , Scoped0Inner::size_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::size_type
+                       , Scoped1Inner::size_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::size_type
+                       , Scoped2Inner::size_type>::value ));
+
+   //difference_type
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::difference_type
+                       , Scoped0Inner::difference_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::difference_type
+                       , Scoped1Inner::difference_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::difference_type
+                       , Scoped2Inner::difference_type>::value ));
+
+   //pointer
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::pointer
+                       , Scoped0Inner::pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::pointer
+                       , Scoped1Inner::pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::pointer
+                       , Scoped2Inner::pointer>::value ));
+
+   //const_pointer
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::const_pointer
+                       , Scoped0Inner::const_pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::const_pointer
+                       , Scoped1Inner::const_pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::const_pointer
+                       , Scoped2Inner::const_pointer>::value ));
+
+   //void_pointer
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::void_pointer
+                       , Scoped0Inner::void_pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::void_pointer
+                       , Scoped1Inner::void_pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::void_pointer
+                       , Scoped2Inner::void_pointer>::value ));
+
+   //const_void_pointer
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::const_void_pointer
+                       , Scoped0Inner::const_void_pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::const_void_pointer
+                       , Scoped1Inner::const_void_pointer>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< allocator_traits::const_void_pointer
+                       , Scoped2Inner::const_void_pointer>::value ));
+
+   //rebind
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same >::other
+                       , Rebound9Scoped0Inner >::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same >::other
+                       , Rebound9Scoped1Inner >::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same >::other
+                       , Rebound9Scoped2Inner >::value ));
+
+   //inner_allocator_type
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< Scoped0Inner
+                       , Scoped0Inner::inner_allocator_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< scoped_allocator_adaptor
+                       , Scoped1Inner::inner_allocator_type>::value ));
+   BOOST_STATIC_ASSERT(( boost::container::container_detail::is_same< scoped_allocator_adaptor
+                       , Scoped2Inner::inner_allocator_type>::value ));
+
+   {
+      //Propagation test
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate  >  Scoped0InnerF;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate  >   Scoped0InnerT;
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate
+                                    , InnerAlloc1FalsePropagate >  Scoped1InnerFF;
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate
+                                    , InnerAlloc1TruePropagate >   Scoped1InnerFT;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate
+                                    , InnerAlloc1FalsePropagate >  Scoped1InnerTF;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate
+                                    , InnerAlloc1TruePropagate >   Scoped1InnerTT;
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate
+                                    , InnerAlloc1FalsePropagate
+                                    , InnerAlloc2FalsePropagate >  Scoped2InnerFFF;
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate
+                                    , InnerAlloc1FalsePropagate
+                                    , InnerAlloc2TruePropagate >  Scoped2InnerFFT;
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate
+                                    , InnerAlloc1TruePropagate
+                                    , InnerAlloc2FalsePropagate >  Scoped2InnerFTF;
+      typedef scoped_allocator_adaptor< OuterAllocFalsePropagate
+                                    , InnerAlloc1TruePropagate
+                                    , InnerAlloc2TruePropagate >  Scoped2InnerFTT;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate
+                                    , InnerAlloc1FalsePropagate
+                                    , InnerAlloc2FalsePropagate >  Scoped2InnerTFF;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate
+                                    , InnerAlloc1FalsePropagate
+                                    , InnerAlloc2TruePropagate >  Scoped2InnerTFT;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate
+                                    , InnerAlloc1TruePropagate
+                                    , InnerAlloc2FalsePropagate >  Scoped2InnerTTF;
+      typedef scoped_allocator_adaptor< OuterAllocTruePropagate
+                                    , InnerAlloc1TruePropagate
+                                    , InnerAlloc2TruePropagate >  Scoped2InnerTTT;
+
+      //propagate_on_container_copy_assignment
+      //0 inner
+      BOOST_STATIC_ASSERT(( !Scoped0InnerF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped0InnerT::propagate_on_container_copy_assignment::value ));
+      //1 inner
+      BOOST_STATIC_ASSERT(( !Scoped1InnerFF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerFT::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerTF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerTT::propagate_on_container_copy_assignment::value ));
+      //2 inner
+      BOOST_STATIC_ASSERT(( !Scoped2InnerFFF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFFT::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFTF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFTT::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTFF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTFT::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTTF::propagate_on_container_copy_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTTT::propagate_on_container_copy_assignment::value ));
+
+      //propagate_on_container_move_assignment
+      //0 inner
+      BOOST_STATIC_ASSERT(( !Scoped0InnerF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped0InnerT::propagate_on_container_move_assignment::value ));
+      //1 inner
+      BOOST_STATIC_ASSERT(( !Scoped1InnerFF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerFT::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerTF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerTT::propagate_on_container_move_assignment::value ));
+      //2 inner
+      BOOST_STATIC_ASSERT(( !Scoped2InnerFFF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFFT::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFTF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFTT::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTFF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTFT::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTTF::propagate_on_container_move_assignment::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTTT::propagate_on_container_move_assignment::value ));
+
+      //propagate_on_container_swap
+      //0 inner
+      BOOST_STATIC_ASSERT(( !Scoped0InnerF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped0InnerT::propagate_on_container_swap::value ));
+      //1 inner
+      BOOST_STATIC_ASSERT(( !Scoped1InnerFF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerFT::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerTF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped1InnerTT::propagate_on_container_swap::value ));
+      //2 inner
+      BOOST_STATIC_ASSERT(( !Scoped2InnerFFF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFFT::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFTF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerFTT::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTFF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTFT::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTTF::propagate_on_container_swap::value ));
+      BOOST_STATIC_ASSERT((  Scoped2InnerTTT::propagate_on_container_swap::value ));
+   }
+
+   //Default constructor
+   {
+      Scoped0Inner s0i;
+      Scoped1Inner s1i;
+   }
+
+   //inner_allocator()
+   {
+      Scoped0Inner s0i;
+      Scoped1Inner s1i;
+      Scoped2Inner s2i;
+      const Scoped0Inner const_s0i;
+      const Scoped1Inner const_s1i;
+      const Scoped2Inner const_s2i;
+
+      Scoped0Inner::inner_allocator_type &s0i_inner =             s0i.inner_allocator();
+      (void)s0i_inner;
+      const Scoped0Inner::inner_allocator_type &const_s0i_inner = const_s0i.inner_allocator();
+      (void)const_s0i_inner;
+      Scoped1Inner::inner_allocator_type &s1i_inner =             s1i.inner_allocator();
+      (void)s1i_inner;
+      const Scoped1Inner::inner_allocator_type &const_s1i_inner = const_s1i.inner_allocator();
+      (void)const_s1i_inner;
+      Scoped2Inner::inner_allocator_type &s2i_inner =             s2i.inner_allocator();
+      (void)s2i_inner;
+      const Scoped2Inner::inner_allocator_type &const_s2i_inner = const_s2i.inner_allocator();
+      (void)const_s2i_inner;
+   }
+
+   //operator==/!=
+   {
+      const Scoped0Inner const_s0i;
+      const Rebound9Scoped0Inner const_rs0i;
+      if(!(const_s0i == const_s0i) ||
+         !(const_rs0i == const_s0i)){
+         return 1;
+      }
+      if(  const_s0i != const_s0i ||
+           const_s0i != const_rs0i ){
+         return 1;
+      }
+
+      const Scoped1Inner const_s1i;
+      const Rebound9Scoped1Inner const_rs1i;
+      if(!(const_s1i == const_s1i) ||
+         !(const_rs1i == const_s1i)){
+         return 1;
+      }
+      if(  const_s1i != const_s1i ||
+           const_s1i != const_rs1i ){
+         return 1;
+      }
+      const Scoped2Inner const_s2i;
+      const Rebound9Scoped2Inner const_rs2i;
+      if(!(const_s2i == const_s2i) ||
+         !(const_s2i == const_rs2i) ){
+         return 1;
+      }
+      if(  const_s2i != const_s2i ||
+           const_s2i != const_rs2i ){
+         return 1;
+      }
+   }
+
+   //outer_allocator()
+   {
+      Scoped0Inner s0i;
+      Scoped1Inner s1i;
+      Scoped2Inner s2i;
+      const Scoped0Inner const_s0i;
+      const Scoped1Inner const_s1i;
+      const Scoped2Inner const_s2i;
+
+      Scoped0Inner::outer_allocator_type &s0i_inner =             s0i.outer_allocator();
+      (void)s0i_inner;
+      const Scoped0Inner::outer_allocator_type &const_s0i_inner = const_s0i.outer_allocator();
+      (void)const_s0i_inner;
+      Scoped1Inner::outer_allocator_type &s1i_inner =             s1i.outer_allocator();
+      (void)s1i_inner;
+      const Scoped1Inner::outer_allocator_type &const_s1i_inner = const_s1i.outer_allocator();
+      (void)const_s1i_inner;
+      Scoped2Inner::outer_allocator_type &s2i_inner =             s2i.outer_allocator();
+      (void)s2i_inner;
+      const Scoped2Inner::outer_allocator_type &const_s2i_inner = const_s2i.outer_allocator();
+      (void)const_s2i_inner;
+   }
+
+   //max_size()
+   {
+      const Scoped0Inner const_s0i;
+      const Scoped1Inner const_s1i;
+      const Scoped2Inner const_s2i;
+      const OuterAlloc  const_oa;
+      const InnerAlloc1 const_ia1;
+      const InnerAlloc2 const_ia2;
+
+      if(const_s0i.max_size() != const_oa.max_size()){
+         return 1;
+      }
+
+      if(const_s1i.max_size() != const_oa.max_size()){
+         return 1;
+      }
+
+      if(const_s2i.max_size() != const_oa.max_size()){
+         return 1;
+      }
+
+      if(const_s1i.inner_allocator().max_size() != const_ia1.max_size()){
+         return 1;
+      }
+
+      if(const_s2i.inner_allocator().inner_allocator().max_size() != const_ia2.max_size()){
+         return 1;
+      }
+   }
+   //Copy and move operations
+   {
+      //Construction
+      {
+         Scoped0Inner s0i_a, s0i_b(s0i_a), s0i_c(::boost::move(s0i_b));
+         Scoped1Inner s1i_a, s1i_b(s1i_a), s1i_c(::boost::move(s1i_b));
+         Scoped2Inner s2i_a, s2i_b(s2i_a), s2i_c(::boost::move(s2i_b));
+      }
+      //Assignment
+      {
+         Scoped0Inner s0i_a, s0i_b;
+         s0i_a = s0i_b;
+         s0i_a = ::boost::move(s0i_b);
+         Scoped1Inner s1i_a, s1i_b;
+         s1i_a = s1i_b;
+         s1i_a = ::boost::move(s1i_b);
+         Scoped2Inner s2i_a, s2i_b;
+         s2i_a = s2i_b;
+         s2i_a = ::boost::move(s2i_b);
+      }
+
+      OuterAlloc  oa;
+      InnerAlloc1 ia1;
+      InnerAlloc2 ia2;
+      Rebound9OuterAlloc roa;
+      Rebound9Scoped0Inner rs0i;
+      Rebound9Scoped1Inner rs1i;
+      Rebound9Scoped2Inner rs2i;
+
+      //Copy from outer
+      {
+         Scoped0Inner s0i(oa);
+         Scoped1Inner s1i(oa, ia1);
+         Scoped2Inner s2i(oa, ia1, ia2);
+      }
+      //Move from outer
+      {
+         Scoped0Inner s0i(::boost::move(oa));
+         Scoped1Inner s1i(::boost::move(oa), ia1);
+         Scoped2Inner s2i(::boost::move(oa), ia1, ia2);
+      }
+      //Copy from rebound outer
+      {
+         Scoped0Inner s0i(roa);
+         Scoped1Inner s1i(roa, ia1);
+         Scoped2Inner s2i(roa, ia1, ia2);
+      }
+      //Move from rebound outer
+      {
+         Scoped0Inner s0i(::boost::move(roa));
+         Scoped1Inner s1i(::boost::move(roa), ia1);
+         Scoped2Inner s2i(::boost::move(roa), ia1, ia2);
+      }
+      //Copy from rebound scoped
+      {
+         Scoped0Inner s0i(rs0i);
+         Scoped1Inner s1i(rs1i);
+         Scoped2Inner s2i(rs2i);
+      }
+      //Move from rebound scoped
+      {
+         Scoped0Inner s0i(::boost::move(rs0i));
+         Scoped1Inner s1i(::boost::move(rs1i));
+         Scoped2Inner s2i(::boost::move(rs2i));
+      }
+   }
+
+   {
+      vector > > dummy;  
+      dummy.push_back(0);
+   }
+
+   //destroy()
+   {
+      {
+         Scoped0Inner s0i;
+         mark_on_destructor mod;
+         s0i.destroy(&mod);
+         if(!mod.destroyed){
+            return 1;
+         }
+      }
+
+      {
+         Scoped1Inner s1i;
+         mark_on_destructor mod;
+         s1i.destroy(&mod);
+         if(!mod.destroyed){
+            return 1;
+         }
+      }
+      {
+         Scoped2Inner s2i;
+         mark_on_destructor mod;
+         s2i.destroy(&mod);
+         if(!mod.destroyed){
+            return 1;
+         }
+      }
+   }
+
+   //construct
+   {
+
+      BOOST_STATIC_ASSERT(( !boost::container::uses_allocator
+                              < ::mark_on_scoped_allocation
+                              , test_allocator 
+                              >::value ));
+      BOOST_STATIC_ASSERT((  boost::container::uses_allocator
+                              < ::mark_on_scoped_allocation
+                              , test_allocator 
+                              >::value ));
+      BOOST_STATIC_ASSERT((  boost::container::uses_allocator
+                              < ::mark_on_scoped_allocation
+                              , test_allocator 
+                              >::value ));
+      BOOST_STATIC_ASSERT(( boost::container::constructible_with_allocator_prefix
+                          < ::mark_on_scoped_allocation >::value ));
+      BOOST_STATIC_ASSERT(( boost::container::constructible_with_allocator_suffix
+                          < ::mark_on_scoped_allocation >::value ));
+
+      ////////////////////////////////////////////////////////////
+      //First check scoped allocator with just OuterAlloc.
+      //In this case OuterAlloc (test_allocator with tag 0) should be
+      //used to construct types.
+      ////////////////////////////////////////////////////////////
+      {
+         Scoped0Inner s0i;
+         //Check construction with 0 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s0i.construct(&dummy);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s0i.construct(&dummy);
+            if(dummy.construction_type != ConstructibleSuffix ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s0i.construct(&dummy);
+            if(dummy.construction_type != ConstructiblePrefix ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+
+         //Check construction with 1 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s0i.construct(&dummy, 1);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 1){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s0i.construct(&dummy, 2);
+            if(dummy.construction_type != ConstructibleSuffix ||
+               dummy.value != 2){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s0i.construct(&dummy, 3);
+            if(dummy.construction_type != ConstructiblePrefix ||
+               dummy.value != 3){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+      }
+      ////////////////////////////////////////////////////////////
+      //Then check scoped allocator with OuterAlloc and InnerAlloc.
+      //In this case InnerAlloc (test_allocator with tag 1) should be
+      //used to construct types.
+      ////////////////////////////////////////////////////////////
+      {
+         Scoped1Inner s1i;
+         //Check construction with 0 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s1i.construct(&dummy);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s1i.construct(&dummy);
+            if(dummy.construction_type != ConstructibleSuffix ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s1i.construct(&dummy);
+            if(dummy.construction_type != ConstructiblePrefix ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+
+         //Check construction with 1 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s1i.construct(&dummy, 1);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 1){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s1i.construct(&dummy, 2);
+            if(dummy.construction_type != ConstructibleSuffix ||
+               dummy.value != 2){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            s1i.construct(&dummy, 3);
+            if(dummy.construction_type != ConstructiblePrefix ||
+               dummy.value != 3){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+      }
+
+      //////////////////////////////////////////////////////////////////////////////////
+      //Now test recursive OuterAllocator types (OuterAllocator is an scoped_allocator)
+      //////////////////////////////////////////////////////////////////////////////////
+
+      ////////////////////////////////////////////////////////////
+      //First check scoped allocator with just OuterAlloc.
+      //In this case OuterAlloc (test_allocator with tag 0) should be
+      //used to construct types.
+      ////////////////////////////////////////////////////////////
+      {
+         //Check outer_allocator_type is scoped
+         BOOST_STATIC_ASSERT(( boost::container::is_scoped_allocator
+            ::value ));
+         BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
+            < boost::container::outermost_allocator::type
+            , Outer10IdAlloc
+            >::value ));
+         BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
+            < ScopedScoped0Inner::outer_allocator_type
+            , scoped_allocator_adaptor
+            >::value ));
+         BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
+            < scoped_allocator_adaptor::outer_allocator_type
+            , Outer10IdAlloc
+            >::value ));
+         ScopedScoped0Inner ssro0i;
+         Outer10IdAlloc & val = boost::container::outermost_allocator::get(ssro0i);
+         (void)val;
+         //Check construction with 0 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro0i.construct(&dummy);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro0i.construct(&dummy);
+            if(dummy.construction_type != ConstructibleSuffix ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro0i.construct(&dummy);
+            if(dummy.construction_type != ConstructiblePrefix ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+
+         //Check construction with 1 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro0i.construct(&dummy, 1);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 1){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro0i.construct(&dummy, 2);
+            if(dummy.construction_type != ConstructibleSuffix ||
+               dummy.value != 2){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro0i.construct(&dummy, 3);
+            if(dummy.construction_type != ConstructiblePrefix ||
+               dummy.value != 3){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+      }
+      ////////////////////////////////////////////////////////////
+      //Then check scoped allocator with OuterAlloc and InnerAlloc.
+      //In this case inner_allocator_type is not convertible to
+      //::mark_on_scoped_allocation so uses_allocator
+      //should be false on all tests.
+      ////////////////////////////////////////////////////////////
+      {
+         //Check outer_allocator_type is scoped
+         BOOST_STATIC_ASSERT(( boost::container::is_scoped_allocator
+            ::value ));
+         BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
+            < boost::container::outermost_allocator::type
+            , Outer10IdAlloc
+            >::value ));
+         BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
+            < ScopedScoped1Inner::outer_allocator_type
+            , scoped_allocator_adaptor
+            >::value ));
+         BOOST_STATIC_ASSERT(( ::boost::container::container_detail::is_same
+            < scoped_allocator_adaptor::outer_allocator_type
+            , Outer10IdAlloc
+            >::value ));
+         BOOST_STATIC_ASSERT(( !
+            ::boost::container::uses_allocator
+               < ::mark_on_scoped_allocation
+               , ScopedScoped1Inner::inner_allocator_type::outer_allocator_type
+               >::value ));
+         ScopedScoped1Inner ssro1i;
+         Outer10IdAlloc & val = boost::container::outermost_allocator::get(ssro1i);
+         (void)val;
+
+         //Check construction with 0 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro1i.construct(&dummy);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro1i.construct(&dummy);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro1i.construct(&dummy);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 0){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+
+         //Check construction with 1 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro1i.construct(&dummy, 1);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 1){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro1i.construct(&dummy, 2);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 2){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            MarkType dummy;
+            dummy.~MarkType();
+            ssro1i.construct(&dummy, 3);
+            if(dummy.construction_type != NotUsesAllocator ||
+               dummy.value != 3){
+               dummy.~MarkType();
+               return 1;
+            }
+            dummy.~MarkType();
+         }
+      }
+
+      ////////////////////////////////////////////////////////////
+      //Now check propagation to pair
+      ////////////////////////////////////////////////////////////
+      //First check scoped allocator with just OuterAlloc.
+      //In this case OuterAlloc (test_allocator with tag 0) should be
+      //used to construct types.
+      ////////////////////////////////////////////////////////////
+      {
+         using boost::container::container_detail::pair;
+         typedef test_allocator< pair< tagged_integer<0>
+                               , tagged_integer<0> >, 0> OuterPairAlloc;
+         typedef test_allocator< pair< tagged_integer<1>
+                               , tagged_integer<1> >, 1> InnerPairAlloc1;
+         typedef test_allocator< pair< tagged_integer<2>
+                               , tagged_integer<2> >, 2> InnerPairAlloc2;
+         //
+         typedef scoped_allocator_adaptor < OuterPairAlloc  >  ScopedPair0Inner;
+         typedef scoped_allocator_adaptor < OuterPairAlloc
+                                          , InnerPairAlloc1 >  ScopedPair1Inner;
+         typedef scoped_allocator_adaptor < OuterPairAlloc
+                                          , InnerPairAlloc1
+                                          , InnerPairAlloc2 >  ScopedPair2Inner;
+
+         ScopedPair0Inner s0i;
+         //Check construction with 0 user arguments
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy);
+            if(dummy.first.construction_type  != NotUsesAllocator ||
+               dummy.second.construction_type != NotUsesAllocator ||
+               dummy.first.value  != 0 ||
+               dummy.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy);
+            if(dummy.first.construction_type  != ConstructibleSuffix ||
+               dummy.second.construction_type != ConstructibleSuffix ||
+               dummy.first.value  != 0 ||
+               dummy.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy);
+            if(dummy.first.construction_type  != ConstructiblePrefix ||
+               dummy.second.construction_type != ConstructiblePrefix ||
+               dummy.first.value  != 0  ||
+               dummy.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+
+         //Check construction with 1 user arguments for each pair
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, 1, 1);
+            if(dummy.first.construction_type  != NotUsesAllocator ||
+               dummy.second.construction_type != NotUsesAllocator ||
+               dummy.first.value  != 1 ||
+               dummy.second.value != 1 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, 1, 1);
+            if(dummy.first.construction_type  != ConstructibleSuffix ||
+               dummy.second.construction_type != ConstructibleSuffix ||
+               dummy.first.value  != 1 ||
+               dummy.second.value != 1 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, 2, 2);
+            if(dummy.first.construction_type  != ConstructiblePrefix ||
+               dummy.second.construction_type != ConstructiblePrefix ||
+               dummy.first.value  != 2 ||
+               dummy.second.value != 2 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         //Check construction with pair copy construction
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy, dummy2;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, dummy2);
+            if(dummy.first.construction_type  != NotUsesAllocator ||
+               dummy.second.construction_type != NotUsesAllocator ||
+               dummy.first.value  != 0 ||
+               dummy.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy, dummy2(1, 1);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, dummy2);
+            if(dummy.first.construction_type  != ConstructibleSuffix ||
+               dummy.second.construction_type != ConstructibleSuffix ||
+               dummy.first.value  != 1 ||
+               dummy.second.value != 1 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy, dummy2(2, 2);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, dummy2);
+            if(dummy.first.construction_type  != ConstructiblePrefix ||
+               dummy.second.construction_type != ConstructiblePrefix ||
+               dummy.first.value  != 2 ||
+               dummy.second.value != 2 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         //Check construction with pair move construction
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy, dummy2(3, 3);
+            dummy2.first.construction_type = dummy2.second.construction_type = ConstructibleSuffix;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, ::boost::move(dummy2));
+            if(dummy.first.construction_type  != NotUsesAllocator ||
+               dummy.second.construction_type != NotUsesAllocator ||
+               dummy.first.value  != 3 ||
+               dummy.second.value != 3 ||
+               dummy2.first.construction_type  != NotUsesAllocator ||
+               dummy2.second.construction_type != NotUsesAllocator ||
+               dummy2.first.value  != 0 ||
+               dummy2.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy, dummy2(1, 1);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, ::boost::move(dummy2));
+            if(dummy.first.construction_type  != ConstructibleSuffix ||
+               dummy.second.construction_type != ConstructibleSuffix ||
+               dummy.first.value  != 1 ||
+               dummy.second.value != 1 ||
+               dummy2.first.construction_type  != ConstructibleSuffix ||
+               dummy2.second.construction_type != ConstructibleSuffix ||
+               dummy2.first.value  != 0 ||
+               dummy2.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy, dummy2(2, 2);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, ::boost::move(dummy2));
+            if(dummy.first.construction_type  != ConstructiblePrefix ||
+               dummy.second.construction_type != ConstructiblePrefix ||
+               dummy.first.value  != 2 ||
+               dummy.second.value != 2 ||
+               dummy2.first.construction_type  != ConstructiblePrefix ||
+               dummy2.second.construction_type != ConstructiblePrefix ||
+               dummy2.first.value  != 0 ||
+               dummy2.second.value != 0 ){
+               dummy2.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         //Check construction with related pair copy construction
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            pair dummy2;
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, dummy2);
+            if(dummy.first.construction_type  != NotUsesAllocator ||
+               dummy.second.construction_type != NotUsesAllocator ||
+               dummy.first.value  != 0 ||
+               dummy.second.value != 0 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            pair dummy2(1, 1);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, dummy2);
+            if(dummy.first.construction_type  != ConstructibleSuffix ||
+               dummy.second.construction_type != ConstructibleSuffix ||
+               dummy.first.value  != 1 ||
+               dummy.second.value != 1 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            pair dummy2(2, 2);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, dummy2);
+            if(dummy.first.construction_type  != ConstructiblePrefix ||
+               dummy.second.construction_type != ConstructiblePrefix ||
+               dummy.first.value  != 2 ||
+               dummy.second.value != 2 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         //Check construction with related pair move construction
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            pair dummy2(3, 3);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, ::boost::move(dummy2));
+            if(dummy.first.construction_type  != NotUsesAllocator ||
+               dummy.second.construction_type != NotUsesAllocator ||
+               dummy.first.value  != 3 ||
+               dummy.second.value != 3 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            pair dummy2(1, 1);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, ::boost::move(dummy2));
+            if(dummy.first.construction_type  != ConstructibleSuffix ||
+               dummy.second.construction_type != ConstructibleSuffix ||
+               dummy.first.value  != 1 ||
+               dummy.second.value != 1 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+         {
+            typedef ::mark_on_scoped_allocation MarkType;
+            typedef pair MarkTypePair;
+            MarkTypePair dummy;
+            pair dummy2(2, 2);
+            dummy.~MarkTypePair();
+            s0i.construct(&dummy, ::boost::move(dummy2));
+            if(dummy.first.construction_type  != ConstructiblePrefix ||
+               dummy.second.construction_type != ConstructiblePrefix ||
+               dummy.first.value  != 2 ||
+               dummy.second.value != 2 ){
+               dummy.~MarkTypePair();
+               return 1;
+            }
+            dummy.~MarkTypePair();
+         }
+      }
+   }
+
+   return 0;
+}
+#include 
diff --git a/test/scoped_allocator_usage_test.cpp b/test/scoped_allocator_usage_test.cpp
new file mode 100644
index 0000000..e7af116
--- /dev/null
+++ b/test/scoped_allocator_usage_test.cpp
@@ -0,0 +1,95 @@
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+template 
+class SimpleAllocator
+{
+public:
+	typedef Ty value_type;
+	typedef typename std::allocator::pointer pointer;
+	typedef typename std::allocator::size_type size_type;
+
+	SimpleAllocator(int value)
+		: _value(value)
+	{}
+
+	template 
+	SimpleAllocator(const SimpleAllocator &other)
+		: _value(other._value)
+	{}
+
+	pointer allocate(size_type n)
+	{
+		return _allocator.allocate(n);
+	}
+	void deallocate(pointer p, size_type n)
+	{
+		_allocator.deallocate(p, n);
+	}
+private:
+	int _value;
+	std::allocator _allocator;
+
+	template  friend class SimpleAllocator;
+};
+
+template 
+class ScopedAllocator : public boost::container::scoped_allocator_adaptor >
+{
+private:
+	typedef boost::container::scoped_allocator_adaptor > Base;
+
+public:
+	ScopedAllocator(int value)
+		: Base(SimpleAllocator(value))
+	{}
+};
+
+class Resource
+{
+private: // Not copyable
+	Resource(const Resource &);
+	Resource &operator=(const Resource &);
+public:
+	typedef SimpleAllocator allocator_type;
+
+	Resource(BOOST_RV_REF(Resource)other)
+		: _value(other._value), _allocator(boost::move(other._allocator))
+	{
+		other._value = -1;
+	}
+
+	Resource(BOOST_RV_REF(Resource)other, const allocator_type &allocator)
+		: _value(other._value), _allocator(allocator)
+	{
+		other._value = -1;
+	}
+
+	Resource(int value, const allocator_type &allocator)
+		: _value(value), _allocator(allocator)
+	{}
+private:
+	int _value;
+	allocator_type _allocator;
+};
+
+typedef std::pair MapNode;
+
+typedef boost::container::scoped_allocator_adaptor > MapAllocator;
+
+typedef boost::container::map, MapAllocator> Map;
+
+int main()
+{
+	Map map1(std::less(), SimpleAllocator(5));
+
+	map1.emplace("foo", 42);
+	map1.emplace("bar", 11);
+
+	//Map map2 = map1;
+	return 0;
+}
diff --git a/test/set_test.hpp b/test/set_test.hpp
index 5dd6a2a..95dfee0 100644
--- a/test/set_test.hpp
+++ b/test/set_test.hpp
@@ -1,6 +1,6 @@
 ////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/slist_test.cpp b/test/slist_test.cpp
index fb9f28f..d1c80e3 100644
--- a/test/slist_test.cpp
+++ b/test/slist_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp
index edcd404..fe7d9e1 100644
--- a/test/stable_vector_test.cpp
+++ b/test/stable_vector_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/string_test.cpp b/test/string_test.cpp
index 3799d4a..c51e80b 100644
--- a/test/string_test.cpp
+++ b/test/string_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/tree_test.cpp b/test/tree_test.cpp
index 0717cce..dca5a31 100644
--- a/test/tree_test.cpp
+++ b/test/tree_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
@@ -201,8 +201,10 @@ void test_move()
 {
    //Now test move semantics
    C original;
+   original.emplace();
    C move_ctor(boost::move(original));
    C move_assign;
+   move_assign.emplace();
    move_assign = boost::move(move_ctor);
    move_assign.swap(original);
 }
diff --git a/test/util.hpp b/test/util.hpp
index eea3b00..9bfe1af 100644
--- a/test/util.hpp
+++ b/test/util.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
diff --git a/test/vector_test.cpp b/test/vector_test.cpp
index 3be90ae..d7fc47c 100644
--- a/test/vector_test.cpp
+++ b/test/vector_test.cpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //
@@ -95,6 +95,26 @@ enum Test
 
 int main()
 {
+   {
+      const std::size_t positions_length = 10;
+      std::size_t positions[positions_length];
+      vector vector_int;
+      vector vector_int2(positions_length);
+      for(std::size_t i = 0; i != positions_length; ++i){
+         positions[i] = 0u;
+      }
+      for(std::size_t i = 0, max = vector_int2.size(); i != max; ++i){
+         vector_int2[i] = i;
+      }
+
+      vector_int.insert(vector_int.begin(), 999);
+
+      vector_int.insert_ordered_at(positions_length, positions + positions_length, vector_int2.end());
+
+      for(std::size_t i = 0, max = vector_int.size(); i != max; ++i){
+         std::cout << vector_int[i] << std::endl;
+      }
+   }
    recursive_vector_test();
    {
       //Now test move semantics
@@ -134,7 +154,8 @@ int main()
 
    if(!boost::container::test::test_propagate_allocator())
       return 1;
-  
+
    return 0;
+
 }
 #include 
diff --git a/test/vector_test.hpp b/test/vector_test.hpp
index 4b6d7b7..847e9e8 100644
--- a/test/vector_test.hpp
+++ b/test/vector_test.hpp
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-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)
 //