Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81518 - in trunk/boost/container: . detail
From: igaztanaga_at_[hidden]
Date: 2012-11-24 16:08:23


Author: igaztanaga
Date: 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
New Revision: 81518
URL: http://svn.boost.org/trac/boost/changeset/81518

Log:
* Improved `vector`'s insertion performance.
* Changed again experimental multiallocation interface for better performance (still experimental).
* Added no exception support for those willing to disable exceptions in their compilers.
* Fixed GCC -Wshadow warnings.
* Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.

Added:
   trunk/boost/container/detail/allocator_version_traits.hpp (contents, props changed)
Text files modified:
   trunk/boost/container/allocator_traits.hpp | 2
   trunk/boost/container/deque.hpp | 261 +++++++-------
   trunk/boost/container/detail/adaptive_node_pool_impl.hpp | 714 ++++++++++++++++++++++++++-------------
   trunk/boost/container/detail/advanced_insert_int.hpp | 491 +++++++++++----------------
   trunk/boost/container/detail/destroyers.hpp | 11
   trunk/boost/container/detail/flat_tree.hpp | 72 ++--
   trunk/boost/container/detail/iterators.hpp | 2
   trunk/boost/container/detail/multiallocation_chain.hpp | 132 +++---
   trunk/boost/container/detail/node_alloc_holder.hpp | 101 +++--
   trunk/boost/container/detail/node_pool_impl.hpp | 32
   trunk/boost/container/detail/pair.hpp | 2
   trunk/boost/container/detail/pool_common.hpp | 2
   trunk/boost/container/detail/preprocessor.hpp | 16
   trunk/boost/container/detail/tree.hpp | 19
   trunk/boost/container/detail/type_traits.hpp | 2
   trunk/boost/container/detail/utilities.hpp | 369 +++++++++++++++++++-
   trunk/boost/container/detail/workaround.hpp | 8
   trunk/boost/container/flat_map.hpp | 108 +++---
   trunk/boost/container/flat_set.hpp | 106 ++--
   trunk/boost/container/list.hpp | 177 ++++-----
   trunk/boost/container/map.hpp | 108 +++---
   trunk/boost/container/scoped_allocator.hpp | 32 +
   trunk/boost/container/set.hpp | 22
   trunk/boost/container/slist.hpp | 172 ++++-----
   trunk/boost/container/stable_vector.hpp | 253 +++++--------
   trunk/boost/container/string.hpp | 403 ++++++++++-----------
   trunk/boost/container/vector.hpp | 425 +++++++++++-----------
   27 files changed, 2218 insertions(+), 1824 deletions(-)

Modified: trunk/boost/container/allocator_traits.hpp
==============================================================================
--- trunk/boost/container/allocator_traits.hpp (original)
+++ trunk/boost/container/allocator_traits.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -28,7 +28,7 @@
 #include <boost/container/detail/memory_util.hpp>
 #include <boost/type_traits/integral_constant.hpp>
 #include <boost/container/detail/mpl.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <limits> //numeric_limits<>::max()
 #include <new> //placement new
 #include <memory> //std::allocator

Modified: trunk/boost/container/deque.hpp
==============================================================================
--- trunk/boost/container/deque.hpp (original)
+++ trunk/boost/container/deque.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -58,9 +58,11 @@
 #include <boost/type_traits/has_trivial_assign.hpp>
 #include <boost/type_traits/has_nothrow_copy.hpp>
 #include <boost/type_traits/has_nothrow_assign.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 
 namespace boost {
 namespace container {
@@ -79,8 +81,7 @@
    typedef T value_type;
    typedef Allocator allocator_type;
    static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move = false;
- //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
    static const bool trivial_copy = has_trivial_copy<value_type>::value;
    static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
    static const bool trivial_assign = has_trivial_assign<value_type>::value;
@@ -304,7 +305,7 @@
       {
          this->m_node = new_node;
          this->m_first = *new_node;
- this->m_last = this->m_first + difference_type(this->s_buffer_size());
+ this->m_last = this->m_first + this->s_buffer_size();
       }
 
       friend const_iterator operator+(difference_type n, const const_iterator& x)
@@ -565,9 +566,6 @@
    typedef typename Base::ptr_alloc_ptr index_pointer;
    static size_type s_buffer_size()
       { return Base::s_buffer_size(); }
- typedef container_detail::advanced_insert_aux_int<iterator> advanced_insert_aux_int_t;
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef boost::move_iterator<r_iterator> move_it;
    typedef allocator_traits<Allocator> allocator_traits_type;
 
    /// @endcond
@@ -590,10 +588,10 @@
 
    //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
    //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
- explicit deque(const allocator_type& a)
+ explicit deque(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
       : Base(a)
    {}
 
@@ -607,8 +605,8 @@
    explicit deque(size_type n)
       : Base(n, allocator_type())
    {
- container_detail::default_construct_aux_proxy<Allocator, iterator> proxy(this->alloc(), n);
- proxy.uninitialized_copy_remaining_to(this->begin());
+ container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
+ proxy.uninitialized_copy_n_and_update(this->begin(), n);
       //deque_base will deallocate in case of exception...
    }
 
@@ -717,7 +715,7 @@
    //! <b>Complexity</b>: Linear to the number of elements.
    ~deque() BOOST_CONTAINER_NOEXCEPT
    {
- priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+ this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
    }
 
    //! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -1020,7 +1018,7 @@
          this->priv_erase_last_n(len - new_size);
       else{
          const size_type n = new_size - this->size();
- container_detail::default_construct_aux_proxy<Allocator, iterator> proxy(this->alloc(), n);
+ container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
          priv_insert_back_aux_impl(n, proxy);
       }
    }
@@ -1176,9 +1174,8 @@
          this->priv_push_front_simple_commit();
       }
       else{
- typedef container_detail::advanced_insert_aux_non_movable_emplace<Allocator, iterator, Args...> type;
- type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- this->priv_insert_front_aux_impl(1, proxy);
+ typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
+ this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
       }
    }
 
@@ -1199,9 +1196,8 @@
          this->priv_push_back_simple_commit();
       }
       else{
- typedef container_detail::advanced_insert_aux_non_movable_emplace<Allocator, iterator, Args...> type;
- type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- this->priv_insert_back_aux_impl(1, proxy);
+ typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
+ this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
       }
    }
 
@@ -1226,9 +1222,8 @@
          return (this->end()-1);
       }
       else{
- typedef container_detail::advanced_insert_aux_emplace<Allocator, iterator, Args...> type;
- type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- return this->priv_insert_aux_impl(p, 1, proxy);
+ typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
+ return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
       }
    }
 
@@ -1247,9 +1242,8 @@
          priv_push_front_simple_commit(); \
       } \
       else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT \
- (advanced_insert_aux_non_movable_emplace, n), arg) \
- <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
+ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
             (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
          priv_insert_front_aux_impl(1, proxy); \
       } \
@@ -1266,9 +1260,8 @@
          priv_push_back_simple_commit(); \
       } \
       else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT( \
- advanced_insert_aux_non_movable_emplace, n), arg) \
- <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
+ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
             (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
          priv_insert_back_aux_impl(1, proxy); \
       } \
@@ -1287,8 +1280,8 @@
          return (this->end()-1); \
       } \
       else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
+ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
             (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
          return this->priv_insert_aux_impl(p, 1, proxy); \
       } \
@@ -1424,7 +1417,7 @@
       #endif
       )
    {
- container_detail::advanced_insert_aux_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first, last);
+ container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
       return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
    }
    #endif
@@ -1477,8 +1470,8 @@
    {
       const_iterator next = pos;
       ++next;
- difference_type index = pos - this->members_.m_start;
- if (size_type(index) < (this->size() >> 1)) {
+ size_type index = pos - this->members_.m_start;
+ if (index < (this->size()/2)) {
          boost::move_backward(begin(), iterator(pos), iterator(next));
          pop_front();
       }
@@ -1504,9 +1497,9 @@
          return this->members_.m_finish;
       }
       else {
- difference_type n = last - first;
- difference_type elems_before = first - this->members_.m_start;
- if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
+ const size_type n = static_cast<size_type>(last - first);
+ const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
+ if (elems_before < (this->size() - n) - elems_before) {
             boost::move_backward(begin(), iterator(first), iterator(last));
             iterator new_start = this->members_.m_start + n;
             if(!Base::traits_t::trivial_dctr_after_move)
@@ -1584,81 +1577,49 @@
    void priv_range_check(size_type n) const
       { if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
 
- iterator priv_insert(const_iterator position, const value_type &x)
+ template <class U>
+ iterator priv_insert(const_iterator position, BOOST_FWD_REF(U) x)
    {
       if (position == cbegin()){
- this->push_front(x);
+ this->push_front(::boost::forward<U>(x));
          return begin();
       }
       else if (position == cend()){
- this->push_back(x);
- return (end()-1);
- }
- else {
- return this->insert(position, size_type(1), x);
- }
- }
-
- iterator priv_insert(const_iterator position, BOOST_RV_REF(value_type) mx)
- {
- if (position == cbegin()) {
- this->push_front(boost::move(mx));
- return begin();
- }
- else if (position == cend()) {
- this->push_back(boost::move(mx));
- return(end()-1);
+ this->push_back(::boost::forward<U>(x));
+ return --end();
       }
       else {
- return this->insert(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
- }
- }
-
- void priv_push_front(const value_type &t)
- {
- if(this->priv_push_front_simple_available()){
- allocator_traits_type::construct
- ( this->alloc(), this->priv_push_front_simple_pos(), t);
- this->priv_push_front_simple_commit();
- }
- else{
- this->insert(cbegin(), size_type(1), t);
+ return priv_insert_aux_impl
+ (position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
       }
    }
 
- void priv_push_front(BOOST_RV_REF(value_type) t)
+ template <class U>
+ void priv_push_front(BOOST_FWD_REF(U) x)
    {
       if(this->priv_push_front_simple_available()){
          allocator_traits_type::construct
- ( this->alloc(), this->priv_push_front_simple_pos(), boost::move(t));
+ ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
          this->priv_push_front_simple_commit();
       }
       else{
- this->insert(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ priv_insert_aux_impl
+ (this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
       }
    }
 
- void priv_push_back(const value_type &t)
+ template <class U>
+ void priv_push_back(BOOST_FWD_REF(U) x)
    {
       if(this->priv_push_back_simple_available()){
          allocator_traits_type::construct
- ( this->alloc(), this->priv_push_back_simple_pos(), t);
+ ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
          this->priv_push_back_simple_commit();
       }
       else{
- this->insert(cend(), size_type(1), t);
- }
- }
-
- void priv_push_back(BOOST_RV_REF(T) t)
- {
- if(this->priv_push_back_simple_available()){
- allocator_traits_type::construct
- ( this->alloc(), this->priv_push_back_simple_pos(), boost::move(t));
- this->priv_push_back_simple_commit();
- }
- else{
- this->insert(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ priv_insert_aux_impl
+ (this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
+ container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
       }
    }
 
@@ -1710,7 +1671,8 @@
       }
    }
 
- iterator priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
+ template<class InsertProxy>
+ iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
    {
       iterator pos(p);
       const size_type pos_n = p - this->cbegin();
@@ -1719,58 +1681,85 @@
          pos = this->begin();
       }
 
- const difference_type elemsbefore = pos - this->members_.m_start;
- size_type length = this->size();
- if (elemsbefore < static_cast<difference_type>(length / 2)) {
- iterator new_start = this->priv_reserve_elements_at_front(n);
- iterator old_start = this->members_.m_start;
- pos = this->members_.m_start + elemsbefore;
- if (elemsbefore >= difference_type(n)) {
- iterator start_n = this->members_.m_start + difference_type(n);
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), this->members_.m_start, start_n, new_start);
+ const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
+ const size_type length = this->size();
+ if (elemsbefore < length / 2) {
+ const iterator new_start = this->priv_reserve_elements_at_front(n);
+ const iterator old_start = this->members_.m_start;
+ if(!elemsbefore){
+ interf.uninitialized_copy_n_and_update(new_start, n);
             this->members_.m_start = new_start;
- boost::move(start_n, pos, old_start);
- interf.copy_remaining_to(pos - difference_type(n));
          }
- else {
- difference_type mid_count = (difference_type(n) - elemsbefore);
- iterator mid_start = old_start - mid_count;
- interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
- this->members_.m_start = mid_start;
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), old_start, pos, new_start);
- this->members_.m_start = new_start;
- interf.copy_remaining_to(old_start);
+ else{
+ pos = this->members_.m_start + elemsbefore;
+ if (elemsbefore >= n) {
+ const iterator start_n = this->members_.m_start + n;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), this->members_.m_start, start_n, new_start);
+ this->members_.m_start = new_start;
+ boost::move(start_n, pos, old_start);
+ interf.copy_n_and_update(pos - n, n);
+ }
+ else {
+ const size_type mid_count = n - elemsbefore;
+ const iterator mid_start = old_start - mid_count;
+ interf.uninitialized_copy_n_and_update(mid_start, mid_count);
+ this->members_.m_start = mid_start;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), old_start, pos, new_start);
+ this->members_.m_start = new_start;
+ interf.copy_n_and_update(old_start, elemsbefore);
+ }
          }
       }
       else {
- iterator new_finish = this->priv_reserve_elements_at_back(n);
- iterator old_finish = this->members_.m_finish;
- const difference_type elemsafter =
- difference_type(length) - elemsbefore;
- pos = this->members_.m_finish - elemsafter;
- if (elemsafter >= difference_type(n)) {
- iterator finish_n = this->members_.m_finish - difference_type(n);
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), finish_n, this->members_.m_finish, this->members_.m_finish);
+ const iterator new_finish = this->priv_reserve_elements_at_back(n);
+ const iterator old_finish = this->members_.m_finish;
+ const size_type elemsafter = length - elemsbefore;
+ if(!elemsafter){
+ interf.uninitialized_copy_n_and_update(old_finish, n);
             this->members_.m_finish = new_finish;
- boost::move_backward(pos, finish_n, old_finish);
- interf.copy_remaining_to(pos);
          }
- else {
- interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
- this->members_.m_finish += n-elemsafter;
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, old_finish, this->members_.m_finish);
- this->members_.m_finish = new_finish;
- interf.copy_remaining_to(pos);
+ else{
+ pos = this->members_.m_finish - elemsafter;
+ if (elemsafter >= n) {
+ iterator finish_n = this->members_.m_finish - difference_type(n);
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), finish_n, this->members_.m_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ boost::move_backward(pos, finish_n, old_finish);
+ interf.copy_n_and_update(pos, n);
+ }
+ else {
+ const size_type raw_gap = n - elemsafter;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), pos, old_finish, this->members_.m_finish + raw_gap);
+ BOOST_TRY{
+ interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_range(this->members_.m_finish, this->members_.m_finish + (old_finish - pos));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ this->members_.m_finish = new_finish;
+ interf.copy_n_and_update(pos, elemsafter);
+ /*
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_finish += n-elemsafter;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), pos, old_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ interf.copy_remaining_to(pos);
+ */
+ }
          }
       }
       return this->begin() + pos_n;
    }
 
- iterator priv_insert_back_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertProxy>
+ iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
    {
       if(!this->members_.m_map){
          this->priv_initialize_map(0);
@@ -1778,19 +1767,20 @@
 
       iterator new_finish = this->priv_reserve_elements_at_back(n);
       iterator old_finish = this->members_.m_finish;
- interf.uninitialized_copy_some_and_update(old_finish, n, true);
+ interf.uninitialized_copy_n_and_update(old_finish, n);
       this->members_.m_finish = new_finish;
       return iterator(this->members_.m_finish - n);
    }
 
- iterator priv_insert_front_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertProxy>
+ iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
    {
       if(!this->members_.m_map){
          this->priv_initialize_map(0);
       }
 
       iterator new_start = this->priv_reserve_elements_at_front(n);
- interf.uninitialized_copy_some_and_update(new_start, difference_type(n), true);
+ interf.uninitialized_copy_n_and_update(new_start, n);
       this->members_.m_start = new_start;
       return new_start;
    }
@@ -2015,15 +2005,14 @@
 /// @cond
 
 namespace boost {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
-{
- enum { value = has_trivial_destructor<Allocator>::value };
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
 }
 
 /// @endcond

Modified: trunk/boost/container/detail/adaptive_node_pool_impl.hpp
==============================================================================
--- trunk/boost/container/detail/adaptive_node_pool_impl.hpp (original)
+++ trunk/boost/container/detail/adaptive_node_pool_impl.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -21,16 +21,28 @@
 #include <boost/container/detail/utilities.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/intrusive/set.hpp>
+#include <boost/intrusive/list.hpp>
 #include <boost/intrusive/slist.hpp>
 #include <boost/container/detail/type_traits.hpp>
 #include <boost/container/detail/math_functions.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/pool_common.hpp>
 #include <boost/assert.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 #include <cstddef>
 
 namespace boost {
 namespace container {
+
+namespace adaptive_pool_flag {
+
+static const unsigned int none = 0u;
+static const unsigned int align_only = 1u << 0u;
+static const unsigned int size_ordered = 1u << 1u;
+static const unsigned int address_ordered = 1u << 2u;
+
+} //namespace adaptive_pool_flag{
+
 namespace container_detail {
 
 template<class size_type>
@@ -42,42 +54,160 @@
    size_type hdr_offset;
 };
 
+template<class SizeType, unsigned int Flags>
+struct less_func;
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::none>
+{
+ static bool less(SizeType, SizeType, const void *, const void *)
+ { return true; }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::size_ordered>
+{
+ static bool less(SizeType ls, SizeType rs, const void *, const void *)
+ { return ls < rs; }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::address_ordered>
+{
+ static bool less(SizeType, SizeType, const void *la, const void *ra)
+ { return &la < &ra; }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered>
+{
+ static bool less(SizeType ls, SizeType rs, const void *la, const void *ra)
+ { return (ls < rs) || ((ls == rs) && (la < ra)); }
+};
+
+template<class VoidPointer, class SizeType, bool ordered>
+struct block_container_traits
+{
+ typedef typename bi::make_set_base_hook
+ < bi::void_pointer<VoidPointer>
+ , bi::optimize_size<true>
+ , bi::link_mode<bi::normal_link> >::type hook_t;
+
+ template<class T>
+ struct container
+ {
+ typedef typename bi::make_multiset
+ <T, bi::base_hook<hook_t>, bi::size_type<SizeType> >::type type;
+ };
+
+ template<class Container>
+ static void reinsert_was_used(Container &container, typename Container::reference v, bool)
+ {
+ typedef typename Container::const_iterator const_block_iterator;
+ const const_block_iterator this_block
+ (Container::s_iterator_to(const_cast<typename Container::const_reference>(v)));
+ const_block_iterator next_block(this_block);
+ if(++next_block != container.cend()){
+ if(this_block->free_nodes.size() > next_block->free_nodes.size()){
+ container.erase(this_block);
+ container.insert(v);
+ }
+ }
+ }
+
+ template<class Container>
+ static void insert_was_empty(Container &container, typename Container::value_type &v, bool)
+ {
+ container.insert(v);
+ }
+
+ template<class Container>
+ static void erase_first(Container &container)
+ {
+ container.erase(container.cbegin());
+ }
+
+ template<class Container>
+ static void erase_last(Container &container)
+ {
+ container.erase(--container.cend());
+ }
+};
+
 template<class VoidPointer, class SizeType>
+struct block_container_traits<VoidPointer, SizeType, false>
+{
+ typedef typename bi::make_list_base_hook
+ < bi::void_pointer<VoidPointer>
+ , bi::link_mode<bi::normal_link> >::type hook_t;
+
+ template<class T>
+ struct container
+ {
+ typedef typename bi::make_list
+ <T, bi::base_hook<hook_t>, bi::size_type<SizeType>, bi::constant_time_size<false> >::type type;
+ };
+
+ template<class Container>
+ static void reinsert_was_used(Container &container, typename Container::value_type &v, bool is_full)
+ {
+ if(is_full){
+ container.erase(Container::s_iterator_to(v));
+ container.push_back(v);
+ }
+ }
+
+ template<class Container>
+ static void insert_was_empty(Container &container, typename Container::value_type &v, bool is_full)
+ {
+ if(is_full){
+ container.push_back(v);
+ }
+ else{
+ container.push_front(v);
+ }
+ }
+
+ template<class Container>
+ static void erase_first(Container &container)
+ {
+ container.pop_front();
+ }
+
+ template<class Container>
+ static void erase_last(Container &container)
+ {
+ container.pop_back();
+ }
+};
+
+template<class MultiallocationChain, class VoidPointer, class SizeType, unsigned int Flags>
 struct adaptive_pool_types
 {
    typedef VoidPointer void_pointer;
- typedef typename bi::make_set_base_hook
- < bi::void_pointer<void_pointer>
- , bi::optimize_size<true>
- , bi::constant_time_size<false>
- , bi::link_mode<bi::normal_link> >::type multiset_hook_t;
-
+ static const bool ordered = (Flags & (adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered)) != 0;
+ typedef block_container_traits<VoidPointer, SizeType, ordered> block_container_traits_t;
+ typedef typename block_container_traits_t::hook_t hook_t;
    typedef hdr_offset_holder_t<SizeType> hdr_offset_holder;
+ static const unsigned int order_flags = Flags & (adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered);
+ typedef MultiallocationChain free_nodes_t;
 
    struct block_info_t
- :
- public hdr_offset_holder,
- public multiset_hook_t
+ : public hdr_offset_holder,
+ public hook_t
    {
- typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
       //An intrusive list of free node from this block
       free_nodes_t free_nodes;
       friend bool operator <(const block_info_t &l, const block_info_t &r)
       {
-// { return l.free_nodes.size() < r.free_nodes.size(); }
- //Let's order blocks first by free nodes and then by address
- //so that highest address fully free blocks are deallocated.
- //This improves returning memory to the OS (trimming).
- const bool is_less = l.free_nodes.size() < r.free_nodes.size();
- const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
- return is_less || (is_equal && (&l < &r));
+ return less_func<SizeType, order_flags>::
+ less(l.free_nodes.size(), r.free_nodes.size(), &l , &r);
       }
 
       friend bool operator ==(const block_info_t &l, const block_info_t &r)
       { return &l == &r; }
    };
- typedef typename bi::make_multiset
- <block_info_t, bi::base_hook<multiset_hook_t> >::type block_multiset_t;
+ typedef typename block_container_traits_t:: template container<block_info_t>::type block_container_t;
 };
 
 template<class size_type>
@@ -113,9 +243,9 @@
    , size_type &num_subblocks, size_type &real_num_node, size_type overhead_percent
    , size_type hdr_size, size_type hdr_offset_size, size_type payload_per_allocation)
 {
+ const size_type hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
    size_type elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
    size_type possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
- size_type hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
    while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
       ++possible_num_subblock;
    }
@@ -135,7 +265,7 @@
    real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
 }
 
-template<class SegmentManagerBase, bool AlignOnly = false>
+template<class SegmentManagerBase, unsigned int Flags>
 class private_adaptive_node_pool_impl
 {
    //Non-copyable
@@ -147,27 +277,42 @@
    typedef typename SegmentManagerBase::void_pointer void_pointer;
    static const typename SegmentManagerBase::
       size_type PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
+ //Flags
+ //align_only
+ static const bool AlignOnly = (Flags & adaptive_pool_flag::align_only) != 0;
    typedef bool_<AlignOnly> IsAlignOnly;
    typedef true_ AlignOnlyTrue;
    typedef false_ AlignOnlyFalse;
+ //size_ordered
+ static const bool SizeOrdered = (Flags & adaptive_pool_flag::size_ordered) != 0;
+ typedef bool_<SizeOrdered> IsSizeOrdered;
+ typedef true_ SizeOrderedTrue;
+ typedef false_ SizeOrderedFalse;
+ //address_ordered
+ static const bool AddressOrdered = (Flags & adaptive_pool_flag::address_ordered) != 0;
+ typedef bool_<AddressOrdered> IsAddressOrdered;
+ typedef true_ AddressOrderedTrue;
+ typedef false_ AddressOrderedFalse;
 
    public:
- typedef typename node_slist<void_pointer>::node_t node_t;
- typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
- typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
- typedef typename SegmentManagerBase::size_type size_type;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
+ typedef typename SegmentManagerBase::size_type size_type;
 
    private:
- typedef typename adaptive_pool_types<void_pointer, size_type>::block_info_t block_info_t;
- typedef typename adaptive_pool_types<void_pointer, size_type>::block_multiset_t block_multiset_t;
- typedef typename block_multiset_t::iterator block_iterator;
- typedef typename adaptive_pool_types<void_pointer, size_type>::hdr_offset_holder hdr_offset_holder;
+ typedef adaptive_pool_types
+ <multiallocation_chain, void_pointer, size_type, Flags> adaptive_pool_types_t;
+ typedef typename adaptive_pool_types_t::free_nodes_t free_nodes_t;
+ typedef typename adaptive_pool_types_t::block_info_t block_info_t;
+ typedef typename adaptive_pool_types_t::block_container_t block_container_t;
+ typedef typename adaptive_pool_types_t::block_container_traits_t block_container_traits_t;
+ typedef typename block_container_t::iterator block_iterator;
+ typedef typename block_container_t::const_iterator const_block_iterator;
+ typedef typename adaptive_pool_types_t::hdr_offset_holder hdr_offset_holder;
 
- static const size_type MaxAlign = alignment_of<node_t>::value;
+ static const size_type MaxAlign = alignment_of<void_pointer>::value;
    static const size_type HdrSize = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
    static const size_type HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
 
-
    public:
    //!Segment manager typedef
    typedef SegmentManagerBase segment_manager_base_type;
@@ -181,7 +326,7 @@
       , unsigned char overhead_percent
       )
    : m_max_free_blocks(max_free_blocks)
- , m_real_node_size(lcm(node_size, size_type(alignment_of<node_t>::value)))
+ , m_real_node_size(lcm(node_size, size_type(alignment_of<void_pointer>::value)))
       //Round the size to a power of two value.
       //This is the total memory size (including payload) that we want to
       //allocate from the general-purpose allocator
@@ -195,7 +340,7 @@
    , m_real_num_node(AlignOnly ? (m_real_block_alignment - PayloadPerAllocation - HdrSize)/m_real_node_size : 0)
       //General purpose allocator
    , mp_segment_mngr_base(segment_mngr_base)
- , m_block_multiset()
+ , m_block_container()
    , m_totally_free_blocks(0)
    {
       if(!AlignOnly){
@@ -214,7 +359,7 @@
 
    //!Destructor. Deallocates all allocated blocks. Never throws
    ~private_adaptive_node_pool_impl()
- { priv_clear(); }
+ { this->priv_clear(); }
 
    size_type get_real_num_node() const
    { return m_real_num_node; }
@@ -226,84 +371,157 @@
    //!Allocates array of count elements. Can throw
    void *allocate_node()
    {
- priv_invariants();
+ this->priv_invariants();
       //If there are no free nodes we allocate a new block
- if (m_block_multiset.empty()){
- priv_alloc_block(1);
+ if(!m_block_container.empty()){
+ //We take the first free node the multiset can't be empty
+ free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
+ BOOST_ASSERT(!free_nodes.empty());
+ const size_type free_nodes_count = free_nodes.size();
+ void *first_node = container_detail::to_raw_pointer(free_nodes.pop_front());
+ if(free_nodes.empty()){
+ block_container_traits_t::erase_first(m_block_container);
+ }
+ m_totally_free_blocks -= static_cast<size_type>(free_nodes_count == m_real_num_node);
+ this->priv_invariants();
+ return first_node;
+ }
+ else{
+ multiallocation_chain chain;
+ this->priv_append_from_new_blocks(1, chain, IsAlignOnly());
+ return container_detail::to_raw_pointer(chain.pop_front());
       }
- //We take the first free node the multiset can't be empty
- return priv_take_first_node();
    }
 
    //!Deallocates an array pointed by ptr. Never throws
    void deallocate_node(void *pElem)
    {
- multiallocation_chain chain;
- chain.push_front(void_pointer(pElem));
- this->priv_reinsert_nodes_in_block(chain, 1);
- //Update free block count<
- if(m_totally_free_blocks > m_max_free_blocks){
- this->priv_deallocate_free_blocks(m_max_free_blocks);
- }
- priv_invariants();
+ this->priv_invariants();
+ block_info_t &block_info = *this->priv_block_from_node(pElem);
+ BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
+
+ //We put the node at the beginning of the free node list
+ block_info.free_nodes.push_back(void_pointer(pElem));
+
+ //The loop reinserts all blocks except the last one
+ this->priv_reinsert_block(block_info, block_info.free_nodes.size() == 1);
+ this->priv_deallocate_free_blocks(m_max_free_blocks);
+ this->priv_invariants();
    }
 
    //!Allocates n nodes.
    //!Can throw
- multiallocation_chain allocate_nodes(const size_type n)
+ void allocate_nodes(const size_type n, multiallocation_chain &chain)
    {
- multiallocation_chain chain;
       size_type i = 0;
- try{
- priv_invariants();
+ BOOST_TRY{
+ this->priv_invariants();
          while(i != n){
             //If there are no free nodes we allocate all needed blocks
- if (m_block_multiset.empty()){
- priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
+ if (m_block_container.empty()){
+ this->priv_append_from_new_blocks(n - i, chain, IsAlignOnly());
+ BOOST_ASSERT(m_block_container.empty() || (++m_block_container.cbegin() == m_block_container.cend()));
+ BOOST_ASSERT(chain.size() == n);
+ break;
             }
- free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+ free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
             const size_type free_nodes_count_before = free_nodes.size();
- if(free_nodes_count_before == m_real_num_node){
- --m_totally_free_blocks;
- }
- const size_type num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
- for(size_type j = 0; j != num_elems; ++j){
- void *new_node = &free_nodes.front();
- free_nodes.pop_front();
- chain.push_back(new_node);
+ m_totally_free_blocks -= static_cast<size_type>(free_nodes_count_before == m_real_num_node);
+ const size_type num_left = n-i;
+ const size_type num_elems = (num_left < free_nodes_count_before) ? num_left : free_nodes_count_before;
+ typedef typename free_nodes_t::iterator free_nodes_iterator;
+
+ if(num_left < free_nodes_count_before){
+ const free_nodes_iterator it_bbeg(free_nodes.before_begin());
+ free_nodes_iterator it_bend(it_bbeg);
+ for(size_type j = 0; j != num_elems; ++j){
+ ++it_bend;
+ }
+ free_nodes_iterator it_end = it_bend; ++it_end;
+ free_nodes_iterator it_beg = it_bbeg; ++it_beg;
+ free_nodes.erase_after(it_bbeg, it_end, num_elems);
+ chain.incorporate_after(chain.last(), &*it_beg, &*it_bend, num_elems);
+ //chain.splice_after(chain.last(), free_nodes, it_bbeg, it_bend, num_elems);
+ BOOST_ASSERT(!free_nodes.empty());
             }
-
- if(free_nodes.empty()){
- m_block_multiset.erase(m_block_multiset.begin());
+ else{
+ const free_nodes_iterator it_beg(free_nodes.begin()), it_bend(free_nodes.last());
+ free_nodes.clear();
+ chain.incorporate_after(chain.last(), &*it_beg, &*it_bend, num_elems);
+ block_container_traits_t::erase_first(m_block_container);
             }
             i += num_elems;
          }
       }
- catch(...){
- this->deallocate_nodes(boost::move(chain));
- throw;
+ BOOST_CATCH(...){
+ this->deallocate_nodes(chain);
+ BOOST_RETHROW
       }
- priv_invariants();
- return boost::move(chain);
+ BOOST_CATCH_END
+ this->priv_invariants();
    }
 
    //!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain nodes)
+ void deallocate_nodes(multiallocation_chain &nodes)
    {
- this->priv_reinsert_nodes_in_block(nodes, nodes.size());
- if(m_totally_free_blocks > m_max_free_blocks){
+ this->priv_invariants();
+ //To take advantage of node locality, wait until two
+ //nodes belong to different blocks. Only then reinsert
+ //the block of the first node in the block tree.
+ //Cache of the previous block
+ block_info_t *prev_block_info = 0;
+
+ //If block was empty before this call, it's not already
+ //inserted in the block tree.
+ bool prev_block_was_empty = false;
+ typedef typename free_nodes_t::iterator free_nodes_iterator;
+ {
+ const free_nodes_iterator itbb(nodes.before_begin()), ite(nodes.end());
+ free_nodes_iterator itf(nodes.begin()), itbf(itbb);
+ size_type splice_node_count = size_type(-1);
+ while(itf != ite){
+ void *pElem = container_detail::to_raw_pointer(&*itf);
+ block_info_t &block_info = *this->priv_block_from_node(pElem);
+ BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
+ ++splice_node_count;
+
+ //If block change is detected calculate the cached block position in the tree
+ if(&block_info != prev_block_info){
+ if(prev_block_info){ //Make sure we skip the initial "dummy" cache
+ free_nodes_iterator it(itbb); ++it;
+ nodes.erase_after(itbb, itf, splice_node_count);
+ prev_block_info->free_nodes.incorporate_after(prev_block_info->free_nodes.last(), &*it, &*itbf, splice_node_count);
+ this->priv_reinsert_block(*prev_block_info, prev_block_was_empty);
+ splice_node_count = 0;
+ }
+ //Update cache with new data
+ prev_block_was_empty = block_info.free_nodes.empty();
+ prev_block_info = &block_info;
+ }
+ itbf = itf;
+ ++itf;
+ }
+ }
+ if(prev_block_info){
+ //The loop reinserts all blocks except the last one
+ const free_nodes_iterator itfirst(nodes.begin()), itlast(nodes.last());
+ const size_type splice_node_count = nodes.size();
+ nodes.clear();
+ prev_block_info->free_nodes.incorporate_after(prev_block_info->free_nodes.last(), &*itfirst, &*itlast, splice_node_count);
+ this->priv_reinsert_block(*prev_block_info, prev_block_was_empty);
+ this->priv_invariants();
          this->priv_deallocate_free_blocks(m_max_free_blocks);
       }
    }
 
    void deallocate_free_blocks()
- { this->priv_deallocate_free_blocks(0); }
+ { this->priv_deallocate_free_blocks(0); }
 
    size_type num_free_nodes()
    {
- typedef typename block_multiset_t::const_iterator citerator;
+ typedef typename block_container_t::const_iterator citerator;
       size_type count = 0;
- citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
+ citerator it (m_block_container.begin()), itend(m_block_container.end());
       for(; it != itend; ++it){
          count += it->free_nodes.size();
       }
@@ -318,7 +536,7 @@
       BOOST_ASSERT(m_real_num_node == other.m_real_num_node);
       std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
       std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
- m_block_multiset.swap(other.m_block_multiset);
+ m_block_container.swap(other.m_block_container);
    }
 
    //Deprecated, use deallocate_free_blocks
@@ -326,83 +544,54 @@
    { this->priv_deallocate_free_blocks(0); }
 
    private:
+
    void priv_deallocate_free_blocks(size_type max_free_blocks)
+ { //Trampoline function to ease inlining
+ if(m_totally_free_blocks > max_free_blocks){
+ this->priv_deallocate_free_blocks_impl(max_free_blocks);
+ }
+ }
+
+ void priv_deallocate_free_blocks_impl(size_type max_free_blocks)
    {
- priv_invariants();
+ this->priv_invariants();
       //Now check if we've reached the free nodes limit
       //and check if we have free blocks. If so, deallocate as much
       //as we can to stay below the limit
- for( block_iterator itend = m_block_multiset.end()
- ; m_totally_free_blocks > max_free_blocks
- ; --m_totally_free_blocks
- ){
- BOOST_ASSERT(!m_block_multiset.empty());
- block_iterator it = itend;
+ multiallocation_chain chain;
+ {
+ const const_block_iterator itend = m_block_container.cend();
+ const_block_iterator it = itend;
          --it;
- BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
- m_block_multiset.erase_and_dispose(it, block_destroyer(this));
- }
- }
-
- void priv_reinsert_nodes_in_block(multiallocation_chain &chain, size_type n)
- {
- block_iterator block_it(m_block_multiset.end());
- while(n--){
- void *pElem = container_detail::to_raw_pointer(chain.pop_front());
- priv_invariants();
- block_info_t *block_info = this->priv_block_from_node(pElem);
- BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
- //We put the node at the beginning of the free node list
- node_t * to_deallocate = static_cast<node_t*>(pElem);
- block_info->free_nodes.push_front(*to_deallocate);
-
- block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
- block_iterator next_block(this_block);
- ++next_block;
+ size_type totally_free_blocks = m_totally_free_blocks;
 
- //Cache the free nodes from the block
- size_type this_block_free_nodes = this_block->free_nodes.size();
-
- if(this_block_free_nodes == 1){
- m_block_multiset.insert(m_block_multiset.begin(), *block_info);
+ for( ; totally_free_blocks > max_free_blocks; --totally_free_blocks){
+ BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
+ void *addr = priv_first_subblock_from_block(const_cast<block_info_t*>(&*it));
+ --it;
+ block_container_traits_t::erase_last(m_block_container);
+ chain.push_front(void_pointer(addr));
          }
- else{
- block_iterator next_block(this_block);
- ++next_block;
- if(next_block != block_it){
- size_type next_free_nodes = next_block->free_nodes.size();
- if(this_block_free_nodes > next_free_nodes){
- //Now move the block to the new position
- m_block_multiset.erase(this_block);
- m_block_multiset.insert(*block_info);
- }
- }
- }
- //Update free block count
- if(this_block_free_nodes == m_real_num_node){
- ++m_totally_free_blocks;
- }
- priv_invariants();
+ BOOST_ASSERT((m_totally_free_blocks - max_free_blocks) == chain.size());
+ m_totally_free_blocks = max_free_blocks;
       }
+ this->mp_segment_mngr_base->deallocate_many(chain);
    }
 
- node_t *priv_take_first_node()
+ void priv_reinsert_block(block_info_t &prev_block_info, const bool prev_block_was_empty)
    {
- BOOST_ASSERT(m_block_multiset.begin() != m_block_multiset.end());
- //We take the first free node the multiset can't be empty
- free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
- node_t *first_node = &free_nodes.front();
- const size_type free_nodes_count = free_nodes.size();
- BOOST_ASSERT(0 != free_nodes_count);
- free_nodes.pop_front();
- if(free_nodes_count == 1){
- m_block_multiset.erase(m_block_multiset.begin());
+ //Cache the free nodes from the block
+ const size_type this_block_free_nodes = prev_block_info.free_nodes.size();
+ const bool is_full = this_block_free_nodes == m_real_num_node;
+
+ //Update free block count
+ m_totally_free_blocks += static_cast<size_type>(is_full);
+ if(prev_block_was_empty){
+ block_container_traits_t::insert_was_empty(m_block_container, prev_block_info, is_full);
       }
- else if(free_nodes_count == m_real_num_node){
- --m_totally_free_blocks;
+ else{
+ block_container_traits_t::reinsert_was_used(m_block_container, prev_block_info, is_full);
       }
- priv_invariants();
- return first_node;
    }
 
    class block_destroyer;
@@ -411,33 +600,31 @@
    class block_destroyer
    {
       public:
- block_destroyer(const this_type *impl)
- : mp_impl(impl)
+ block_destroyer(const this_type *impl, multiallocation_chain &chain)
+ : mp_impl(impl), m_chain(chain)
       {}
 
- void operator()(typename block_multiset_t::pointer to_deallocate)
+ void operator()(typename block_container_t::pointer to_deallocate)
       { return this->do_destroy(to_deallocate, IsAlignOnly()); }
 
       private:
- void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyTrue)
+ void do_destroy(typename block_container_t::pointer to_deallocate, AlignOnlyTrue)
       {
- size_type free_nodes = to_deallocate->free_nodes.size();
- (void)free_nodes;
- BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
- mp_impl->mp_segment_mngr_base->deallocate(to_deallocate);
+ BOOST_ASSERT(to_deallocate->free_nodes.size() == mp_impl->m_real_num_node);
+ m_chain.push_back(to_deallocate);
       }
 
- void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyFalse)
+ void do_destroy(typename block_container_t::pointer to_deallocate, AlignOnlyFalse)
       {
- size_type free_nodes = to_deallocate->free_nodes.size();
- (void)free_nodes;
- BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
+ BOOST_ASSERT(to_deallocate->free_nodes.size() == mp_impl->m_real_num_node);
          BOOST_ASSERT(0 == to_deallocate->hdr_offset);
- hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
- mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
+ hdr_offset_holder *hdr_off_holder =
+ mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
+ m_chain.push_back(hdr_off_holder);
       }
 
       const this_type *mp_impl;
+ multiallocation_chain &m_chain;
    };
 
    //This macro will activate invariant checking. Slow, but helpful for debugging the code.
@@ -446,44 +633,45 @@
    #ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
    #undef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
    {
- //We iterate through the block tree to free the memory
- block_iterator it(m_block_multiset.begin()),
- itend(m_block_multiset.end()), to_deallocate;
- if(it != itend){
- for(++it; it != itend; ++it){
- block_iterator prev(it);
- --prev;
- size_type sp = prev->free_nodes.size(),
- si = it->free_nodes.size();
- BOOST_ASSERT(sp <= si);
- (void)sp; (void)si;
- }
- }
- //Check that the total free nodes are correct
- it = m_block_multiset.begin();
- itend = m_block_multiset.end();
- size_type total_free_nodes = 0;
- for(; it != itend; ++it){
- total_free_nodes += it->free_nodes.size();
- }
- BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+ const const_block_iterator itend(m_block_container.end());
 
- //Check that the total totally free blocks are correct
- it = m_block_multiset.begin();
- itend = m_block_multiset.end();
- total_free = 0;
- for(; it != itend; ++it){
- total_free += it->free_nodes.size() == m_real_num_node;
+ { //We iterate through the block tree to free the memory
+ const_block_iterator it(m_block_container.begin());
+
+ if(it != itend){
+ for(++it; it != itend; ++it){
+ const_block_iterator prev(it);
+ --prev;
+ BOOST_ASSERT(*prev < *it);
+ (void)prev; (void)it;
+ }
+ }
+ }
+ { //Check that the total free nodes are correct
+ const_block_iterator it(m_block_container.cbegin());
+ size_type total_free_nodes = 0;
+ for(; it != itend; ++it){
+ total_free_nodes += it->free_nodes.size();
+ }
+ BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+ }
+ { //Check that the total totally free blocks are correct
+ BOOST_ASSERT(m_block_container.size() >= m_totally_free_blocks);
+ const_block_iterator it = m_block_container.cend();
+ size_type total_free_blocks = m_totally_free_blocks;
+ while(total_free_blocks--){
+ BOOST_ASSERT((--it)->free_nodes.size() == m_real_num_node);
+ }
       }
- BOOST_ASSERT(total_free >= m_totally_free_blocks);
 
       if(!AlignOnly){
          //Check that header offsets are correct
- it = m_block_multiset.begin();
+ const_block_iterator it = m_block_container.begin();
          for(; it != itend; ++it){
- hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
+ hdr_offset_holder *hdr_off_holder = this->priv_first_subblock_from_block(const_cast<block_info_t *>(&*it));
             for(size_type i = 0, max = m_num_subblocks; i < max; ++i){
- BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
+ const size_type offset = reinterpret_cast<char*>(const_cast<block_info_t *>(&*it)) - reinterpret_cast<char*>(hdr_off_holder);
+ BOOST_ASSERT(hdr_off_holder->hdr_offset == offset);
                BOOST_ASSERT(0 == ((size_type)hdr_off_holder & (m_real_block_alignment - 1)));
                BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
                hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
@@ -499,19 +687,21 @@
    void priv_clear()
    {
       #ifndef NDEBUG
- block_iterator it = m_block_multiset.begin();
- block_iterator itend = m_block_multiset.end();
- size_type num_free_nodes = 0;
+ block_iterator it = m_block_container.begin();
+ block_iterator itend = m_block_container.end();
+ size_type n_free_nodes = 0;
       for(; it != itend; ++it){
          //Check for memory leak
          BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
- ++num_free_nodes;
+ ++n_free_nodes;
       }
- BOOST_ASSERT(num_free_nodes == m_totally_free_blocks);
+ BOOST_ASSERT(n_free_nodes == m_totally_free_blocks);
       #endif
       //Check for memory leaks
- priv_invariants();
- m_block_multiset.clear_and_dispose(block_destroyer(this));
+ this->priv_invariants();
+ multiallocation_chain chain;
+ m_block_container.clear_and_dispose(block_destroyer(this, chain));
+ this->mp_segment_mngr_base->deallocate_many(chain);
       m_totally_free_blocks = 0;
    }
 
@@ -533,93 +723,129 @@
    }
 
    block_info_t *priv_block_from_node(void *node) const
- { return priv_block_from_node(node, IsAlignOnly()); }
+ { return this->priv_block_from_node(node, IsAlignOnly()); }
 
    hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
+ { return this->priv_first_subblock_from_block(block, IsAlignOnly()); }
+
+ hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, AlignOnlyFalse) const
    {
- hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
+ hdr_offset_holder *const hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
             (reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
       BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
- BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
       BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
       return hdr_off_holder;
    }
 
+ hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, AlignOnlyTrue) const
+ {
+ return reinterpret_cast<hdr_offset_holder*>(block);
+ }
+
+ void priv_dispatch_block_chain_or_free
+ ( multiallocation_chain &chain, block_info_t &c_info, size_type num_node
+ , char *mem_address, size_type total_elements, bool insert_block_if_free)
+ {
+ BOOST_ASSERT(chain.size() <= total_elements);
+ //First add all possible nodes to the chain
+ const size_type left = total_elements - chain.size();
+ const size_type max_chain = (num_node < left) ? num_node : left;
+ mem_address = static_cast<char *>(container_detail::to_raw_pointer
+ (chain.incorporate_after(chain.last(), void_pointer(mem_address), m_real_node_size, max_chain)));
+ //Now store remaining nodes in the free list
+ if(const size_type max_free = num_node - max_chain){
+ free_nodes_t & free_nodes = c_info.free_nodes;
+ free_nodes.incorporate_after(free_nodes.last(), void_pointer(mem_address), m_real_node_size, max_free);
+ if(insert_block_if_free){
+ m_block_container.push_front(c_info);
+ }
+ }
+ }
+
    //!Allocates a several blocks of nodes. Can throw
- void priv_alloc_block(size_type n, AlignOnlyTrue)
+ void priv_append_from_new_blocks(size_type min_elements, multiallocation_chain &chain, AlignOnlyTrue)
    {
- size_type real_block_size = m_real_block_alignment - PayloadPerAllocation;
+ BOOST_ASSERT(m_block_container.empty());
+ BOOST_ASSERT(min_elements > 0);
+ const size_type n = (min_elements - 1)/m_real_num_node + 1;
+ const size_type real_block_size = m_real_block_alignment - PayloadPerAllocation;
+ const size_type total_elements = chain.size() + min_elements;
       for(size_type i = 0; i != n; ++i){
          //We allocate a new NodeBlock and put it the last
          //element of the tree
          char *mem_address = static_cast<char*>
             (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
- if(!mem_address) throw std::bad_alloc();
- ++m_totally_free_blocks;
- block_info_t *c_info = new(mem_address)block_info_t();
- m_block_multiset.insert(m_block_multiset.end(), *c_info);
-
+ if(!mem_address){
+ //In case of error, free memory deallocating all nodes (the new ones allocated
+ //in this function plus previously stored nodes in chain).
+ this->deallocate_nodes(chain);
+ throw std::bad_alloc();
+ }
+ block_info_t &c_info = *new(mem_address)block_info_t();
          mem_address += HdrSize;
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
- for(size_type i = 0; i < m_real_num_node; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *(node_t*)mem_address);
- mem_address += m_real_node_size;
+ if(i != (n-1)){
+ chain.incorporate_after(chain.last(), void_pointer(mem_address), m_real_node_size, m_real_num_node);
+ }
+ else{
+ this->priv_dispatch_block_chain_or_free(chain, c_info, m_real_num_node, mem_address, total_elements, true);
          }
       }
    }
 
- void priv_alloc_block(size_type n, AlignOnlyFalse)
+ void priv_append_from_new_blocks(size_type min_elements, multiallocation_chain &chain, AlignOnlyFalse)
    {
- size_type real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
- size_type elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
- size_type hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+ BOOST_ASSERT(m_block_container.empty());
+ BOOST_ASSERT(min_elements > 0);
+ const size_type n = (min_elements - 1)/m_real_num_node + 1;
+ const size_type real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
+ const size_type elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
+ const size_type hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+ const size_type total_elements = chain.size() + min_elements;
 
       for(size_type i = 0; i != n; ++i){
          //We allocate a new NodeBlock and put it the last
          //element of the tree
          char *mem_address = static_cast<char*>
             (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
- if(!mem_address) throw std::bad_alloc();
- ++m_totally_free_blocks;
-
+ if(!mem_address){
+ //In case of error, free memory deallocating all nodes (the new ones allocated
+ //in this function plus previously stored nodes in chain).
+ this->deallocate_nodes(chain);
+ throw std::bad_alloc();
+ }
          //First initialize header information on the last subblock
          char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
- block_info_t *c_info = new(hdr_addr)block_info_t();
+ block_info_t &c_info = *new(hdr_addr)block_info_t();
          //Some structural checks
- BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
- static_cast<void*>(c_info));
- typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
- for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
- ; subblock < maxsubblock
- ; ++subblock, mem_address += m_real_block_alignment){
- //Initialize header offset mark
- new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
- char *pNode = mem_address + HdrOffsetSize;
- for(size_type i = 0; i < elements_per_subblock; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
- pNode += m_real_node_size;
+ BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder&>(c_info).hdr_offset) ==
+ static_cast<void*>(&c_info)); (void)c_info;
+ if(i != (n-1)){
+ for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
+ ; subblock < maxsubblock
+ ; ++subblock, mem_address += m_real_block_alignment){
+ //Initialize header offset mark
+ new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+ chain.incorporate_after
+ (chain.last(), void_pointer(mem_address + HdrOffsetSize), m_real_node_size, elements_per_subblock);
             }
+ chain.incorporate_after(chain.last(), void_pointer(hdr_addr + HdrSize), m_real_node_size, hdr_subblock_elements);
          }
- {
- char *pNode = hdr_addr + HdrSize;
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- for(size_type i = 0; i < hdr_subblock_elements; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
- pNode += m_real_node_size;
+ else{
+ for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
+ ; subblock < maxsubblock
+ ; ++subblock, mem_address += m_real_block_alignment){
+ //Initialize header offset mark
+ new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+ this->priv_dispatch_block_chain_or_free
+ (chain, c_info, elements_per_subblock, mem_address + HdrOffsetSize, total_elements, false);
             }
+ this->priv_dispatch_block_chain_or_free
+ (chain, c_info, hdr_subblock_elements, hdr_addr + HdrSize, total_elements, true);
          }
- //Insert the block after the free node list is full
- m_block_multiset.insert(m_block_multiset.end(), *c_info);
       }
    }
 
- //!Allocates a block of nodes. Can throw std::bad_alloc
- void priv_alloc_block(size_type n)
- { return priv_alloc_block(n, IsAlignOnly()); }
-
    private:
    typedef typename boost::intrusive::pointer_traits
       <void_pointer>::template rebind_pointer<segment_manager_base_type>::type segment_mngr_base_ptr_t;
@@ -633,9 +859,9 @@
    //This is the real number of nodes per block
    //const
    size_type m_real_num_node;
- segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
- block_multiset_t m_block_multiset; //Intrusive block list
- size_type m_totally_free_blocks; //Free blocks
+ segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
+ block_container_t m_block_container; //Intrusive block list
+ size_type m_totally_free_blocks; //Free blocks
 };
 
 } //namespace container_detail {

Modified: trunk/boost/container/detail/advanced_insert_int.hpp
==============================================================================
--- trunk/boost/container/detail/advanced_insert_int.hpp (original)
+++ trunk/boost/container/detail/advanced_insert_int.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -20,160 +20,177 @@
 #include <boost/container/allocator_traits.hpp>
 #include <boost/container/detail/destroyers.hpp>
 #include <boost/aligned_storage.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <iterator> //std::iterator_traits
 #include <boost/assert.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 
 namespace boost { namespace container { namespace container_detail {
 
-//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
-template<class Iterator>
-struct advanced_insert_aux_int
+template<class A, class FwdIt, class Iterator>
+struct insert_range_proxy
 {
- typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
- virtual void copy_remaining_to(Iterator p) = 0;
- virtual void uninitialized_copy_remaining_to(Iterator p) = 0;
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
- virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
- virtual ~advanced_insert_aux_int() {}
+ typedef typename allocator_traits<A>::size_type size_type;
+ typedef typename allocator_traits<A>::value_type value_type;
+
+ insert_range_proxy(A& a, FwdIt first)
+ : a_(a), first_(first)
+ {}
+
+ void uninitialized_copy_n_and_update(Iterator pos, size_type n)
+ {
+ this->first_ = ::boost::container::uninitialized_copy_or_move_alloc_n_source
+ (this->a_, this->first_, n, pos);
+ }
+
+ void copy_n_and_update(Iterator pos, size_type n)
+ {
+ this->first_ = ::boost::container::copy_or_move_n_source(this->first_, n, pos);
+ }
+
+ A &a_;
+ FwdIt first_;
 };
 
-//This class template will adapt each FwIt types to advanced_insert_aux_int
-template<class A, class FwdIt, class Iterator>
-struct advanced_insert_aux_proxy
- : public advanced_insert_aux_int<Iterator>
+
+template<class A, class Iterator>
+struct insert_n_copies_proxy
 {
    typedef typename allocator_traits<A>::size_type size_type;
    typedef typename allocator_traits<A>::value_type value_type;
- typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
 
- advanced_insert_aux_proxy(A& a, FwdIt first, FwdIt last)
- : a_(a), first_(first), last_(last)
+ insert_n_copies_proxy(A& a, const value_type &v)
+ : a_(a), v_(v)
    {}
 
- virtual ~advanced_insert_aux_proxy()
- {}
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
+ { std::uninitialized_fill_n(p, n, v_); }
 
- virtual void copy_remaining_to(Iterator p)
- { ::boost::copy_or_move(this->first_, this->last_, p); }
+ void copy_n_and_update(Iterator p, size_type n)
+ { std::fill_n(p, n, v_); }
 
- virtual void uninitialized_copy_remaining_to(Iterator p)
- { ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); }
+ A &a_;
+ const value_type &v_;
+};
 
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+template<class A, class Iterator>
+struct insert_default_constructed_n_proxy
+{
+ typedef ::boost::container::allocator_traits<A> alloc_traits;
+ typedef typename allocator_traits<A>::size_type size_type;
+ typedef typename allocator_traits<A>::value_type value_type;
+
+
+ explicit insert_default_constructed_n_proxy(A &a)
+ : a_(a)
+ {}
+
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
    {
- FwdIt mid = this->first_;
- std::advance(mid, division_count);
- if(first_n){
- ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
- this->first_ = mid;
+ Iterator orig_p = p;
+ size_type n_left = n;
+ BOOST_TRY{
+ for(; n_left--; ++p){
+ alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
+ }
       }
- else{
- ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
- this->last_ = mid;
+ BOOST_CATCH(...){
+ for(; orig_p != p; ++orig_p){
+ alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
+ }
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
    }
 
- virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ void copy_n_and_update(Iterator, size_type)
    {
- FwdIt mid = this->first_;
- std::advance(mid, division_count);
- if(first_n){
- ::boost::copy_or_move(this->first_, mid, pos);
- this->first_ = mid;
- }
- else{
- ::boost::copy_or_move(mid, this->last_, pos);
- this->last_ = mid;
- }
+ BOOST_ASSERT(false);
    }
+
+ private:
    A &a_;
- FwdIt first_, last_;
 };
 
-//This class template will adapt default construction insertions to advanced_insert_aux_int
 template<class A, class Iterator>
-struct default_construct_aux_proxy
- : public advanced_insert_aux_int<Iterator>
+struct insert_copy_proxy
 {
- typedef ::boost::container::allocator_traits<A> alloc_traits;
- typedef typename allocator_traits<A>::size_type size_type;
- typedef typename allocator_traits<A>::value_type value_type;
- typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
-
- default_construct_aux_proxy(A &a, size_type count)
- : a_(a), count_(count)
- {}
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename alloc_traits::size_type size_type;
+ typedef typename alloc_traits::value_type value_type;
 
- virtual ~default_construct_aux_proxy()
+ insert_copy_proxy(A& a, const value_type &v)
+ : a_(a), v_(v)
    {}
 
- virtual void copy_remaining_to(Iterator)
- { //This should never be called with any count
- BOOST_ASSERT(this->count_ == 0);
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
+ {
+ BOOST_ASSERT(n == 1); (void)n;
+ alloc_traits::construct( this->a_
+ , container_detail::to_raw_pointer(&*p)
+ , v_
+ );
    }
 
- virtual void uninitialized_copy_remaining_to(Iterator p)
- { this->priv_uninitialized_copy(p, this->count_); }
-
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ void copy_n_and_update(Iterator p, size_type n)
    {
- size_type new_count;
- if(first_n){
- new_count = division_count;
- }
- else{
- BOOST_ASSERT(difference_type(this->count_)>= division_count);
- new_count = this->count_ - division_count;
- }
- this->priv_uninitialized_copy(pos, new_count);
+ BOOST_ASSERT(n == 1); (void)n;
+ *p =v_;
    }
 
- virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
+ A &a_;
+ const value_type &v_;
+};
+
+
+template<class A, class Iterator>
+struct insert_move_proxy
+{
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename alloc_traits::size_type size_type;
+ typedef typename alloc_traits::value_type value_type;
+
+ insert_move_proxy(A& a, value_type &v)
+ : a_(a), v_(v)
+ {}
+
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
    {
- BOOST_ASSERT(this->count_ == 0);
- size_type new_count;
- if(first_n){
- new_count = division_count;
- }
- else{
- 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);
- (void)new_count;
+ BOOST_ASSERT(n == 1); (void)n;
+ alloc_traits::construct( this->a_
+ , container_detail::to_raw_pointer(&*p)
+ , ::boost::move(v_)
+ );
    }
 
- private:
- void priv_uninitialized_copy(Iterator p, const size_type n)
+ void copy_n_and_update(Iterator p, size_type n)
    {
- BOOST_ASSERT(n <= this->count_);
- Iterator orig_p = p;
- size_type i = 0;
- try{
- for(; i < n; ++i, ++p){
- alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
- }
- }
- catch(...){
- while(i--){
- alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
- }
- throw;
- }
- this->count_ -= n;
+ BOOST_ASSERT(n == 1); (void)n;
+ *p = ::boost::move(v_);
    }
+
    A &a_;
- size_type count_;
+ value_type &v_;
 };
 
+template<class It, class A>
+insert_move_proxy<A, It> get_insert_value_proxy(A& a, BOOST_RV_REF(typename std::iterator_traits<It>::value_type) v)
+{
+ return insert_move_proxy<A, It>(a, v);
+}
+
+template<class It, class A>
+insert_copy_proxy<A, It> get_insert_value_proxy(A& a, const typename std::iterator_traits<It>::value_type &v)
+{
+ return insert_copy_proxy<A, It>(a, v);
+}
+
 }}} //namespace boost { namespace container { namespace container_detail {
 
 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 
 #include <boost/container/detail/variadic_templates_tools.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <typeinfo>
 //#include <iostream> //For debugging purposes
 
@@ -181,138 +198,74 @@
 namespace container {
 namespace container_detail {
 
-
-//This class template will adapt emplace construction insertions of movable types
-//to advanced_insert_aux_int
 template<class A, class Iterator, class ...Args>
-struct advanced_insert_aux_non_movable_emplace
- : public advanced_insert_aux_int<Iterator>
+struct insert_non_movable_emplace_proxy
 {
- typedef boost::container::allocator_traits<A> alloc_traits;
- typedef typename allocator_traits<A>::size_type size_type;
- typedef typename allocator_traits<A>::value_type value_type;
- typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
- typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename alloc_traits::size_type size_type;
+ typedef typename alloc_traits::value_type value_type;
 
- explicit advanced_insert_aux_non_movable_emplace(A &a, Args&&... args)
- : a_(a)
- , args_(args...)
- , used_(false)
- {}
+ typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
 
- ~advanced_insert_aux_non_movable_emplace()
+ explicit insert_non_movable_emplace_proxy(A &a, Args&&... args)
+ : a_(a), args_(args...)
    {}
 
- virtual void copy_remaining_to(Iterator)
- //This code can't be called since value_type is not movable or copyable
- { BOOST_ASSERT(false); }
-
- virtual void uninitialized_copy_remaining_to(Iterator p)
- { this->priv_uninitialized_copy_remaining_to(index_tuple_t(), p); }
-
- virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
-
- virtual void copy_some_and_update(Iterator, difference_type, bool )
- //This code can't be called since value_type is not movable or copyable
- { BOOST_ASSERT(false); }
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
+ { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, n); }
 
    private:
    template<int ...IdxPack>
- void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
- {
- BOOST_ASSERT(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!this->used_){
- alloc_traits::construct( this->a_
- , container_detail::to_raw_pointer(&*p)
- , ::boost::forward<Args>(get<IdxPack>(this->args_))...
- );
- this->used_ = true;
- }
- }
- }
-
- template<int ...IdxPack>
- void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
+ void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, size_type n)
    {
- if(!this->used_){
- alloc_traits::construct( this->a_
- , container_detail::to_raw_pointer(&*p)
- , ::boost::forward<Args>(get<IdxPack>(this->args_))...
- );
- this->used_ = true;
- }
+ BOOST_ASSERT(n == 1); (void)n;
+ alloc_traits::construct( this->a_
+ , container_detail::to_raw_pointer(&*p)
+ , ::boost::forward<Args>(get<IdxPack>(this->args_))...
+ );
    }
 
    protected:
    A &a_;
    tuple<Args&...> args_;
- bool used_;
 };
 
-//This class template will adapt emplace construction insertions of movable types
-//to advanced_insert_aux_int
 template<class A, class Iterator, class ...Args>
-struct advanced_insert_aux_emplace
- : public advanced_insert_aux_non_movable_emplace<A, Iterator, Args...>
+struct insert_emplace_proxy
+ : public insert_non_movable_emplace_proxy<A, Iterator, Args...>
 {
- typedef advanced_insert_aux_non_movable_emplace<A, Iterator, Args...> base_t;
- typedef boost::container::allocator_traits<A> 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;
+ typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::size_type size_type;
+ typedef typename base_t::index_tuple_t index_tuple_t;
 
- explicit advanced_insert_aux_emplace(A &a, Args&&... args)
+ explicit insert_emplace_proxy(A &a, Args&&... args)
       : base_t(a, ::boost::forward<Args>(args)...)
    {}
 
- ~advanced_insert_aux_emplace()
- {}
-
- //Override only needed functions
- virtual void copy_remaining_to(Iterator p)
- { this->priv_copy_remaining_to(index_tuple_t(), p); }
-
- virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- { this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
+ void copy_n_and_update(Iterator p, size_type n)
+ { this->priv_copy_some_and_update(index_tuple_t(), p, n); }
 
    private:
+
    template<int ...IdxPack>
- void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
+ void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, size_type n)
    {
- if(!this->used_){
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
- alloc_traits::construct(this->a_, vp,
- ::boost::forward<Args>(get<IdxPack>(this->args_))...);
- scoped_destructor<A> d(this->a_, vp);
+ BOOST_ASSERT(n ==1); (void)n;
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
+ alloc_traits::construct(this->a_, vp,
+ ::boost::forward<Args>(get<IdxPack>(this->args_))...);
+ BOOST_TRY{
          *p = ::boost::move(*vp);
- d.release();
- this->used_ = true;
       }
- }
-
- template<int ...IdxPack>
- void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
- {
- BOOST_ASSERT(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!this->used_){
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
- alloc_traits::construct(this->a_, vp,
- ::boost::forward<Args>(get<IdxPack>(this->args_))...);
- try {
- *p = ::boost::move(*vp);
- } catch (...) {
- alloc_traits::destroy(this->a_, vp);
- throw;
- }
- alloc_traits::destroy(this->a_, vp);
- this->used_ = true;
- }
+ BOOST_CATCH(...){
+ alloc_traits::destroy(this->a_, vp);
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
+ alloc_traits::destroy(this->a_, vp);
    }
 };
 
@@ -327,115 +280,73 @@
 namespace container {
 namespace container_detail {
 
-#define BOOST_PP_LOCAL_MACRO(n) \
-template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
-struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \
- : public advanced_insert_aux_int<Iterator> \
+#define BOOST_PP_LOCAL_MACRO(N) \
+template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
+struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
 { \
    typedef boost::container::allocator_traits<A> alloc_traits; \
- typedef typename allocator_traits<A>::size_type size_type; \
- typedef typename allocator_traits<A>::value_type value_type; \
- typedef typename advanced_insert_aux_int<Iterator>::difference_type \
- difference_type; \
+ typedef typename alloc_traits::size_type size_type; \
+ typedef typename alloc_traits::value_type value_type; \
                                                                                     \
- BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \
- ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
+ BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
+ ( A &a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
       : a_(a) \
- , used_(false) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_INIT, _) \
- {} \
- \
- virtual void copy_remaining_to(Iterator) \
- { BOOST_ASSERT(false); } \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
+ {} \
                                                                                     \
- virtual void uninitialized_copy_remaining_to(Iterator p) \
+ void uninitialized_copy_n_and_update(Iterator p, size_type n) \
    { \
- if(!this->used_){ \
- alloc_traits::construct \
- ( this->a_ \
- , container_detail::to_raw_pointer(&*p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- ); \
- this->used_ = true; \
- } \
+ BOOST_ASSERT(n == 1); (void)n; \
+ alloc_traits::construct \
+ ( this->a_ \
+ , container_detail::to_raw_pointer(&*p) \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
+ ); \
    } \
                                                                                     \
- virtual void uninitialized_copy_some_and_update \
- (Iterator p, difference_type division_count, bool first_n) \
- { \
- BOOST_ASSERT(division_count <=1); \
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!this->used_){ \
- alloc_traits::construct \
- ( this->a_ \
- , container_detail::to_raw_pointer(&*p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- ); \
- this->used_ = true; \
- } \
- } \
- } \
- \
- virtual void copy_some_and_update(Iterator, difference_type, bool) \
+ void copy_n_and_update(Iterator, size_type) \
    { BOOST_ASSERT(false); } \
                                                                                     \
+ protected: \
    A &a_; \
- bool used_; \
- BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
+ BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
 }; \
                                                                                     \
-template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
-struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- : BOOST_PP_CAT(BOOST_PP_CAT( \
- advanced_insert_aux_non_movable_emplace, n), arg) \
- < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > \
+template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
+struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
+ : BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
+ < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
 { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT( \
- advanced_insert_aux_non_movable_emplace, n), arg) \
- <A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > base_t; \
+ typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
+ <A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
    typedef typename base_t::value_type value_type; \
- typedef typename base_t::difference_type difference_type; \
+ typedef typename base_t::size_type size_type; \
    typedef boost::container::allocator_traits<A> 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, _) ) \
- : base_t(a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
- {} \
+ BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
+ ( A &a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
+ : base_t(a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
+ {} \
                                                                                     \
- virtual void copy_remaining_to(Iterator p) \
+ void copy_n_and_update(Iterator p, size_type n) \
    { \
- if(!this->used_){ \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
- alloc_traits::construct(this->a_, vp \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
- scoped_destructor<A> d(this->a_, vp); \
+ BOOST_ASSERT(n == 1); (void)n; \
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
+ alloc_traits::construct(this->a_, vp \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
+ BOOST_TRY{ \
          *p = ::boost::move(*vp); \
- d.release(); \
- this->used_ = true; \
       } \
- } \
- \
- virtual void copy_some_and_update \
- (Iterator p, difference_type division_count, bool first_n) \
- { \
- BOOST_ASSERT(division_count <=1); \
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!this->used_){ \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
- alloc_traits::construct(this->a_, vp \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
- scoped_destructor<A> d(this->a_, vp); \
- *p = ::boost::move(*vp); \
- d.release(); \
- this->used_ = true; \
- } \
+ BOOST_CATCH(...){ \
+ alloc_traits::destroy(this->a_, vp); \
+ BOOST_RETHROW \
       } \
+ BOOST_CATCH_END \
+ alloc_traits::destroy(this->a_, vp); \
    } \
 }; \
 //!
-
 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
 #include BOOST_PP_LOCAL_ITERATE()
 

Added: trunk/boost/container/detail/allocator_version_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/container/detail/allocator_version_traits.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-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_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
+#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/allocator_traits.hpp> //allocator_traits
+#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
+#include <boost/container/detail/version_type.hpp> //version_type
+#include <boost/container/detail/allocation_type.hpp> //allocation_type
+#include <boost/container/detail/mpl.hpp> //integral_constant
+#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
+#include <utility> //pair
+#include <stdexcept> //runtime_error
+#include <boost/detail/no_exceptions_support.hpp> //BOOST_TRY
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template<class Allocator, unsigned Version = boost::container::container_detail::version<Allocator>::value>
+struct allocator_version_traits
+{
+ typedef ::boost::container::container_detail::integral_constant
+ <unsigned, Version> alloc_version;
+
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
+
+ typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
+ typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
+
+ //Node allocation interface
+ static pointer allocate_one(Allocator &a)
+ { return a.allocate_one(); }
+
+ static void deallocate_one(Allocator &a, const pointer &p)
+ { a.deallocate_one(p); }
+
+ static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
+ { return a.allocate_individual(n, m); }
+
+ static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
+ { a.deallocate_individual(holder); }
+
+ static std::pair<pointer, bool>
+ allocation_command(Allocator &a, allocation_type command,
+ size_type limit_size, size_type preferred_size,
+ size_type &received_size, const pointer &reuse)
+ {
+ return a.allocation_command
+ (command, limit_size, preferred_size, received_size, reuse);
+ }
+};
+
+template<class Allocator>
+struct allocator_version_traits<Allocator, 1>
+{
+ typedef ::boost::container::container_detail::integral_constant
+ <unsigned, 1> alloc_version;
+
+ typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
+ typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
+ typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
+
+ typedef typename boost::intrusive::pointer_traits<pointer>::
+ template rebind_pointer<void>::type void_ptr;
+ typedef container_detail::basic_multiallocation_chain
+ <void_ptr> multialloc_cached_counted;
+ typedef boost::container::container_detail::
+ transform_multiallocation_chain
+ < multialloc_cached_counted, value_type> multiallocation_chain;
+
+ //Node allocation interface
+ static pointer allocate_one(Allocator &a)
+ { return a.allocate(1); }
+
+ static void deallocate_one(Allocator &a, const pointer &p)
+ { a.deallocate(p, 1); }
+
+ static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
+ {
+ while(!holder.empty()){
+ a.deallocate(holder.pop_front(), 1);
+ }
+ }
+
+ struct allocate_individual_rollback
+ {
+ allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
+ : mr_a(a), mp_chain(&chain)
+ {}
+
+ ~allocate_individual_rollback()
+ {
+ if(mp_chain)
+ allocator_version_traits::deallocate_individual(mr_a, *mp_chain);
+ }
+
+ void release()
+ {
+ mp_chain = 0;
+ }
+
+ Allocator &mr_a;
+ multiallocation_chain * mp_chain;
+ };
+
+ static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
+ {
+ allocate_individual_rollback rollback(a, m);
+ while(n--){
+ m.push_front(a.allocate(1));
+ }
+ rollback.release();
+ }
+
+ static std::pair<pointer, bool>
+ allocation_command(Allocator &a, allocation_type command,
+ size_type, size_type preferred_size,
+ size_type &received_size, const pointer &)
+ {
+ std::pair<pointer, bool> ret(pointer(), false);
+ if(!(command & allocate_new)){
+ if(!(command & nothrow_allocation)){
+ throw std::runtime_error("version 1 allocator without allocate_new flag");
+ }
+ }
+ else{
+ received_size = preferred_size;
+ BOOST_TRY{
+ ret.first = a.allocate(received_size);
+ }
+ BOOST_CATCH(...){
+ if(!(command & nothrow_allocation)){
+ BOOST_RETHROW
+ }
+ }
+ BOOST_CATCH_END
+ }
+ return ret;
+ }
+};
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)

Modified: trunk/boost/container/detail/destroyers.hpp
==============================================================================
--- trunk/boost/container/detail/destroyers.hpp (original)
+++ trunk/boost/container/detail/destroyers.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -188,13 +188,17 @@
 
    void increment_size_backwards(size_type inc)
    { m_n += inc; m_p -= inc; }
+
+ void shrink_forward(size_type inc)
+ { m_n -= inc; m_p += inc; }
   
    ~scoped_destructor_n()
    {
       if(!m_p) return;
       value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
- for(size_type i = 0; i < m_n; ++i, ++raw_ptr)
+ while(m_n--){
          AllocTraits::destroy(m_a, raw_ptr);
+ }
    }
 
    private:
@@ -323,7 +327,7 @@
    void operator()(const typename A::pointer &p)
    {
       allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
- c_.push_front(p);
+ c_.push_back(p);
    }
 };
 
@@ -348,8 +352,7 @@
 
    ~allocator_multialloc_chain_node_deallocator()
    {
- if(!c_.empty())
- a_.deallocate_individual(boost::move(c_));
+ a_.deallocate_individual(c_);
    }
 };
 

Modified: trunk/boost/container/detail/flat_tree.hpp
==============================================================================
--- trunk/boost/container/detail/flat_tree.hpp (original)
+++ trunk/boost/container/detail/flat_tree.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -25,7 +25,7 @@
 #include <utility>
 
 #include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 
 #include <boost/container/detail/utilities.hpp>
 #include <boost/container/detail/pair.hpp>
@@ -48,7 +48,7 @@
    typedef Value first_argument_type;
    typedef Value second_argument_type;
    typedef bool return_type;
- public:
+ public:
    flat_tree_value_compare()
       : Compare()
    {}
@@ -65,7 +65,7 @@
 
    const Compare &get_comp() const
       { return *this; }
-
+
    Compare &get_comp()
       { return *this; }
 };
@@ -238,7 +238,7 @@
    flat_tree& operator=(BOOST_RV_REF(flat_tree) mx)
    { m_data = boost::move(mx.m_data); return *this; }
 
- public:
+ public:
    // accessors:
    Compare key_comp() const
    { return this->m_data.get_comp(); }
@@ -441,17 +441,17 @@
 
       //Prereserve all memory so that iterators are not invalidated
       this->reserve(this->size()+len);
- const const_iterator beg(this->cbegin());
- const_iterator pos(beg);
+ const const_iterator b(this->cbegin());
+ const_iterator pos(b);
       //Loop in burst sizes
       while(len){
          const size_type burst = len < BurstSize ? len : BurstSize;
- const const_iterator cend_(this->cend());
+ const const_iterator ce(this->cend());
          len -= burst;
          for(size_type i = 0; i != burst; ++i){
             //Get the insertion position for each key
- pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, cend_, KeyOfValue()(*first));
- positions[i] = static_cast<size_type>(pos - beg);
+ pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, ce, KeyOfValue()(*first));
+ positions[i] = static_cast<size_type>(pos - b);
             ++first;
          }
          //Insert all in a single step in the precalculated positions
@@ -489,22 +489,22 @@
 
       //Prereserve all memory so that iterators are not invalidated
       this->reserve(this->size()+len);
- const const_iterator beg(this->cbegin());
- const_iterator pos(beg);
+ const const_iterator b(this->cbegin());
+ const_iterator pos(b);
       const value_compare &value_comp = this->m_data;
       skips[0u] = 0u;
       //Loop in burst sizes
       while(len){
          const size_type burst = len < BurstSize ? len : BurstSize;
          size_type unique_burst = 0u;
- const const_iterator cend_(this->cend());
+ const const_iterator ce(this->cend());
          while(unique_burst < burst && len > 0){
             //Get the insertion position for each key
             const value_type & val = *first++;
             --len;
- pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, cend_, KeyOfValue()(val));
+ pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
             //Check if already present
- if(pos != cend_ && !value_comp(val, *pos)){
+ if(pos != ce && !value_comp(val, *pos)){
                if(unique_burst > 0){
                   ++skips[unique_burst-1];
                }
@@ -512,7 +512,7 @@
             }
 
             //If not present, calculate position
- positions[unique_burst] = static_cast<size_type>(pos - beg);
+ positions[unique_burst] = static_cast<size_type>(pos - b);
             skips[unique_burst++] = 0u;
          }
          if(unique_burst){
@@ -692,22 +692,22 @@
    // set operations:
    iterator find(const key_type& k)
    {
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
       iterator i = this->lower_bound(k);
 
- if (i != this->end() && key_comp_(k, KeyOfValue()(*i))){
- i = this->end();
+ if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
+ i = this->end();
       }
       return i;
    }
 
    const_iterator find(const key_type& k) const
    {
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
       const_iterator i = this->lower_bound(k);
 
- if (i != this->end() && key_comp_(k, KeyOfValue()(*i))){
- i = this->end();
+ if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
+ i = this->end();
       }
       return i;
    }
@@ -737,11 +737,11 @@
    std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
    { return this->priv_equal_range(this->begin(), this->end(), k); }
 
- size_type capacity() const
+ size_type capacity() const
    { return this->m_data.m_vect.capacity(); }
 
- void reserve(size_type count_)
- { this->m_data.m_vect.reserve(count_); }
+ void reserve(size_type cnt)
+ { this->m_data.m_vect.reserve(cnt); }
 
    private:
    struct insert_commit_data
@@ -780,13 +780,13 @@
    }
 
    std::pair<iterator,bool> priv_insert_unique_prepare
- (const_iterator beg, const_iterator end_, const value_type& val, insert_commit_data &commit_data)
+ (const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data)
    {
       const value_compare &value_comp = this->m_data;
- commit_data.position = this->priv_lower_bound(beg, end_, KeyOfValue()(val));
+ commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
       return std::pair<iterator,bool>
          ( *reinterpret_cast<iterator*>(&commit_data.position)
- , commit_data.position == end_ || value_comp(val, *commit_data.position));
+ , commit_data.position == e || value_comp(val, *commit_data.position));
    }
 
    std::pair<iterator,bool> priv_insert_unique_prepare
@@ -854,7 +854,7 @@
    RanIt priv_lower_bound(RanIt first, RanIt last,
                           const key_type & key) const
    {
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
       KeyOfValue key_extract;
       difference_type len = last - first, half;
       RanIt middle;
@@ -864,7 +864,7 @@
          middle = first;
          middle += half;
 
- if (key_comp_(key_extract(*middle), key)) {
+ if (key_cmp(key_extract(*middle), key)) {
             ++middle;
             first = middle;
             len = len - half - 1;
@@ -879,7 +879,7 @@
    RanIt priv_upper_bound(RanIt first, RanIt last,
                           const key_type & key) const
    {
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
       KeyOfValue key_extract;
       difference_type len = last - first, half;
       RanIt middle;
@@ -889,12 +889,12 @@
          middle = first;
          middle += half;
 
- if (key_comp_(key, key_extract(*middle))) {
+ if (key_cmp(key, key_extract(*middle))) {
             len = half;
          }
          else{
             first = ++middle;
- len = len - half - 1;
+ len = len - half - 1;
          }
       }
       return first;
@@ -904,7 +904,7 @@
    std::pair<RanIt, RanIt>
       priv_equal_range(RanIt first, RanIt last, const key_type& key) const
    {
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
       KeyOfValue key_extract;
       difference_type len = last - first, half;
       RanIt middle, left, right;
@@ -914,12 +914,12 @@
          middle = first;
          middle += half;
 
- if (key_comp_(key_extract(*middle), key)){
+ if (key_cmp(key_extract(*middle), key)){
             first = middle;
             ++first;
             len = len - half - 1;
          }
- else if (key_comp_(key, key_extract(*middle))){
+ else if (key_cmp(key, key_extract(*middle))){
             len = half;
          }
          else {
@@ -1033,7 +1033,7 @@
 class C, class A>
 struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<K, V, KOV, C, A> >
 {
- static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
 };
 */
 } //namespace boost {

Modified: trunk/boost/container/detail/iterators.hpp
==============================================================================
--- trunk/boost/container/detail/iterators.hpp (original)
+++ trunk/boost/container/detail/iterators.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -20,7 +20,7 @@
 
 #include "config_begin.hpp"
 #include <boost/container/detail/workaround.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <boost/container/allocator_traits.hpp>
 #include <boost/container/detail/type_traits.hpp>
 

Modified: trunk/boost/container/detail/multiallocation_chain.hpp
==============================================================================
--- trunk/boost/container/detail/multiallocation_chain.hpp (original)
+++ trunk/boost/container/detail/multiallocation_chain.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -19,7 +19,7 @@
 #include <boost/intrusive/slist.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/type_traits/make_unsigned.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 
 namespace boost {
 namespace container {
@@ -50,41 +50,38 @@
    typedef typename boost::intrusive::
       pointer_traits<node_ptr> node_ptr_traits;
 
- static node & build_node(const VoidPointer &p)
- {
- return *::new (static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p)))) node;
- }
+ static node & to_node(const VoidPointer &p)
+ { return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
 
- static VoidPointer destroy_node(node &n)
- {
- VoidPointer retptr = node_ptr_traits::pointer_to(n);
- n.~node();
- return retptr;
- }
+ static VoidPointer from_node(node &n)
+ { return node_ptr_traits::pointer_to(n); }
 
- static node_ptr to_node_ptr(VoidPointer p)
+ static node_ptr to_node_ptr(const VoidPointer &p)
    { return node_ptr_traits::static_cast_from(p); }
 
    BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
 
    public:
 
- typedef VoidPointer void_pointer;
- typedef typename slist_impl_t::iterator iterator;
- typedef typename slist_impl_t::size_type size_type;
+ typedef VoidPointer void_pointer;
+ typedef typename slist_impl_t::iterator iterator;
+ typedef typename slist_impl_t::size_type size_type;
 
    basic_multiallocation_chain()
       : slist_impl_()
    {}
 
+ basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
+ : slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
+ {}
+
    basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
- : slist_impl_()
- { slist_impl_.swap(other.slist_impl_); }
+ : slist_impl_(::boost::move(other.slist_impl_))
+ {}
 
    basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
    {
- basic_multiallocation_chain tmp(boost::move(other));
- this->swap(tmp);
+ slist_impl_ = ::boost::move(other.slist_impl_);
       return *this;
    }
 
@@ -110,43 +107,54 @@
    { slist_impl_.clear(); }
 
    iterator insert_after(iterator it, void_pointer m)
- { return slist_impl_.insert_after(it, build_node(m)); }
+ { return slist_impl_.insert_after(it, to_node(m)); }
 
- void push_front(void_pointer m)
- { return slist_impl_.push_front(build_node(m)); }
+ void push_front(const void_pointer &m)
+ { return slist_impl_.push_front(to_node(m)); }
 
- void push_back(void_pointer m)
- { return slist_impl_.push_back(build_node(m)); }
+ void push_back(const void_pointer &m)
+ { return slist_impl_.push_back(to_node(m)); }
 
    void_pointer pop_front()
    {
       node & n = slist_impl_.front();
- void_pointer ret = destroy_node(n);
+ void_pointer ret = from_node(n);
       slist_impl_.pop_front();
       return ret;
    }
 
- void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin_, iterator before_end)
- { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin_, before_end); }
-
- void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin_, iterator before_end, size_type n)
- { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin_, before_end, n); }
+ void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
+ { slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); }
 
    void splice_after(iterator after_this, basic_multiallocation_chain &x)
    { slist_impl_.splice_after(after_this, x.slist_impl_); }
 
- void incorporate_after(iterator after_this, void_pointer begin_ , iterator before_end)
+ void erase_after(iterator before_b, iterator e, size_type n)
+ { slist_impl_.erase_after(before_b, e, n); }
+
+ void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
    {
- slist_impl_.incorporate_after(after_this, to_node_ptr(begin_), to_node_ptr(before_end));
+ typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
+ char_ptr elem = char_pointer_traits::static_cast_from(b);
+ if(num_units){
+ char_ptr prev_elem = elem;
+ elem += unit_bytes;
+ for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
+ ::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem);
+ prev_elem = elem;
+ }
+ slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
+ }
+ return elem;
    }
 
- void incorporate_after(iterator after_this, void_pointer begin_, void_pointer before_end, size_type n)
- { slist_impl_.incorporate_after(after_this, to_node_ptr(begin_), to_node_ptr(before_end), n); }
+ void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
+ { slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); }
 
    void swap(basic_multiallocation_chain &x)
    { slist_impl_.swap(x.slist_impl_); }
 
- static iterator iterator_to(void_pointer p)
+ static iterator iterator_to(const void_pointer &p)
    { return slist_impl_t::s_iterator_to(to_node(p)); }
 
    std::pair<void_pointer, void_pointer> extract_data()
@@ -170,11 +178,13 @@
 
 template<class MultiallocationChain, class T>
 class transform_multiallocation_chain
+ : public MultiallocationChain
 {
    private:
    BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
+ //transform_multiallocation_chain(const transform_multiallocation_chain &);
+ //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
 
- MultiallocationChain holder_;
    typedef typename MultiallocationChain::void_pointer void_pointer;
    typedef typename boost::intrusive::pointer_traits
       <void_pointer> void_pointer_traits;
@@ -193,39 +203,41 @@
    typedef typename MultiallocationChain::size_type size_type;
 
    transform_multiallocation_chain()
- : holder_()
+ : MultiallocationChain()
    {}
 
    transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
- : holder_()
- { this->swap(other); }
+ : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
+ {}
 
    transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
- : holder_(boost::move(other))
+ : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
    {}
 
    transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
    {
- transform_multiallocation_chain tmp(boost::move(other));
- this->swap(tmp);
- return *this;
+ return static_cast<MultiallocationChain&>
+ (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
    }
-
- void push_front(pointer mem)
+/*
+ void push_front(const pointer &mem)
    { holder_.push_front(mem); }
 
+ void push_back(const pointer &mem)
+ { return holder_.push_back(mem); }
+
    void swap(transform_multiallocation_chain &other_chain)
    { holder_.swap(other_chain.holder_); }
 
- void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin_, iterator before_end, size_type n)
- { holder_.splice_after(after_this.base(), x.holder_, before_begin_.base(), before_end.base(), n); }
-
- void incorporate_after(iterator after_this, pointer begin_, pointer before_end, size_type n)
- { holder_.incorporate_after(after_this.base(), begin_, before_end, n); }
+ void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
+ { holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n); }
 
+ void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
+ { holder_.incorporate_after(after_this.base(), b, before_e, n); }
+*/
    pointer pop_front()
- { return cast(holder_.pop_front()); }
-
+ { return cast(this->MultiallocationChain::pop_front()); }
+/*
    bool empty() const
    { return holder_.empty(); }
 
@@ -246,23 +258,21 @@
 
    void clear()
    { holder_.clear(); }
-
+*/
    iterator insert_after(iterator it, pointer m)
- { return iterator(holder_.insert_after(it.base(), m)); }
+ { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
 
- static iterator iterator_to(pointer p)
+ static iterator iterator_to(const pointer &p)
    { return iterator(MultiallocationChain::iterator_to(p)); }
 
    std::pair<pointer, pointer> extract_data()
    {
- std::pair<void_pointer, void_pointer> data(holder_.extract_data());
+ std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data());
       return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
    }
-
- MultiallocationChain extract_multiallocation_chain()
- {
- return MultiallocationChain(boost::move(holder_));
- }
+/*
+ MultiallocationChain &extract_multiallocation_chain()
+ { return holder_; }*/
 };
 
 }}}

Modified: trunk/boost/container/detail/node_alloc_holder.hpp
==============================================================================
--- trunk/boost/container/detail/node_alloc_holder.hpp (original)
+++ trunk/boost/container/detail/node_alloc_holder.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -21,7 +21,7 @@
 #include <utility>
 #include <functional>
 
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <boost/intrusive/options.hpp>
 
 #include <boost/container/detail/version_type.hpp>
@@ -30,6 +30,8 @@
 #include <boost/container/allocator_traits.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 
 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
 #include <boost/container/detail/preprocessor.hpp>
@@ -89,6 +91,7 @@
    typedef typename ICont::const_iterator icont_citerator;
    typedef allocator_destroyer<NodeAlloc> Destroyer;
    typedef allocator_traits<NodeAlloc> NodeAllocTraits;
+ typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
 
    private:
    BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
@@ -151,22 +154,10 @@
    { return allocator_traits_type::max_size(this->node_alloc()); }
 
    NodePtr allocate_one()
- { return this->allocate_one(alloc_version()); }
-
- NodePtr allocate_one(allocator_v1)
- { return this->node_alloc().allocate(1); }
-
- NodePtr allocate_one(allocator_v2)
- { return this->node_alloc().allocate_one(); }
+ { return AllocVersionTraits::allocate_one(this->node_alloc()); }
 
    void deallocate_one(const NodePtr &p)
- { return this->deallocate_one(p, alloc_version()); }
-
- void deallocate_one(const NodePtr &p, allocator_v1)
- { this->node_alloc().deallocate(p, 1); }
-
- void deallocate_one(const NodePtr &p, allocator_v2)
- { this->node_alloc().deallocate_one(p); }
+ { AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
 
    #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 
@@ -235,40 +226,51 @@
    }
 
    template<class FwdIterator, class Inserter>
- FwdIterator allocate_many_and_construct
+ void allocate_many_and_construct
       (FwdIterator beg, difference_type n, Inserter inserter)
    {
- if(n){
- typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+ /*
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ ::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<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
+ return (p);
+ */
+ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
 
- //Try to allocate memory in a single block
- multiallocation_chain mem(this->node_alloc().allocate_individual(n));
- int constructed = 0;
- Node *p = 0;
- BOOST_TRY{
- for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
- p = container_detail::to_raw_pointer(mem.pop_front());
- //This can throw
- constructed = 0;
- 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<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
- //This can throw in some containers (predicate might throw)
- inserter(*p);
- }
+ //Try to allocate memory in a single block
+ typedef typename multiallocation_chain::iterator multialloc_iterator;
+ multiallocation_chain mem;
+ this->node_alloc().allocate_individual(n, mem);
+ multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
+ mem.clear();
+ Node *p = 0;
+ NodeAlloc &nalloc = this->node_alloc();
+ BOOST_TRY{
+ while(n--){
+ p = container_detail::to_raw_pointer(&*itbeg);
+ ++itbeg;
+ //This can throw
+ Deallocator node_deallocator(p, nalloc);
+ boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
+ ++beg;
+ node_deallocator.release();
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(p)) hook_type;
+ //This can throw in some containers (predicate might throw)
+ inserter(*p);
          }
- BOOST_CATCH(...){
- if(constructed){
- allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(p));
- }
- this->node_alloc().deallocate_individual(boost::move(mem));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
       }
- return beg;
+ BOOST_CATCH(...){
+ mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
+ this->node_alloc().deallocate_individual(mem);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
    }
 
    void clear(allocator_v1)
@@ -281,7 +283,7 @@
       this->icont().clear_and_dispose(builder);
       //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
       if(!chain.empty())
- this->node_alloc().deallocate_individual(boost::move(chain));
+ this->node_alloc().deallocate_individual(chain);
    }
 
    icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
@@ -289,8 +291,13 @@
 
    icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
    {
- allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
- return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
+ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+ NodeAlloc & nalloc = this->node_alloc();
+ multiallocation_chain chain;
+ allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
+ icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
+ nalloc.deallocate_individual(chain);
+ return ret_it;
    }
 
    template<class Key, class Comparator>

Modified: trunk/boost/container/detail/node_pool_impl.hpp
==============================================================================
--- trunk/boost/container/detail/node_pool_impl.hpp (original)
+++ trunk/boost/container/detail/node_pool_impl.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -26,10 +26,12 @@
 #include <boost/container/detail/math_functions.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/pool_common.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 #include <boost/assert.hpp>
 #include <cstddef>
 #include <functional> //std::unary_function
 
+
 namespace boost {
 namespace container {
 namespace container_detail {
@@ -85,19 +87,19 @@
    { return container_detail::to_raw_pointer(mp_segment_mngr_base); }
 
    void *allocate_node()
- { return priv_alloc_node(); }
+ { return this->priv_alloc_node(); }
   
    //!Deallocates an array pointed by ptr. Never throws
    void deallocate_node(void *ptr)
- { priv_dealloc_node(ptr); }
+ { this->priv_dealloc_node(ptr); }
 
    //!Allocates a singly linked list of n nodes ending in null pointer.
- multiallocation_chain allocate_nodes(const size_type n)
+ void allocate_nodes(const size_type n, multiallocation_chain &chain)
    {
       //Preallocate all needed blocks to fulfill the request
       size_type cur_nodes = m_freelist.size();
       if(cur_nodes < n){
- priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
+ this->priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
       }
 
       //We just iterate the needed nodes to get the last we'll erase
@@ -118,20 +120,18 @@
 
       //Now take the last erased node and just splice it in the end
       //of the intrusive list that will be traversed by the multialloc iterator.
- multiallocation_chain chain;
       chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
       m_allocated += n;
- return boost::move(chain);
    }
 
- void deallocate_nodes(multiallocation_chain chain)
+ void deallocate_nodes(multiallocation_chain &chain)
    {
       typedef typename multiallocation_chain::iterator iterator;
       iterator it(chain.begin()), itend(chain.end());
       while(it != itend){
          void *pElem = &*it;
          ++it;
- priv_dealloc_node(pElem);
+ this->priv_dealloc_node(pElem);
       }
    }
 
@@ -275,7 +275,7 @@
    {
       //If there are no free nodes we allocate a new block
       if (m_freelist.empty())
- priv_alloc_block();
+ this->priv_alloc_block(1);
       //We take the first free node
       node_t *n = (node_t*)&m_freelist.front();
       m_freelist.pop_front();
@@ -295,14 +295,13 @@
    }
 
    //!Allocates several blocks of nodes. Can throw
- void priv_alloc_block(size_type num_blocks = 1)
+ void priv_alloc_block(size_type num_blocks)
    {
- if(!num_blocks)
- return;
+ BOOST_ASSERT(num_blocks > 0);
       size_type blocksize =
          get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
 
- try{
+ BOOST_TRY{
          for(size_type i = 0; i != num_blocks; ++i){
             //We allocate a new NodeBlock and put it as first
             //element in the free Node list
@@ -313,15 +312,16 @@
 
             //We initialize all Nodes in Node Block to insert
             //them in the free Node list
- for(size_type i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
+ for(size_type j = 0; j < m_nodes_per_block; ++j, pNode += m_real_node_size){
                m_freelist.push_front(*new (pNode) node_t);
             }
          }
       }
- catch(...){
+ BOOST_CATCH(...){
          //to-do: if possible, an efficient way to deallocate allocated blocks
- throw;
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
    }
 
    //!Deprecated, use deallocate_free_blocks

Modified: trunk/boost/container/detail/pair.hpp
==============================================================================
--- trunk/boost/container/detail/pair.hpp (original)
+++ trunk/boost/container/detail/pair.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -27,7 +27,7 @@
 
 #include <utility> //std::pair
 
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <boost/type_traits/is_class.hpp>
 
 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING

Modified: trunk/boost/container/detail/pool_common.hpp
==============================================================================
--- trunk/boost/container/detail/pool_common.hpp (original)
+++ trunk/boost/container/detail/pool_common.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -34,7 +34,7 @@
    typedef slist_hook_t node_t;
 
    typedef typename bi::make_slist
- <node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
+ <node_t, bi::linear<true>, bi::cache_last<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
 };
 
 template<class T>

Modified: trunk/boost/container/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/container/detail/preprocessor.hpp (original)
+++ trunk/boost/container/detail/preprocessor.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -17,6 +17,7 @@
 
 #include <boost/container/detail/config_begin.hpp>
 #include <boost/container/detail/workaround.hpp>
+#include <boost/move/utility.hpp>
 
 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 //#error "This file is not needed when perfect forwarding is available"
@@ -38,6 +39,7 @@
 #include <boost/preprocessor/arithmetic/sub.hpp>
 #include <boost/preprocessor/arithmetic/add.hpp>
 #include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/move/utility.hpp>
 
 #define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
 
@@ -97,7 +99,7 @@
          template<class T>
          struct ref_holder<T &>
          {
- ref_holder(T &t)
+ explicit ref_holder(T &t)
                : t_(t)
             {}
             T &t_;
@@ -107,7 +109,7 @@
          template<class T>
          struct ref_holder<const T>
          {
- ref_holder(const T &t)
+ explicit ref_holder(const T &t)
                : t_(t)
             {}
             const T &t_;
@@ -117,7 +119,7 @@
          template<class T>
          struct ref_holder<const T &&>
          {
- ref_holder(const T &t)
+ explicit ref_holder(const T &t)
                : t_(t)
             {}
             const T &t_;
@@ -127,7 +129,7 @@
          template<class T>
          struct ref_holder
          {
- ref_holder(T &&t)
+ explicit ref_holder(T &&t)
                : t_(t)
             {}
             T &t_;
@@ -137,10 +139,10 @@
          template<class T>
          struct ref_holder<T &&>
          {
- ref_holder(T &&t)
- : t(t)
+ explicit ref_holder(T &&t)
+ : t_(t)
             {}
- T &t;
+ T &t_;
             T && get() { return ::boost::move(t_); }
          };
 

Modified: trunk/boost/container/detail/tree.hpp
==============================================================================
--- trunk/boost/container/detail/tree.hpp (original)
+++ trunk/boost/container/detail/tree.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -15,7 +15,7 @@
 #include <boost/container/detail/workaround.hpp>
 #include <boost/container/container_fwd.hpp>
 
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/detail/no_exceptions_support.hpp>
@@ -28,6 +28,7 @@
 #include <boost/container/detail/pair.hpp>
 #include <boost/container/detail/type_traits.hpp>
 #include <boost/container/allocator_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
 #include <boost/container/detail/preprocessor.hpp>
 #endif
@@ -247,19 +248,20 @@
       {
          if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
             //First recycle a node (this can't throw)
- try{
+ BOOST_TRY{
                //This can throw
                p->do_assign(other.m_data);
                return p;
             }
- catch(...){
+ BOOST_CATCH(...){
                //If there is an exception destroy the whole source
                m_holder.destroy_node(p);
                while((p = m_icont.unlink_leftmost_without_rebalance())){
                   m_holder.destroy_node(p);
                }
- throw;
+ BOOST_RETHROW
             }
+ BOOST_CATCH_END
          }
          else{
             return m_holder.create_node(other.m_data);
@@ -284,19 +286,20 @@
       {
          if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
             //First recycle a node (this can't throw)
- try{
+ BOOST_TRY{
                //This can throw
                p->do_move_assign(const_cast<Node &>(other).m_data);
                return p;
             }
- catch(...){
+ BOOST_CATCH(...){
                //If there is an exception destroy the whole source
                m_holder.destroy_node(p);
                while((p = m_icont.unlink_leftmost_without_rebalance())){
                   m_holder.destroy_node(p);
                }
- throw;
+ BOOST_RETHROW
             }
+ BOOST_CATCH_END
          }
          else{
             return m_holder.create_node(other.m_data);
@@ -1121,7 +1124,7 @@
 struct has_trivial_destructor_after_move
    <boost::container::container_detail::rbtree<K, V, KOV, C, A> >
 {
- static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
 };
 */
 } //namespace boost {

Modified: trunk/boost/container/detail/type_traits.hpp
==============================================================================
--- trunk/boost/container/detail/type_traits.hpp (original)
+++ trunk/boost/container/detail/type_traits.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -21,7 +21,7 @@
 
 #include "config_begin.hpp"
 
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 
 namespace boost {
 namespace container {

Modified: trunk/boost/container/detail/utilities.hpp
==============================================================================
--- trunk/boost/container/detail/utilities.hpp (original)
+++ trunk/boost/container/detail/utilities.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -18,11 +18,14 @@
 #include <boost/type_traits/is_enum.hpp>
 #include <boost/type_traits/is_member_pointer.hpp>
 #include <boost/type_traits/is_class.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/type_traits.hpp>
 #include <boost/container/allocator_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 #include <algorithm>
+#include <iterator>
 
 namespace boost {
 namespace container {
@@ -123,16 +126,6 @@
    enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
 };
 
-template<class T>
-struct move_const_ref_type
- : if_c
-// < ::boost::is_fundamental<T>::value || ::boost::is_pointer<T>::value || ::boost::is_member_pointer<T>::value || ::boost::is_enum<T>::value
- < !::boost::is_class<T>::value
- ,const T &
- ,BOOST_CATCH_CONST_RLVALUE(T)
- >
-{};
-
 } //namespace container_detail {
 
 //////////////////////////////////////////////////////////////////////////////
@@ -154,15 +147,97 @@
     typename F> // F models ForwardIterator
 F uninitialized_move_alloc(A &a, I f, I l, F r)
 {
- while (f != l) {
- allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
- ++f; ++r;
+ F back = r;
+ BOOST_TRY{
+ while (f != l) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_move_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, boost::move(*first));
+//! \endcode
+//!
+//! <b>Returns</b>: result
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+F uninitialized_move_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
    }
+ BOOST_CATCH_END
    return r;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
+// uninitialized_move_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, boost::move(*first));
+//! \endcode
+//!
+//! <b>Returns</b>: first (after incremented)
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+I uninitialized_move_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return f;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
 // uninitialized_copy_alloc
 //
 //////////////////////////////////////////////////////////////////////////////
@@ -180,15 +255,97 @@
     typename F> // F models ForwardIterator
 F uninitialized_copy_alloc(A &a, I f, I l, F r)
 {
- while (f != l) {
- allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
- ++f; ++r;
+ F back = r;
+ BOOST_TRY{
+ while (f != l) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
    }
+ BOOST_CATCH_END
    return r;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 //
+// uninitialized_copy_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, *first);
+//! \endcode
+//!
+//! <b>Returns</b>: result
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+F uninitialized_copy_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, *first);
+//! \endcode
+//!
+//! <b>Returns</b>: first (after incremented)
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+I uninitialized_copy_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return f;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
 // uninitialized_copy_alloc
 //
 //////////////////////////////////////////////////////////////////////////////
@@ -206,10 +363,20 @@
     typename T>
 void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
 {
- while (f != l) {
- allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
- ++f;
+ F back = f;
+ BOOST_TRY{
+ while (f != l) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
+ ++f;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != l; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
    }
+ BOOST_CATCH_END
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -242,6 +409,168 @@
    return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
 }
 
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_or_move_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+F uninitialized_copy_or_move_alloc_n
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_move_alloc_n(a, f, n, r);
+}
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+F uninitialized_copy_or_move_alloc_n
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_copy_alloc_n(a, f, n, r);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_or_move_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+I uninitialized_copy_or_move_alloc_n_source
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_move_alloc_n_source(a, f, n, r);
+}
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+I uninitialized_copy_or_move_alloc_n_source
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_copy_alloc_n_source(a, f, n, r);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (f != l) {
+ *r = ::boost::move(*f);
+ ++f; ++r;
+ }
+ return r;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (f != l) {
+ *r = *f;
+ ++f; ++r;
+ }
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// copy_or_move_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = ::boost::move(*f);
+ ++f; ++r;
+ }
+ return r;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = *f;
+ ++f; ++r;
+ }
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// copy_or_move_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = ::boost::move(*f);
+ ++f; ++r;
+ }
+ return f;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = *f;
+ ++f; ++r;
+ }
+ return f;
+}
 
 } //namespace container {
 } //namespace boost {

Modified: trunk/boost/container/detail/workaround.hpp
==============================================================================
--- trunk/boost/container/detail/workaround.hpp (original)
+++ trunk/boost/container/detail/workaround.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -18,8 +18,12 @@
    #define BOOST_CONTAINER_PERFECT_FORWARDING
 #endif
 
-#if defined(BOOST_NO_CXX11_NOEXCEPT)
- #define BOOST_CONTAINER_NOEXCEPT
+#if defined(BOOST_NO_NOEXCEPT)
+ #if defined(BOOST_MSVC)
+ #define BOOST_CONTAINER_NOEXCEPT throw()
+ #else
+ #define BOOST_CONTAINER_NOEXCEPT
+ #endif
    #define BOOST_CONTAINER_NOEXCEPT_IF(x)
 #else
    #define BOOST_CONTAINER_NOEXCEPT noexcept

Modified: trunk/boost/container/flat_map.hpp
==============================================================================
--- trunk/boost/container/flat_map.hpp (original)
+++ trunk/boost/container/flat_map.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -27,8 +27,8 @@
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/allocator_traits.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 
 namespace boost {
 namespace container {
@@ -251,7 +251,7 @@
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -261,7 +261,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -271,7 +271,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
 
    //////////////////////////////////////////////
@@ -285,7 +285,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -293,7 +293,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -301,7 +301,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -309,7 +309,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -318,7 +318,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -327,7 +327,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -336,7 +336,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -345,7 +345,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -353,7 +353,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -361,7 +361,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -370,7 +370,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -379,7 +379,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
 
    //////////////////////////////////////////////
@@ -393,7 +393,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.empty(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -401,7 +401,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the container.
@@ -409,7 +409,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.max_size(); }
 
    //! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -418,7 +418,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.capacity(); }
 
    //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -428,10 +428,10 @@
    //!
    //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
    //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
    //! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
 
    //! <b>Effects</b>: Tries to deallocate the excess of memory created
    // with previous allocations. The size of the vector is unchanged
@@ -740,7 +740,7 @@
    //! <b>Postcondition</b>: size() == 0.
    //!
    //! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
       { m_flat_tree.clear(); }
 
    //////////////////////////////////////////////
@@ -900,15 +900,15 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
@@ -1099,7 +1099,7 @@
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1109,7 +1109,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1119,7 +1119,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
 
    //////////////////////////////////////////////
@@ -1133,7 +1133,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1141,7 +1141,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -1149,7 +1149,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1157,7 +1157,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -1166,7 +1166,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1175,7 +1175,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1184,7 +1184,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1193,7 +1193,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1201,7 +1201,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1209,7 +1209,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1218,7 +1218,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1227,7 +1227,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
       { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
 
    //////////////////////////////////////////////
@@ -1241,7 +1241,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.empty(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1249,7 +1249,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1257,7 +1257,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.max_size(); }
 
    //! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -1266,7 +1266,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.capacity(); }
 
    //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1276,10 +1276,10 @@
    //!
    //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
    //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
    //! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
 
    //! <b>Effects</b>: Tries to deallocate the excess of memory created
    // with previous allocations. The size of the vector is unchanged
@@ -1516,7 +1516,7 @@
    //! <b>Postcondition</b>: size() == 0.
    //!
    //! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
       { m_flat_tree.clear(); }
 
    //////////////////////////////////////////////
@@ -1655,15 +1655,15 @@
 /// @cond
 
 namespace boost {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class Allocator>
 struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 } //namespace boost {
 
 /// @endcond

Modified: trunk/boost/container/flat_set.hpp
==============================================================================
--- trunk/boost/container/flat_set.hpp (original)
+++ trunk/boost/container/flat_set.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -25,8 +25,8 @@
 #include <boost/container/detail/flat_tree.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/allocator_traits.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 
 namespace boost {
 namespace container {
@@ -197,7 +197,7 @@
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.get_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -207,7 +207,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    { return m_flat_tree.get_stored_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -217,7 +217,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_flat_tree.get_stored_allocator(); }
 
    //////////////////////////////////////////////
@@ -231,7 +231,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -239,7 +239,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.begin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -247,7 +247,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -255,7 +255,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.end(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -264,7 +264,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -273,7 +273,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -282,7 +282,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -291,7 +291,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rend(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -299,7 +299,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.cbegin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -307,7 +307,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.cend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -316,7 +316,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.crbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -325,7 +325,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.crend(); }
 
 
@@ -340,7 +340,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.empty(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -348,7 +348,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the container.
@@ -356,7 +356,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.max_size(); }
 
    //! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -365,7 +365,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.capacity(); }
 
    //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -375,10 +375,10 @@
    //!
    //! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
    //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
    //! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
 
    //! <b>Effects</b>: Tries to deallocate the excess of memory created
    // with previous allocations. The size of the vector is unchanged
@@ -582,7 +582,7 @@
    //! <b>Postcondition</b>: size() == 0.
    //!
    //! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
       { m_flat_tree.clear(); }
 
    //////////////////////////////////////////////
@@ -726,15 +726,15 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class Key, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value &&has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value &&has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
@@ -884,7 +884,7 @@
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_flat_tree.get_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -894,7 +894,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    { return m_flat_tree.get_stored_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -904,7 +904,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_flat_tree.get_stored_allocator(); }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
@@ -912,7 +912,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -928,7 +928,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -936,7 +936,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -944,7 +944,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -952,7 +952,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.cend(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -961,7 +961,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -970,7 +970,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -979,7 +979,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -988,7 +988,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -997,7 +997,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.rend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1006,7 +1006,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.crend(); }
 
    //////////////////////////////////////////////
@@ -1020,7 +1020,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.empty(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1028,7 +1028,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1036,7 +1036,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.max_size(); }
 
    //! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -1045,7 +1045,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
       { return m_flat_tree.capacity(); }
 
    //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1055,10 +1055,10 @@
    //!
    //! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
    //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
    //! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
 
    //! <b>Effects</b>: Tries to deallocate the excess of memory created
    // with previous allocations. The size of the vector is unchanged
@@ -1244,7 +1244,7 @@
    //! <b>Postcondition</b>: size() == 0.
    //!
    //! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
       { m_flat_tree.clear(); }
 
    //////////////////////////////////////////////
@@ -1388,15 +1388,15 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class Key, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 /// @endcond

Modified: trunk/boost/container/list.hpp
==============================================================================
--- trunk/boost/container/list.hpp (original)
+++ trunk/boost/container/list.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -18,8 +18,9 @@
 #include <boost/container/detail/workaround.hpp>
 #include <boost/container/container_fwd.hpp>
 #include <boost/container/detail/version_type.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/container/detail/utilities.hpp>
 #include <boost/container/detail/algorithms.hpp>
@@ -140,9 +141,6 @@
    friend bool operator!= (const list_const_iterator& l, const list_const_iterator& r)
    { return l.m_it != r.m_it; }
 
- IIterator &get()
- { return this->m_it; }
-
    const IIterator &get() const
    { return this->m_it; }
 };
@@ -187,9 +185,6 @@
    list_iterator operator--(int)
    { IIterator tmp = this->m_it; --*this; return list_iterator(tmp); }
 
- IIterator &get()
- { return this->m_it; }
-
    const IIterator &get() const
    { return this->m_it; }
 };
@@ -303,10 +298,10 @@
 
    //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
    //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
- explicit list(const allocator_type &a)
+ explicit list(const allocator_type &a) BOOST_CONTAINER_NOEXCEPT
       : AllocHolder(a)
    {}
 
@@ -398,7 +393,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements.
- ~list()
+ ~list() BOOST_CONTAINER_NOEXCEPT
    {} //AllocHolder clears the list
 
    //! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -498,7 +493,7 @@
    //! <b>Throws</b>: If allocator's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return allocator_type(this->node_alloc()); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -508,7 +503,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    { return this->node_alloc(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -518,7 +513,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return this->node_alloc(); }
 
    //////////////////////////////////////////////
@@ -532,7 +527,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->icont().begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -540,7 +535,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -548,7 +543,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->icont().end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -556,7 +551,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    { return this->cend(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -565,7 +560,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    { return reverse_iterator(end()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -574,7 +569,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -583,7 +578,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    { return reverse_iterator(begin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -592,7 +587,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    { return this->crend(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -600,7 +595,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    { return const_iterator(this->non_const_icont().begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -608,7 +603,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    { return const_iterator(this->non_const_icont().end()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -617,7 +612,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
    { return const_reverse_iterator(this->cend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -626,7 +621,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
    { return const_reverse_iterator(this->cbegin()); }
 
    //////////////////////////////////////////////
@@ -640,7 +635,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
    { return !this->size(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the list.
@@ -648,7 +643,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
    { return this->icont().size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the list.
@@ -656,7 +651,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    { return AllocHolder::max_size(); }
 
    //! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -700,7 +695,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference front()
+ reference front() BOOST_CONTAINER_NOEXCEPT
    { return *this->begin(); }
 
    //! <b>Requires</b>: !empty()
@@ -711,7 +706,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reference front() const
+ const_reference front() const BOOST_CONTAINER_NOEXCEPT
    { return *this->begin(); }
 
    //! <b>Requires</b>: !empty()
@@ -722,7 +717,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference back()
+ reference back() BOOST_CONTAINER_NOEXCEPT
    { return *(--this->end()); }
 
    //! <b>Requires</b>: !empty()
@@ -733,7 +728,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reference back() const
+ const_reference back() const BOOST_CONTAINER_NOEXCEPT
    { return *(--this->end()); }
 
    //////////////////////////////////////////////
@@ -939,8 +934,10 @@
    {
       //Optimized allocation and construction
       insertion_functor func(this->icont(), p.get());
+ iterator before_p(p.get());
+ --before_p;
       this->allocate_many_and_construct(first, std::distance(first, last), func);
- return iterator(func.inserted_first());
+ return ++before_p;
    }
    #endif
 
@@ -949,7 +946,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- void pop_front()
+ void pop_front() BOOST_CONTAINER_NOEXCEPT
    { this->erase(this->cbegin()); }
 
    //! <b>Effects</b>: Removes the last element from the list.
@@ -957,7 +954,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
    { const_iterator tmp = this->cend(); this->erase(--tmp); }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -967,7 +964,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- iterator erase(const_iterator p)
+ iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -977,7 +974,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the distance between first and last.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
 
    //! <b>Effects</b>: Swaps the contents of *this and x.
@@ -993,7 +990,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in the list.
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
    { AllocHolder::clear(alloc_version()); }
 
    //////////////////////////////////////////////
@@ -1003,13 +1000,12 @@
    //////////////////////////////////////////////
 
    //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
    //! the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1017,19 +1013,18 @@
    //! this list. Iterators of this list and all the references are not invalidated.
    void splice(const_iterator p, list& x) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this != &x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice(p.get(), x.icont());
    }
 
    //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
    //! the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1040,13 +1035,13 @@
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //! If p == i or p == ++i, this function is a null operation.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1054,20 +1049,20 @@
    //! list. Iterators of this list and all the references are not invalidated.
    void splice(const_iterator p, list &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
+ //BOOST_ASSERT(this != &x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice(p.get(), x.icont(), i.get());
    }
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //! If p == i or p == ++i, this function is a null operation.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1078,12 +1073,12 @@
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. first and last must point to elements contained in list x.
+ //! this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear to the number of elements transferred.
    //!
@@ -1091,19 +1086,18 @@
    //! list. Iterators of this list and all the references are not invalidated.
    void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice(p.get(), x.icont(), first.get(), last.get());
    }
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. first and last must point to elements contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear to the number of elements transferred.
    //!
@@ -1114,13 +1108,12 @@
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last)
+ //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1130,20 +1123,18 @@
    //! <b>Note</b>: Non-standard extension
    void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
    }
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last)
+ //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1156,7 +1147,7 @@
 
    //! <b>Effects</b>: Removes all the elements that compare equal to value.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
    //!
@@ -1184,9 +1175,9 @@
    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
    //! elements that are equal from the list.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
    //!
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
@@ -1198,7 +1189,7 @@
    //!
    //! <b>Throws</b>: If pred throws.
    //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
    //!
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
@@ -1216,7 +1207,7 @@
    //! that is, if an element from *this is equivalent to one from x, then the element
    //! from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1230,7 +1221,7 @@
    //! that is, if an element from *this is equivalent to one from x, then the element
    //! from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1245,22 +1236,18 @@
    //! in order into *this. The merge is stable; that is, if an element from *this is
    //! equivalent to one from x, then the element from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
    //!
    //! <b>Note</b>: Iterators and references to *this are not invalidated.
    template <class StrictWeakOrdering>
- void merge(list &x, StrictWeakOrdering comp)
+ void merge(list &x, const StrictWeakOrdering &comp)
    {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
- else{
- throw std::runtime_error("list::merge called with unequal allocators");
- }
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
    }
 
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1271,7 +1258,7 @@
    //! in order into *this. The merge is stable; that is, if an element from *this is
    //! equivalent to one from x, then the element from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1284,7 +1271,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Notes</b>: Iterators and references are not invalidated.
    //!
@@ -1296,7 +1283,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
    //!
    //! <b>Notes</b>: Iterators and references are not invalidated.
    //!
@@ -1318,7 +1305,7 @@
    //! <b>Complexity</b>: This function is linear time.
    //!
    //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
+ void reverse() BOOST_CONTAINER_NOEXCEPT
    { this->icont().reverse(); }
 
    /// @cond
@@ -1382,31 +1369,18 @@
    class insertion_functor
    {
       Icont &icont_;
- typedef typename Icont::iterator iiterator;
       typedef typename Icont::const_iterator iconst_iterator;
-
       const iconst_iterator pos_;
- iiterator ret_;
- bool first_;
 
       public:
       insertion_functor(Icont &icont, typename Icont::const_iterator pos)
- : icont_(icont), pos_(pos), ret_(pos.unconst()), first_(true)
+ : icont_(icont), pos_(pos)
       {}
 
       void operator()(Node &n)
       {
- if(first_){
- ret_ = this->icont_.insert(pos_, n);
- first_ = false;
- }
- else{
- this->icont_.insert(pos_, n);
- }
+ this->icont_.insert(pos_, n);
       }
-
- iiterator inserted_first() const
- { return ret_; }
    };
 
    //Functors for member algorithm defaults
@@ -1483,15 +1457,14 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
 namespace container {
 
 /// @endcond

Modified: trunk/boost/container/map.hpp
==============================================================================
--- trunk/boost/container/map.hpp (original)
+++ trunk/boost/container/map.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -30,8 +30,8 @@
 #include <boost/container/detail/utilities.hpp>
 #include <boost/container/detail/pair.hpp>
 #include <boost/container/detail/type_traits.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/container/detail/value_init.hpp>
 
@@ -229,7 +229,7 @@
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.get_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -239,7 +239,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.get_stored_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -249,7 +249,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.get_stored_allocator(); }
 
    //////////////////////////////////////////////
@@ -263,7 +263,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -271,7 +271,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -279,7 +279,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -287,7 +287,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    { return this->cend(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -296,7 +296,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -305,7 +305,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -314,7 +314,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -323,7 +323,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    { return this->crend(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -331,7 +331,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -339,7 +339,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -348,7 +348,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -357,7 +357,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rend(); }
 
    //////////////////////////////////////////////
@@ -371,7 +371,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.empty(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -379,7 +379,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the container.
@@ -387,7 +387,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.max_size(); }
 
    //////////////////////////////////////////////
@@ -621,7 +621,7 @@
    //! returns end().
    //!
    //! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator position)
+ iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
    { return m_tree.erase(position); }
 
    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
@@ -629,7 +629,7 @@
    //! <b>Returns</b>: Returns the number of erased elements.
    //!
    //! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
+ size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT
    { return m_tree.erase(x); }
 
    //! <b>Effects</b>: Erases all the elements in the range [first, last).
@@ -637,7 +637,7 @@
    //! <b>Returns</b>: Returns last.
    //!
    //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    { return m_tree.erase(first, last); }
 
    //! <b>Effects</b>: Swaps the contents of *this and x.
@@ -653,7 +653,7 @@
    //! <b>Postcondition</b>: size() == 0.
    //!
    //! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
    { m_tree.clear(); }
 
    //////////////////////////////////////////////
@@ -827,15 +827,15 @@
                       const multimap<Key,T,Compare,Allocator>& y);
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 /// @endcond
@@ -951,9 +951,9 @@
    //!
    //! <b>Complexity</b>: Linear in N.
    template <class InputIterator>
- multimap(ordered_range_t ordered_range_, InputIterator first, InputIterator last, const Compare& comp = Compare(),
+ multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
          const allocator_type& a = allocator_type())
- : m_tree(ordered_range_, first, last, comp, a)
+ : m_tree(ordered_range, first, last, comp, a)
    {}
 
    //! <b>Effects</b>: Copy constructs a multimap.
@@ -1016,7 +1016,7 @@
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.get_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1026,7 +1026,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.get_stored_allocator(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1036,7 +1036,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.get_stored_allocator(); }
 
    //////////////////////////////////////////////
@@ -1050,7 +1050,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1058,7 +1058,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -1066,7 +1066,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1074,7 +1074,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    { return this->cend(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -1083,7 +1083,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1092,7 +1092,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1101,7 +1101,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1110,7 +1110,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    { return this->crend(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1118,7 +1118,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1126,7 +1126,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.end(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1135,7 +1135,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1144,7 +1144,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.rend(); }
 
    //////////////////////////////////////////////
@@ -1158,7 +1158,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.empty(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1166,7 +1166,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1174,7 +1174,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    { return m_tree.max_size(); }
 
    //////////////////////////////////////////////
@@ -1317,7 +1317,7 @@
    //! returns end().
    //!
    //! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator position)
+ iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
    { return m_tree.erase(position); }
 
    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
@@ -1325,7 +1325,7 @@
    //! <b>Returns</b>: Returns the number of erased elements.
    //!
    //! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
+ size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT
    { return m_tree.erase(x); }
 
    //! <b>Effects</b>: Erases all the elements in the range [first, last).
@@ -1333,7 +1333,7 @@
    //! <b>Returns</b>: Returns last.
    //!
    //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    { return m_tree.erase(first, last); }
 
    //! <b>Effects</b>: Swaps the contents of *this and x.
@@ -1349,7 +1349,7 @@
    //! <b>Postcondition</b>: size() == 0.
    //!
    //! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
    { m_tree.clear(); }
 
    //////////////////////////////////////////////
@@ -1486,15 +1486,15 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 /// @endcond

Modified: trunk/boost/container/scoped_allocator.hpp
==============================================================================
--- trunk/boost/container/scoped_allocator.hpp (original)
+++ trunk/boost/container/scoped_allocator.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -30,8 +30,8 @@
 #include <boost/container/detail/utilities.hpp>
 #include <utility>
 #include <boost/container/detail/pair.hpp>
-#include <boost/move/move.hpp>
-
+#include <boost/move/utility.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 
 namespace boost { namespace container {
 
@@ -1338,52 +1338,56 @@
    void construct_pair(Pair* p)
    {
       this->construct(container_detail::addressof(p->first));
- try {
+ BOOST_TRY{
          this->construct(container_detail::addressof(p->second));
       }
- catch (...) {
+ BOOST_CATCH(...){
          this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
    }
 
    template <class Pair, class U, class V>
    void construct_pair(Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
    {
       this->construct(container_detail::addressof(p->first), ::boost::forward<U>(x));
- try {
+ BOOST_TRY{
          this->construct(container_detail::addressof(p->second), ::boost::forward<V>(y));
       }
- catch (...) {
+ BOOST_CATCH(...){
          this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
    }
 
    template <class Pair, class Pair2>
    void construct_pair(Pair* p, const Pair2& pr)
    {
       this->construct(container_detail::addressof(p->first), pr.first);
- try {
+ BOOST_TRY{
          this->construct(container_detail::addressof(p->second), pr.second);
       }
- catch (...) {
+ BOOST_CATCH(...){
          this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
    }
 
    template <class Pair, class Pair2>
    void construct_pair(Pair* p, BOOST_RV_REF(Pair2) pr)
    {
       this->construct(container_detail::addressof(p->first), ::boost::move(pr.first));
- try {
+ BOOST_TRY{
          this->construct(container_detail::addressof(p->second), ::boost::move(pr.second));
       }
- catch (...) {
+ BOOST_CATCH(...){
          this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
       }
+ BOOST_CATCH_END
    }
 
    //template <class T1, class T2, class... Args1, class... Args2>

Modified: trunk/boost/container/set.hpp
==============================================================================
--- trunk/boost/container/set.hpp (original)
+++ trunk/boost/container/set.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -23,11 +23,11 @@
 #include <functional>
 #include <memory>
 
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/tree.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
 #include <boost/container/detail/preprocessor.hpp>
 #endif
@@ -646,15 +646,15 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class Key, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::set<Key, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
@@ -757,10 +757,10 @@
    //!
    //! <b>Complexity</b>: Linear in N.
    template <class InputIterator>
- multiset( ordered_range_t ordered_range_, InputIterator first, InputIterator last
+ multiset( ordered_range_t, InputIterator first, InputIterator last
            , const Compare& comp = Compare()
            , const allocator_type& a = allocator_type())
- : m_tree(ordered_range_, first, last, comp, a)
+ : m_tree(ordered_range, first, last, comp, a)
    {}
 
    //! <b>Effects</b>: Copy constructs a multiset.
@@ -1259,15 +1259,15 @@
 /// @cond
 
 } //namespace container {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class Key, class C, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, Allocator> >
 {
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
 };
-*/
+
 namespace container {
 
 /// @endcond

Modified: trunk/boost/container/slist.hpp
==============================================================================
--- trunk/boost/container/slist.hpp (original)
+++ trunk/boost/container/slist.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -19,8 +19,8 @@
 #include <boost/container/detail/workaround.hpp>
 
 #include <boost/container/container_fwd.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/container/detail/utilities.hpp>
 #include <boost/container/detail/mpl.hpp>
@@ -140,9 +140,6 @@
    friend bool operator!= (const slist_const_iterator& l, const slist_const_iterator& r)
    { return l.m_it != r.m_it; }
 
- IIterator &get()
- { return this->m_it; }
-
    const IIterator &get() const
    { return this->m_it; }
 };
@@ -181,9 +178,6 @@
    slist_iterator operator++(int)
    { IIterator tmp = this->m_it; ++*this; return slist_iterator(tmp); }
 
- IIterator &get()
- { return this->m_it; }
-
    const IIterator &get() const
    { return this->m_it; }
 };
@@ -319,10 +313,10 @@
 
    //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
    //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
- explicit slist(const allocator_type& a)
+ explicit slist(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
       : AllocHolder(a)
    {}
 
@@ -407,7 +401,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements.
- ~slist()
+ ~slist() BOOST_CONTAINER_NOEXCEPT
    {} //AllocHolder clears the slist
 
    //! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -511,7 +505,7 @@
    //! <b>Throws</b>: If allocator's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return allocator_type(this->node_alloc()); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -521,7 +515,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    { return this->node_alloc(); }
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -531,7 +525,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    { return this->node_alloc(); }
 
    //////////////////////////////////////////////
@@ -547,7 +541,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator before_begin()
+ iterator before_begin() BOOST_CONTAINER_NOEXCEPT
    { return iterator(end()); }
 
    //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
@@ -557,7 +551,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator before_begin() const
+ const_iterator before_begin() const BOOST_CONTAINER_NOEXCEPT
    { return this->cbefore_begin(); }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
@@ -565,7 +559,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->icont().begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -573,7 +567,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -581,7 +575,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->icont().end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -589,7 +583,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    { return this->cend(); }
 
    //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
@@ -599,7 +593,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbefore_begin() const
+ const_iterator cbefore_begin() const BOOST_CONTAINER_NOEXCEPT
    { return const_iterator(end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -607,7 +601,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    { return const_iterator(this->non_const_icont().begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -615,7 +609,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    { return const_iterator(this->non_const_icont().end()); }
 
    //! <b>Returns</b>: The iterator to the element before i in the sequence.
@@ -627,7 +621,7 @@
    //! <b>Complexity</b>: Linear to the number of elements before i.
    //!
    //! <b>Note</b>: Non-standard extension.
- iterator previous(iterator p)
+ iterator previous(iterator p) BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->icont().previous(p.get())); }
 
    //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
@@ -986,9 +980,9 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //! this list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, slist& x)
+ void splice_after(const_iterator prev_pos, slist& x) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this != &x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice_after(prev_pos.get(), x.icont());
    }
@@ -1006,65 +1000,63 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //! this list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x)
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(prev_pos, static_cast<slist&>(x)); }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
    //! after the element pointed by prev_pos.
    //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
+ void splice_after(const_iterator prev_pos, slist& x, const_iterator prev) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
    }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
    //! after the element pointed by prev_pos.
    //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x, const_iterator prev)
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(prev_pos, static_cast<slist&>(x), prev); }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! before_first and before_last must be valid iterators of x.
    //! prev_pos must not be contained in [before_first, before_last) range.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
    //! from list x to this list, after the element pointed by prev_pos.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear to the number of transferred elements.
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
    void splice_after(const_iterator prev_pos, slist& x,
- const_iterator before_first, const_iterator before_last)
+ const_iterator before_first, const_iterator before_last) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice_after
          (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
@@ -1073,31 +1065,31 @@
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! before_first and before_last must be valid iterators of x.
    //! prev_pos must not be contained in [before_first, before_last) range.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
    //! from list x to this list, after the element pointed by prev_pos.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear to the number of transferred elements.
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
    void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x,
- const_iterator before_first, const_iterator before_last)
+ const_iterator before_first, const_iterator before_last) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(prev_pos, static_cast<slist&>(x), before_first, before_last); }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! before_first and before_last must be valid iterators of x.
    //! prev_pos must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last)
+ //! n == std::distance(before_first, before_last).
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
    //! from list x to this list, after the element pointed by prev_pos.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1105,9 +1097,8 @@
    //! list. Iterators of this list and all the references are not invalidated.
    void splice_after(const_iterator prev_pos, slist& x,
                      const_iterator before_first, const_iterator before_last,
- size_type n)
+ size_type n) BOOST_CONTAINER_NOEXCEPT
    {
- BOOST_ASSERT(*this != x);
       BOOST_ASSERT(this->node_alloc() == x.node_alloc());
       this->icont().splice_after
          (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
@@ -1116,13 +1107,13 @@
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! before_first and before_last must be valid iterators of x.
    //! prev_pos must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last)
+ //! n == std::distance(before_first, before_last).
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
    //! from list x to this list, after the element pointed by prev_pos.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1130,7 +1121,7 @@
    //! list. Iterators of this list and all the references are not invalidated.
    void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x,
                      const_iterator before_first, const_iterator before_last,
- size_type n)
+ size_type n) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(prev_pos, static_cast<slist&>(x), before_first, before_last, n); }
 
    //! <b>Effects</b>: Removes all the elements that compare equal to value.
@@ -1163,9 +1154,9 @@
    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
    //! elements that are equal from the list.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
    //!
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
@@ -1177,7 +1168,7 @@
    //!
    //! <b>Throws</b>: If pred throws.
    //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
    //!
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
@@ -1195,7 +1186,7 @@
    //! that is, if an element from *this is equivalent to one from x, then the element
    //! from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1209,7 +1200,7 @@
    //! that is, if an element from *this is equivalent to one from x, then the element
    //! from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1224,7 +1215,7 @@
    //! in order into *this. The merge is stable; that is, if an element from *this is
    //! equivalent to one from x, then the element from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1233,13 +1224,9 @@
    template <class StrictWeakOrdering>
    void merge(slist& x, StrictWeakOrdering comp)
    {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
- else{
- throw std::runtime_error("list::merge called with unequal allocators");
- }
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
    }
 
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1250,7 +1237,7 @@
    //! in order into *this. The merge is stable; that is, if an element from *this is
    //! equivalent to one from x, then the element from *this will precede the one from x.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
@@ -1263,7 +1250,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
    //!
    //! <b>Notes</b>: Iterators and references are not invalidated.
    //!
@@ -1275,7 +1262,7 @@
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
    //!
    //! <b>Notes</b>: Iterators and references are not invalidated.
    //!
@@ -1297,7 +1284,7 @@
    //! <b>Complexity</b>: This function is linear time.
    //!
    //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
+ void reverse() BOOST_CONTAINER_NOEXCEPT
    { this->icont().reverse(); }
 
    //////////////////////////////////////////////
@@ -1403,7 +1390,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements before p.
- iterator erase(const_iterator p)
+ iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->erase_after(previous(p))); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -1414,73 +1401,71 @@
    //!
    //! <b>Complexity</b>: Linear to the distance between first and last plus
    //! linear to the elements before first.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->erase_after(previous(first), last)); }
 
    //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
    //! the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x)
+ void splice(const_iterator p, slist& x) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(this->previous(p), x); }
 
    //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
    //! the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x)
+ void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_CONTAINER_NOEXCEPT
    { this->splice(p, static_cast<slist&>(x)); }
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //! If p == i or p == ++i, this function is a null operation.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator i)
+ void splice(const_iterator p, slist& x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(this->previous(p), x, this->previous(i)); }
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
    //!
    //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //! If p == i or p == ++i, this function is a null operation.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i)
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
    { this->splice(p, static_cast<slist&>(x), i); }
 
    //! <b>Requires</b>: p must point to an element contained
@@ -1488,33 +1473,33 @@
    //!
    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! this' allocator and x's allocator shall compare equal.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
    //! and in distance(first, last).
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    { this->splice_after(this->previous(p), x, this->previous(first), this->previous(last)); }
 
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. first and last must point to elements contained in list x.
+ //! this' allocator and x's allocator shall compare equal
    //!
    //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
    //! before the the element pointed by p. No destructors or copy constructors are called.
    //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
    //! and in distance(first, last).
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last)
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    { this->splice(p, static_cast<slist&>(x), first, last); }
 
    /// @cond
@@ -1658,15 +1643,14 @@
 /// @cond
 
 namespace boost {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
 namespace container {
 
 /// @endcond

Modified: trunk/boost/container/stable_vector.hpp
==============================================================================
--- trunk/boost/container/stable_vector.hpp (original)
+++ trunk/boost/container/stable_vector.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -1,4 +1,4 @@
-//////////////////////////////////////////////////////////////////////////////
+
 //
 // (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
@@ -29,15 +29,16 @@
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/not.hpp>
 #include <boost/assert.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
 #include <boost/container/detail/utilities.hpp>
 #include <boost/container/detail/iterators.hpp>
 #include <boost/container/detail/algorithms.hpp>
 #include <boost/container/allocator_traits.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/aligned_storage.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <algorithm> //max
 #include <stdexcept>
 #include <memory>
@@ -303,7 +304,7 @@
    static const size_type ExtraPointers = 3;
    //Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers:
    // back() is this->index.back() - ExtraPointers;
- // end node index is *(this->index.end() -3)
+ // end node index is *(this->index.end() - 3)
    // Node cache first is *(this->index.end() - 2);
    // Node cache last is this->index.back();
 
@@ -366,89 +367,6 @@
    #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
 };
 
-template<class Allocator, unsigned Version = boost::container::container_detail::version<Allocator>::value>
-struct allocator_version_wrapper
-{
- typedef ::boost::container::container_detail::integral_constant
- <unsigned, Version> alloc_version;
-
- typedef typename Allocator::multiallocation_chain multiallocation_chain;
-
- typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
- typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
-
- static pointer allocate_one(Allocator &a)
- { return a.allocate_one(); }
-
- static void deallocate_one(Allocator &a, const pointer &p)
- { a.deallocate_one(p); }
-
- static multiallocation_chain allocate_individual(Allocator &a, size_type n)
- { return a.allocate_individual(n); }
-
- static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
- { a.deallocate_individual(::boost::move(holder)); }
-};
-
-template<class Allocator>
-struct allocator_version_wrapper<Allocator, 1>
-{
- typedef ::boost::container::container_detail::integral_constant
- <unsigned, 1> alloc_version;
-
- typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
- typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
- typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
-
- typedef typename boost::intrusive::pointer_traits<pointer>::
- template rebind_pointer<void>::type void_ptr;
- typedef container_detail::basic_multiallocation_chain
- <void_ptr> multialloc_cached_counted;
- typedef boost::container::container_detail::
- transform_multiallocation_chain
- < multialloc_cached_counted, value_type> multiallocation_chain;
-
- static pointer allocate_one(Allocator &a)
- { return a.allocate(1); }
-
- static void deallocate_one(Allocator &a, const pointer &p)
- { a.deallocate(p, 1); }
-
- static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
- {
- while(!holder.empty()){
- a.deallocate(holder.pop_front(), 1);
- }
- }
-
- struct allocate_individual_rollback
- {
- allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
- : mr_a(a), mr_chain(chain)
- {}
-
- ~allocate_individual_rollback()
- {
- allocator_version_wrapper::deallocate_individual(mr_a, mr_chain);
- }
-
- Allocator &mr_a;
- multiallocation_chain &mr_chain;
- };
-
- static multiallocation_chain allocate_individual(Allocator &a, size_type n)
- {
- multiallocation_chain m;
- multiallocation_chain m_ret;
- allocate_individual_rollback rollback(a, m);
- while(n--){
- m.push_front(a.allocate(1));
- }
- m.swap(m_ret);
- return ::boost::move(m_ret);
- }
-};
-
 } //namespace stable_vector_detail
 
 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -555,20 +473,21 @@
       template portable_rebind_alloc
          <node_type>::type node_allocator_type;
 
- typedef stable_vector_detail::allocator_version_wrapper<node_allocator_type> allocator_version_wrapper_t;
- typedef typename allocator_version_wrapper_t::multiallocation_chain multiallocation_chain;
+ typedef ::boost::container::container_detail::
+ allocator_version_traits<node_allocator_type> allocator_version_traits_t;
+ typedef typename allocator_version_traits_t::multiallocation_chain multiallocation_chain;
 
    node_ptr allocate_one()
- { return allocator_version_wrapper_t::allocate_one(this->priv_node_alloc()); }
+ { return allocator_version_traits_t::allocate_one(this->priv_node_alloc()); }
 
    void deallocate_one(const node_ptr &p)
- { allocator_version_wrapper_t::deallocate_one(this->priv_node_alloc(), p); }
+ { allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p); }
 
- multiallocation_chain allocate_individual(typename allocator_traits_type::size_type n)
- { return allocator_version_wrapper_t::allocate_individual(this->priv_node_alloc(), n); }
+ void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m)
+ { allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m); }
 
    void deallocate_individual(multiallocation_chain &holder)
- { allocator_version_wrapper_t::deallocate_individual(this->priv_node_alloc(), holder); }
+ { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); }
 
    friend class stable_vector_detail::clear_on_destroy<stable_vector>;
    typedef stable_vector_detail::iterator
@@ -633,10 +552,10 @@
 
    //! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
    //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
- explicit stable_vector(const allocator_type& al)
+ explicit stable_vector(const allocator_type& al) BOOST_CONTAINER_NOEXCEPT
       : internal_data(al), index(al)
    {
       STABLE_VECTOR_CHECK_INVARIANT;
@@ -904,7 +823,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
    { return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
@@ -912,7 +831,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin()const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    { return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; }
 
    //! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
@@ -920,7 +839,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
    { return iterator(this->priv_get_end_node()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
@@ -928,7 +847,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    { return const_iterator(this->priv_get_end_node()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -937,7 +856,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    { return reverse_iterator(this->end()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -946,7 +865,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    { return const_reverse_iterator(this->end()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -955,7 +874,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    { return reverse_iterator(this->begin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -964,7 +883,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend()const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    { return const_reverse_iterator(this->begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
@@ -972,7 +891,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    { return this->begin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
@@ -980,7 +899,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend()const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    { return this->end(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -989,7 +908,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
    { return this->rbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -998,7 +917,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend()const
+ const_reverse_iterator crend()const BOOST_CONTAINER_NOEXCEPT
    { return this->rend(); }
 
    //////////////////////////////////////////////
@@ -1012,7 +931,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
    { return this->index.size() <= ExtraPointers; }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
@@ -1020,7 +939,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
    {
       const size_type index_size = this->index.size();
       return index_size ? (index_size - ExtraPointers) : 0;
@@ -1031,7 +950,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    { return this->index.max_size() - ExtraPointers; }
 
    //! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -1071,7 +990,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
    {
       const size_type index_size = this->index.size();
       BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
@@ -1094,7 +1013,7 @@
       if(n > this->max_size())
          throw std::bad_alloc();
 
- size_type size_ = this->size();
+ size_type sz = this->size();
       size_type old_capacity = this->capacity();
       if(n > old_capacity){
          index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n);
@@ -1106,8 +1025,8 @@
             index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
          }
          //Now fill pool if data is not enough
- if((n - size_) > this->internal_data.pool_size){
- this->priv_increase_pool((n - size_) - this->internal_data.pool_size);
+ if((n - sz) > this->internal_data.pool_size){
+ this->priv_increase_pool((n - sz) - this->internal_data.pool_size);
          }
       }
    }
@@ -1156,7 +1075,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference front()
+ reference front() BOOST_CONTAINER_NOEXCEPT
    { return static_cast<node_reference>(*this->index.front()).value; }
 
    //! <b>Requires</b>: !empty()
@@ -1167,7 +1086,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reference front() const
+ const_reference front() const BOOST_CONTAINER_NOEXCEPT
    { return static_cast<const_node_reference>(*this->index.front()).value; }
 
    //! <b>Requires</b>: !empty()
@@ -1178,7 +1097,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference back()
+ reference back() BOOST_CONTAINER_NOEXCEPT
    { return static_cast<node_reference>(*this->index[this->size() - ExtraPointers]).value; }
 
    //! <b>Requires</b>: !empty()
@@ -1189,7 +1108,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reference back()const
+ const_reference back() const BOOST_CONTAINER_NOEXCEPT
    { return static_cast<const_node_reference>(*this->index[this->size() - ExtraPointers]).value; }
 
    //! <b>Requires</b>: size() > n.
@@ -1200,7 +1119,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
+ reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
    { return static_cast<node_reference>(*this->index[n]).value; }
 
    //! <b>Requires</b>: size() > n.
@@ -1211,7 +1130,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n)const
+ const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
    { return static_cast<const_node_reference>(*this->index[n]).value; }
 
    //! <b>Requires</b>: size() > n.
@@ -1400,7 +1319,7 @@
    //!
    //! <b>Complexity</b>: Linear to std::distance [first, last).
    template <class InputIterator>
- iterator insert(const_iterator position,InputIterator first, InputIterator last
+ iterator insert(const_iterator position, InputIterator first, InputIterator last
       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
       , typename container_detail::enable_if_c
          < !container_detail::is_convertible<InputIterator, size_type>::value
@@ -1426,8 +1345,8 @@
>::type * = 0
       )
    {
- const size_type num_new = (size_type)std::distance(first,last);
- const size_type pos = static_cast<size_type>(position - this->cbegin());
+ const size_type num_new = static_cast<size_type>(std::distance(first, last));
+ const size_type pos = static_cast<size_type>(position - this->cbegin());
       if(num_new){
          //Fills the node pool and inserts num_new null pointers in pos.
          //If a new buffer was needed fixes up pointers up to pos so
@@ -1463,7 +1382,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant time.
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
    { this->erase(--this->cend()); }
 
    //! <b>Effects</b>: Erases the element at position pos.
@@ -1472,15 +1391,15 @@
    //!
    //! <b>Complexity</b>: Linear to the elements between pos and the
    //! last element. Constant if pos is the last element.
- iterator erase(const_iterator position)
+ iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
    {
       STABLE_VECTOR_CHECK_INVARIANT;
- difference_type d = position - this->cbegin();
- index_iterator it = this->index.begin() + d;
+ const size_type d = position - this->cbegin();
+ index_iterator it = this->index.begin() + d;
       this->priv_delete_node(position.node_pointer());
       it = this->index.erase(it);
       index_traits_type::fix_up_pointers_from(this->index, it);
- return this->begin()+d;
+ return iterator(node_ptr_traits::static_cast_from(*it));
    }
 
    //! <b>Effects</b>: Erases the elements pointed by [first, last).
@@ -1489,19 +1408,30 @@
    //!
    //! <b>Complexity</b>: Linear to the distance between first and last
    //! plus linear to the elements between pos and the last element.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    {
       STABLE_VECTOR_CHECK_INVARIANT;
- difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
- if(d1 != d2){
- index_iterator it1(this->index.begin() + d1), it2(it1 + (d2 - d1));
- for(index_iterator it = it1; it != it2; ++it){
- this->priv_delete_node(node_ptr_traits::static_cast_from(*it));
+ const const_iterator cbeg(this->cbegin());
+ const size_type d1 = static_cast<size_type>(first - cbeg),
+ d2 = static_cast<size_type>(last - cbeg);
+ size_type d_dif = d2 - d1;
+ if(d_dif){
+ multiallocation_chain holder;
+ const index_iterator it1(this->index.begin() + d1);
+ const index_iterator it2(it1 + d_dif);
+ index_iterator it(it1);
+ while(d_dif--){
+ node_base_ptr &nb = *it;
+ ++it;
+ node_type &n = *node_ptr_traits::static_cast_from(nb);
+ this->priv_destroy_node(n);
+ holder.push_back(node_ptr_traits::pointer_to(n));
          }
+ this->priv_put_in_pool(holder);
          const index_iterator e = this->index.erase(it1, it2);
          index_traits_type::fix_up_pointers_from(this->index, e);
       }
- return iterator(this->begin() + d1);
+ return iterator(last.node_pointer());
    }
 
    //! <b>Effects</b>: Swaps the contents of *this and x.
@@ -1524,7 +1454,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
    { this->erase(this->cbegin(),this->cend()); }
 
    /// @cond
@@ -1666,7 +1596,8 @@
                               , node_ptr_traits::static_cast_from(pool_first_ref)
                               , node_ptr_traits::static_cast_from(pool_last_ref)
                               , internal_data.pool_size);
- multiallocation_chain m (this->allocate_individual(n));
+ multiallocation_chain m;
+ this->allocate_individual(n, m);
       holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
       this->internal_data.pool_size += n;
       std::pair<node_ptr, node_ptr> data(holder.extract_data());
@@ -1690,11 +1621,25 @@
       pool_last_ref = ret.second;
    }
 
+ void priv_put_in_pool(multiallocation_chain &ch)
+ {
+ node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1));
+ node_base_ptr &pool_last_ref = this->index.back();
+ ch.incorporate_after( ch.before_begin()
+ , node_ptr_traits::static_cast_from(pool_first_ref)
+ , node_ptr_traits::static_cast_from(pool_last_ref)
+ , internal_data.pool_size);
+ this->internal_data.pool_size = ch.size();
+ const std::pair<node_ptr, node_ptr> ret(ch.extract_data());
+ pool_first_ref = ret.first;
+ pool_last_ref = ret.second;
+ }
+
    node_ptr priv_get_from_pool()
    {
       //Precondition: index is not empty
       BOOST_ASSERT(!this->index.empty());
- node_base_ptr &pool_first_ref = *(this->index.end() - 2);
+ node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1));
       node_base_ptr &pool_last_ref = this->index.back();
       multiallocation_chain holder;
       holder.incorporate_after( holder.before_begin()
@@ -1707,9 +1652,9 @@
          pool_first_ref = pool_last_ref = node_ptr();
       }
       else{
- std::pair<node_ptr, node_ptr> data(holder.extract_data());
+ const std::pair<node_ptr, node_ptr> data(holder.extract_data());
          pool_first_ref = data.first;
- pool_last_ref = data.second;
+ pool_last_ref = data.second;
       }
       return ret;
    }
@@ -1720,11 +1665,16 @@
          (static_cast<node_type&>(const_cast<node_base_type&>(this->internal_data.end_node)));
    }
 
- void priv_delete_node(const node_ptr &n)
+ void priv_destroy_node(const node_type &n)
    {
       allocator_traits<node_allocator_type>::
- destroy(this->priv_node_alloc(), container_detail::addressof(n->value));
- static_cast<node_base_type*>(container_detail::to_raw_pointer(n))->~node_base_type();
+ destroy(this->priv_node_alloc(), container_detail::addressof(n.value));
+ static_cast<const node_base_type*>(&n)->~node_base_type();
+ }
+
+ void priv_delete_node(const node_ptr &n)
+ {
+ this->priv_destroy_node(*n);
       this->priv_put_in_pool(n);
    }
 
@@ -1776,7 +1726,7 @@
       }
 
       size_type n = this->capacity() - this->size();
- node_base_ptr &pool_first_ref = *(index_ref.end() - 2);
+ node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1));
       node_base_ptr &pool_last_ref = index_ref.back();
       multiallocation_chain holder;
       holder.incorporate_after( holder.before_begin()
@@ -1886,6 +1836,17 @@
 
 /// @endcond
 
+/*
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
+ : public has_trivial_destructor_after_move<Allocator>::value
+{};
+
+*/
+
 }}
 
 #include <boost/container/detail/config_end.hpp>

Modified: trunk/boost/container/string.hpp
==============================================================================
--- trunk/boost/container/string.hpp (original)
+++ trunk/boost/container/string.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -44,11 +44,13 @@
 #include <boost/container/detail/version_type.hpp>
 #include <boost/container/detail/allocation_type.hpp>
 #include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
 #include <boost/container/detail/mpl.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/functional/hash.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
 
 #include <functional>
 #include <string>
@@ -81,8 +83,8 @@
 // an exception-safe version of basic_string. The constructor allocates,
 // but does not initialize, a block of memory. The destructor
 // deallocates, but does not destroy elements within, a block of
-// memory. The destructor assumes that the memory either is the internal buffer,
-// or else points to a block of memory that was allocated using _String_base's
+// memory. The destructor assumes that the memory either is the internal buffer,
+// or else points to a block of memory that was allocated using string_base's
 // allocator and whose size is this->m_storage.
 template <class Allocator>
 class basic_string_base
@@ -92,7 +94,6 @@
    typedef allocator_traits<Allocator> allocator_traits_type;
  public:
    typedef Allocator allocator_type;
- //! The stored allocator type
    typedef allocator_type stored_allocator_type;
    typedef typename allocator_traits_type::pointer pointer;
    typedef typename allocator_traits_type::value_type value_type;
@@ -284,36 +285,8 @@
          reuse = pointer();
          command &= ~(expand_fwd | expand_bwd);
       }
- return this->allocation_command
- (command, limit_size, preferred_size, received_size, reuse, alloc_version());
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v1)
- {
- (void)limit_size;
- (void)reuse;
- if(!(command & allocate_new))
- return std::pair<pointer, bool>(pointer(), false);
- received_size = preferred_size;
- return std::make_pair(this->alloc().allocate(received_size), false);
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- pointer reuse,
- allocator_v2)
- {
- return this->alloc().allocation_command(command, limit_size, preferred_size,
- received_size, reuse);
+ return container_detail::allocator_version_traits<Allocator>::allocation_command
+ (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
    }
 
    size_type next_capacity(size_type additional_objects) const
@@ -336,11 +309,9 @@
 
    void destroy(pointer p, size_type n)
    {
- for(; n--; ++p){
- allocator_traits_type::destroy
- ( this->alloc()
- , container_detail::to_raw_pointer(p)
- );
+ value_type *raw_p = container_detail::to_raw_pointer(p);
+ for(; n--; ++raw_p){
+ allocator_traits_type::destroy( this->alloc(), raw_p);
       }
    }
 
@@ -569,37 +540,26 @@
    /// @endcond
 
    public:
-
- //! The allocator type
- typedef Allocator allocator_type;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
- //! The type of object, CharT, stored in the string
- typedef CharT value_type;
- //! The second template parameter Traits
- typedef Traits traits_type;
- //! Pointer to CharT
- typedef typename allocator_traits_type::pointer pointer;
- //! Const pointer to CharT
- typedef typename allocator_traits_type::const_pointer const_pointer;
- //! Reference to CharT
- typedef typename allocator_traits_type::reference reference;
- //! Const reference to CharT
- typedef typename allocator_traits_type::const_reference const_reference;
- //! An unsigned integral type
- typedef typename allocator_traits_type::size_type size_type;
- //! A signed integral type
- typedef typename allocator_traits_type::difference_type difference_type;
- //! Iterator used to iterate through a string. It's a Random Access Iterator
- typedef pointer iterator;
- //! Const iterator used to iterate through a string. It's a Random Access Iterator
- typedef const_pointer const_iterator;
- //! Iterator used to iterate backwards through a string
- typedef std::reverse_iterator<iterator> reverse_iterator;
- //! Const iterator used to iterate backwards through a string
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- //! The largest possible value of type size_type. That is, size_type(-1).
- static const size_type npos;
+ //////////////////////////////////////////////
+ //
+ // types
+ //
+ //////////////////////////////////////////////
+ typedef Traits traits_type;
+ typedef CharT value_type;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
+ typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
+ typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
+ typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
+ typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
+ typedef Allocator allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(pointer) iterator;
+ typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
+ static const size_type npos = size_type(-1);
 
    /// @cond
    private:
@@ -611,6 +571,11 @@
    /// @endcond
 
    public: // Constructor, destructor, assignment.
+ //////////////////////////////////////////////
+ //
+ // construct/copy/destroy
+ //
+ //////////////////////////////////////////////
    /// @cond
    struct reserve_t {};
 
@@ -634,8 +599,8 @@
 
    //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
    //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- explicit basic_string(const allocator_type& a)
+ //! <b>Throws</b>: Nothing
+ explicit basic_string(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
       : base_t(a)
    { this->priv_terminate_string(); }
 
@@ -653,10 +618,10 @@
 
    //! <b>Effects</b>: Move constructor. Moves s's resources to *this.
    //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- basic_string(BOOST_RV_REF(basic_string) s)
+ basic_string(BOOST_RV_REF(basic_string) s) BOOST_CONTAINER_NOEXCEPT
       : base_t(boost::move((base_t&)s))
    {}
 
@@ -693,7 +658,7 @@
    //! <b>Effects</b>: 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,
- const allocator_type& a = allocator_type())
+ const allocator_type& a = allocator_type())
       : base_t(a)
    {
       this->priv_terminate_string();
@@ -706,8 +671,7 @@
 
    //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
    //! and is initialized by a specific number of characters of the s c-string.
- basic_string(const CharT* s, size_type n,
- const allocator_type& a = allocator_type())
+ basic_string(const CharT* s, size_type n, const allocator_type& a = allocator_type())
       : base_t(a)
    {
       this->priv_terminate_string();
@@ -716,8 +680,7 @@
 
    //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
    //! and is initialized by the null-terminated s c-string.
- basic_string(const CharT* s,
- const allocator_type& a = allocator_type())
+ basic_string(const CharT* s, const allocator_type& a = allocator_type())
       : base_t(a)
    {
       this->priv_terminate_string();
@@ -726,8 +689,7 @@
 
    //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
    //! and is initialized by n copies of c.
- basic_string(size_type n, CharT c,
- const allocator_type& a = allocator_type())
+ basic_string(size_type n, CharT c, const allocator_type& a = allocator_type())
       : base_t(a)
    {
       this->priv_terminate_string();
@@ -737,8 +699,7 @@
    //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
    //! and a range of iterators.
    template <class InputIterator>
- basic_string(InputIterator f, InputIterator l,
- const allocator_type& a = allocator_type())
+ basic_string(InputIterator f, InputIterator l, const allocator_type& a = allocator_type())
       : base_t(a)
    {
       this->priv_terminate_string();
@@ -750,7 +711,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- ~basic_string()
+ ~basic_string() BOOST_CONTAINER_NOEXCEPT
    {}
      
    //! <b>Effects</b>: Copy constructs a string.
@@ -784,7 +745,7 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- basic_string& operator=(BOOST_RV_REF(basic_string) x)
+ basic_string& operator=(BOOST_RV_REF(basic_string) x) BOOST_CONTAINER_NOEXCEPT
    {
       if (&x != this){
          allocator_type &this_alloc = this->alloc();
@@ -815,44 +776,62 @@
    basic_string& operator=(CharT c)
    { return this->assign(static_cast<size_type>(1), c); }
 
- //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If allocator's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- iterator begin()
- { return this->priv_addr(); }
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
 
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //! <b>Effects</b>: Returns a reference to the internal allocator.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: Nothing
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return this->priv_addr(); }
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
 
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //! <b>Effects</b>: Returns a reference to the internal allocator.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
+
+ //////////////////////////////////////////////
+ //
+ // iterators
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
    { return this->priv_addr(); }
 
- //! <b>Effects</b>: Returns an iterator to the end of the vector.
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- iterator end()
- { return this->priv_end_addr(); }
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_addr(); }
 
- //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //! <b>Effects</b>: Returns an iterator to the end of the vector.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator end() const
+ iterator end() BOOST_CONTAINER_NOEXCEPT
    { return this->priv_end_addr(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -860,7 +839,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    { return this->priv_end_addr(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -869,7 +848,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    { return reverse_iterator(this->priv_end_addr()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -878,25 +857,16 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    { return this->crbegin(); }
 
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return const_reverse_iterator(this->priv_end_addr()); }
-
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed vector.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    { return reverse_iterator(this->priv_addr()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -905,52 +875,63 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    { return this->crend(); }
 
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed vector.
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return const_reverse_iterator(this->priv_addr()); }
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_addr(); }
 
- //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
    //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return this->alloc(); }
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_end_addr(); }
 
- //! <b>Effects</b>: Returns a reference to the internal allocator.
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
    //!
- //! <b>Throws</b>: Nothing
+ //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
- { return this->alloc(); }
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ { return const_reverse_iterator(this->priv_end_addr()); }
 
- //! <b>Effects</b>: Returns a reference to the internal allocator.
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
    //!
- //! <b>Throws</b>: Nothing
+ //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ { return const_reverse_iterator(this->priv_addr()); }
+
+ //////////////////////////////////////////////
+ //
+ // capacity
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
    //!
- //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
- { return this->alloc(); }
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
+ { return !this->priv_size(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the vector.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
    { return this->priv_size(); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -958,7 +939,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type length() const
+ size_type length() const BOOST_CONTAINER_NOEXCEPT
    { return this->size(); }
 
    //! <b>Effects</b>: Returns the largest possible size of the vector.
@@ -966,7 +947,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    { return base_t::max_size(); }
 
    //! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -990,7 +971,16 @@
    //!
    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
    void resize(size_type n)
- { resize(n, CharT(0)); }
+ { resize(n, CharT()); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_capacity(); }
 
    //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
    //! effect. Otherwise, it is a request for allocation of additional memory.
@@ -1023,28 +1013,6 @@
       }
    }
 
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return this->priv_capacity(); }
-
- //! <b>Effects</b>: Erases all the elements of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the vector.
- void clear()
- {
- if (!this->empty()) {
- Traits::assign(*this->priv_addr(), CharT(0));
- this->priv_size(0);
- }
- }
-
    //! <b>Effects</b>: Tries to deallocate the excess of memory created
    //! with previous allocations. The size of the string is unchanged
    //!
@@ -1076,13 +1044,11 @@
       }
    }
 
- //! <b>Effects</b>: Returns true if the vector contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->priv_size(); }
+ //////////////////////////////////////////////
+ //
+ // element access
+ //
+ //////////////////////////////////////////////
 
    //! <b>Requires</b>: size() > n.
    //!
@@ -1092,7 +1058,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
+ reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
       { return *(this->priv_addr() + n); }
 
    //! <b>Requires</b>: size() > n.
@@ -1103,7 +1069,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const
+ const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
       { return *(this->priv_addr() + n); }
 
    //! <b>Requires</b>: size() > n.
@@ -1135,6 +1101,12 @@
       return *(this->priv_addr() + n);
    }
 
+ //////////////////////////////////////////////
+ //
+ // modifiers
+ //
+ //////////////////////////////////////////////
+
    //! <b>Effects</b>: Calls append(str.data, str.size()).
    //!
    //! <b>Returns</b>: *this
@@ -1240,7 +1212,7 @@
    //! <b>Throws</b>: Nothing
    //!
    //! <b>Returns</b>: *this
- basic_string& assign(BOOST_RV_REF(basic_string) ms)
+ basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_CONTAINER_NOEXCEPT
    { return this->swap_data(ms), *this; }
 
    //! <b>Requires</b>: pos <= str.size()
@@ -1322,10 +1294,10 @@
    //! <b>Returns</b>: *this
    basic_string& insert(size_type pos, const basic_string& s)
    {
- const size_type size_ = this->size();
- if (pos > size_)
+ const size_type sz = this->size();
+ if (pos > sz)
          this->throw_out_of_range();
- if (size_ > this->max_size() - s.size())
+ if (sz > this->max_size() - s.size())
          this->throw_length_error();
       this->insert(this->priv_addr() + pos, s.begin(), s.end());
       return *this;
@@ -1341,12 +1313,12 @@
    //! <b>Returns</b>: *this
    basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n)
    {
- const size_type size_ = this->size();
+ const size_type sz = this->size();
       const size_type str_size = s.size();
- if (pos1 > size_ || pos2 > str_size)
+ if (pos1 > sz || pos2 > str_size)
          this->throw_out_of_range();
       size_type len = container_detail::min_value(n, str_size - pos2);
- if (size_ > this->max_size() - len)
+ if (sz > this->max_size() - len)
          this->throw_length_error();
       const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2;
       const CharT *end_ptr = beg_ptr + len;
@@ -1591,7 +1563,7 @@
    //!
    //! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
    //! erased. If no such element exists, end() is returned.
- iterator erase(const_iterator p)
+ iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
    {
       // The move includes the terminating null.
       CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
@@ -1611,7 +1583,7 @@
    //!
    //! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
    //! the other elements being erased. If no such element exists, end() is returned.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    {
       CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
       if (first != last) { // The move includes the terminating null.
@@ -1631,13 +1603,26 @@
    //! <b>Throws</b>: Nothing
    //!
    //! <b>Effects</b>: Equivalent to erase(size() - 1, 1).
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
    {
       const size_type old_size = this->priv_size();
       Traits::assign(this->priv_addr()[old_size-1], CharT(0));
       this->priv_size(old_size-1);;
    }
 
+ //! <b>Effects</b>: Erases all the elements of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the vector.
+ void clear() BOOST_CONTAINER_NOEXCEPT
+ {
+ if (!this->empty()) {
+ Traits::assign(*this->priv_addr(), CharT(0));
+ this->priv_size(0);
+ }
+ }
+
    //! <b>Requires</b>: pos1 <= size().
    //!
    //! <b>Effects</b>: Calls replace(pos1, n1, str.data(), str.size()).
@@ -1890,12 +1875,18 @@
       container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
    }
 
+ //////////////////////////////////////////////
+ //
+ // data access
+ //
+ //////////////////////////////////////////////
+
    //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
    //!
    //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
    //!
    //! <b>Complexity</b>: constant time.
- const CharT* c_str() const
+ const CharT* c_str() const BOOST_CONTAINER_NOEXCEPT
    { return container_detail::to_raw_pointer(this->priv_addr()); }
 
    //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
@@ -1903,9 +1894,15 @@
    //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
    //!
    //! <b>Complexity</b>: constant time.
- const CharT* data() const
+ const CharT* data() const BOOST_CONTAINER_NOEXCEPT
    { return container_detail::to_raw_pointer(this->priv_addr()); }
 
+ //////////////////////////////////////////////
+ //
+ // string operations
+ //
+ //////////////////////////////////////////////
+
    //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
    //! of the following conditions obtain: 19 pos <= xpos and xpos + str.size() <= size();
    //! 2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
@@ -1949,12 +1946,12 @@
    //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos).
    size_type find(CharT c, size_type pos = 0) const
    {
- const size_type size_ = this->size();
- if (pos >= size_)
+ const size_type sz = this->size();
+ if (pos >= sz)
          return npos;
       else {
- const pointer addr = this->priv_addr();
- pointer finish = addr + size_;
+ const pointer addr = this->priv_addr();
+ pointer finish = addr + sz;
          const const_iterator result =
             std::find_if(addr + pos, finish,
                   std::bind2nd(Eq_traits<Traits>(), c));
@@ -2039,12 +2036,12 @@
    //! <b>Returns</b>: find_first_of(basic_string(s, n), pos).
    size_type find_first_of(const CharT* s, size_type pos, size_type n) const
    {
- const size_type size_ = this->size();
- if (pos >= size_)
+ const size_type sz = this->size();
+ if (pos >= sz)
          return npos;
       else {
- const pointer addr = this->priv_addr();
- pointer finish = addr + size_;
+ const pointer addr = this->priv_addr();
+ pointer finish = addr + sz;
          const_iterator result = std::find_first_of
             (addr + pos, finish, s, s + n, Eq_traits<Traits>());
          return result != finish ? result - this->begin() : npos;
@@ -2282,8 +2279,8 @@
    //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size()
    //!
    //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
- int compare(size_type pos1, size_type n1,
- const basic_string& str, size_type pos2, size_type n2) const {
+ int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2) const
+ {
       if (pos1 > this->size() || pos2 > str.size())
          this->throw_out_of_range();
       const pointer addr = this->priv_addr();
@@ -2309,8 +2306,7 @@
    //! <b>Throws</b>: out_of_range if pos1 > size()
    //!
    //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
- int compare(size_type pos1, size_type n1,
- const CharT* s, size_type n2) const
+ int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const
    {
       if (pos1 > this->size())
          this->throw_out_of_range();
@@ -2352,7 +2348,7 @@
       const size_type long_size = this->priv_long_size();
       const size_type long_storage = this->priv_long_storage();
       //We can make this nothrow as chars are always NoThrowCopyables
- try{
+ BOOST_TRY{
          const std::pair<pointer, bool> ret = this->allocation_command
                (allocate_new, long_size+1, long_size+1, real_cap, long_addr);
          //Copy and update
@@ -2364,9 +2360,10 @@
          //And release old buffer
          this->alloc().deallocate(long_addr, long_storage);
       }
- catch(...){
+ BOOST_CATCH(...){
          return;
       }
+ BOOST_CATCH_END
    }
 
    template<class AllocVersion>
@@ -2481,15 +2478,6 @@
    ,std::allocator<wchar_t> >
 wstring;
 
-/// @cond
-
-template <class CharT, class Traits, class Allocator>
-const typename basic_string<CharT,Traits,Allocator>::size_type
-basic_string<CharT,Traits,Allocator>::npos
- = (typename basic_string<CharT,Traits,Allocator>::size_type) -1;
-
-/// @endcond
-
 // ------------------------------------------------------------
 // Non-member functions.
 
@@ -2857,15 +2845,14 @@
 /// @cond
 
 namespace boost {
-/*
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class C, class T, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
 }
 
 /// @endcond

Modified: trunk/boost/container/vector.hpp
==============================================================================
--- trunk/boost/container/vector.hpp (original)
+++ trunk/boost/container/vector.hpp 2012-11-24 16:08:18 EST (Sat, 24 Nov 2012)
@@ -32,6 +32,7 @@
 #include <boost/type_traits/has_nothrow_copy.hpp>
 #include <boost/type_traits/has_nothrow_assign.hpp>
 #include <boost/type_traits/has_nothrow_constructor.hpp>
+#include <boost/container/container_fwd.hpp>
 #include <boost/container/detail/version_type.hpp>
 #include <boost/container/detail/allocation_type.hpp>
 #include <boost/container/detail/utilities.hpp>
@@ -39,9 +40,10 @@
 #include <boost/container/detail/algorithms.hpp>
 #include <boost/container/detail/destroyers.hpp>
 #include <boost/container/allocator_traits.hpp>
-#include <boost/container/container_fwd.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/type_traits.hpp>
@@ -213,8 +215,7 @@
    typedef T value_type;
    typedef Allocator allocator_type;
    static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move = trivial_dctr;
- //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
    //static const bool trivial_copy = has_trivial_copy<value_type>::value;
    //static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
    //static const bool trivial_assign = has_trivial_assign<value_type>::value;
@@ -286,42 +287,17 @@
                          size_type preferred_size,
                          size_type &received_size, const pointer &reuse = 0)
    {
- return allocation_command(command, limit_size, preferred_size,
- received_size, reuse, alloc_version());
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v1)
- {
- (void)limit_size;
- (void)reuse;
- if(!(command & allocate_new))
- return std::pair<pointer, bool>(pointer(0), false);
- received_size = preferred_size;
- return std::make_pair(this->alloc().allocate(received_size), false);
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v2)
- {
- return this->alloc().allocation_command
- (command, limit_size, preferred_size, received_size, reuse);
+ return allocator_version_traits<Allocator>::allocation_command
+ (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
    }
 
    size_type next_capacity(size_type additional_objects) const
    {
+ std::size_t num_objects = this->members_.m_size + additional_objects;
+ std::size_t next_cap = this->members_.m_capacity + this->members_.m_capacity/2;
+ return num_objects > next_cap ? num_objects : next_cap;/*
       return get_next_capacity( allocator_traits_type::max_size(this->alloc())
- , this->members_.m_capacity, additional_objects);
+ , this->members_.m_capacity, additional_objects);*/
    }
 
    struct members_holder
@@ -435,7 +411,6 @@
    /// @cond
    private:
    BOOST_COPYABLE_AND_MOVABLE(vector)
- typedef container_detail::advanced_insert_aux_int<T*> advanced_insert_aux_int_t;
    typedef container_detail::vector_value_traits<value_type, Allocator> value_traits;
 
    typedef typename base_t::allocator_v1 allocator_v1;
@@ -443,8 +418,6 @@
    typedef typename base_t::alloc_version alloc_version;
 
    typedef constant_iterator<T, difference_type> cvalue_iterator;
- typedef repeat_iterator<T, difference_type> repeat_it;
- typedef boost::move_iterator<repeat_it> repeat_move_it;
    /// @endcond
 
    public:
@@ -857,7 +830,7 @@
       else{
          const size_type n = new_size - this->size();
          this->reserve(new_size);
- container_detail::default_construct_aux_proxy<Allocator, T*> proxy(this->alloc(), n);
+ container_detail::insert_default_constructed_n_proxy<Allocator, T*> proxy(this->alloc());
          this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy);
       }
    }
@@ -920,11 +893,10 @@
          //If there is no forward expansion, move objects
          else{
             //We will reuse insert code, so create a dummy input iterator
- T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
- container_detail::advanced_insert_aux_proxy<Allocator, boost::move_iterator<T*>, T*>
- proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+ container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
+ proxy(this->alloc(), ::boost::make_move_iterator((T *)0));
             //Backwards (and possibly forward) expansion
- if(ret.second){
+ if(alloc_version::value > 1 && ret.second){
                #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
                ++this->num_expand_bwd;
                #endif
@@ -1018,7 +990,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
+ reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
    { return this->members_.m_start[n]; }
 
    //! <b>Requires</b>: size() > n.
@@ -1102,9 +1074,9 @@
          ++this->members_.m_size;
       }
       else{
- typedef container_detail::advanced_insert_aux_emplace<Allocator, T*, Args...> type;
- type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
- this->priv_forward_range_insert(back_pos, 1, proxy);
+ typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
+ this->priv_forward_range_insert
+ (back_pos, 1, type(this->alloc(), ::boost::forward<Args>(args)...));
       }
    }
 
@@ -1122,11 +1094,9 @@
    iterator emplace(const_iterator position, Args && ...args)
    {
       //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- typedef container_detail::advanced_insert_aux_emplace<Allocator, T*, Args...> type;
- type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
- this->priv_forward_range_insert(position.get_ptr(), 1, proxy);
- return iterator(this->members_.m_start + pos_n);
+ typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
+ return this->priv_forward_range_insert
+ (position.get_ptr(), 1, type(this->alloc(), ::boost::forward<Args>(args)...));
    }
 
    #else
@@ -1143,8 +1113,8 @@
          ++this->members_.m_size; \
       } \
       else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
+ <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
             (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
          this->priv_forward_range_insert(back_pos, 1, proxy); \
       } \
@@ -1154,12 +1124,11 @@
    iterator emplace(const_iterator pos \
                     BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
    { \
- size_type pos_n = pos - cbegin(); \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
+ <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
             (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- this->priv_forward_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1,proxy);\
- return iterator(this->members_.m_start + pos_n); \
+ return this->priv_forward_range_insert \
+ (container_detail::to_raw_pointer(pos.get_ptr()), 1, proxy); \
    } \
    //!
    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -1222,7 +1191,10 @@
    //!
    //! <b>Complexity</b>: Linear to n.
    iterator insert(const_iterator p, size_type n, const T& x)
- { return this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
+ {
+ container_detail::insert_n_copies_proxy<Allocator, T*> proxy(this->alloc(), x);
+ return this->priv_forward_range_insert(p.get_ptr(), n, proxy);
+ }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
    //!
@@ -1250,7 +1222,7 @@
          it = this->emplace(it, *first);
          ++it;
       }
- return this->begin() + n_pos;
+ return iterator(this->members_.m_start + n_pos);
    }
 
    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1262,11 +1234,8 @@
>::type * = 0
       )
    {
- const size_type n_pos = pos - this->cbegin();
- const size_type n = std::distance(first, last);
- container_detail::advanced_insert_aux_proxy<Allocator, FwdIt, T*> proxy(this->alloc(), first, last);
- this->priv_forward_range_insert(pos.get_ptr(), n, proxy);
- return this->begin() + n_pos;
+ container_detail::insert_range_proxy<Allocator, FwdIt, T*> proxy(this->alloc(), first);
+ return this->priv_forward_range_insert(pos.get_ptr(), std::distance(first, last), proxy);
    }
    #endif
 
@@ -1275,7 +1244,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant time.
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
    {
       //Destroy last element
       --this->members_.m_size;
@@ -1290,8 +1259,8 @@
    //! last element. Constant if pos is the last element.
    iterator erase(const_iterator position)
    {
- T *pos = container_detail::to_raw_pointer(position.get_ptr());
- T *beg = container_detail::to_raw_pointer(this->members_.m_start);
+ T *const pos = container_detail::to_raw_pointer(position.get_ptr());
+ T *const beg = container_detail::to_raw_pointer(this->members_.m_start);
       ::boost::move(pos + 1, beg + this->members_.m_size, pos);
       --this->members_.m_size;
       //Destroy last element
@@ -1307,14 +1276,14 @@
    //! plus linear to the elements between pos and the last element.
    iterator erase(const_iterator first, const_iterator last)
    {
- if (first != last){ // worth doing, copy down over hole
+ if (first != last){
          T* end_pos = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
          T* ptr = container_detail::to_raw_pointer(boost::move
             (container_detail::to_raw_pointer(last.get_ptr())
             ,end_pos
             ,container_detail::to_raw_pointer(first.get_ptr())
             ));
- size_type destroyed = (end_pos - ptr);
+ const size_type destroyed = (end_pos - ptr);
          this->destroy_n(ptr, destroyed);
          this->members_.m_size -= destroyed;
       }
@@ -1361,26 +1330,15 @@
    }
 
    private:
- iterator priv_insert(const_iterator position, const T &x)
- {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position, (size_type)1, x);
- return iterator(this->members_.m_start + pos_n);
- }
-
- iterator priv_insert(const_iterator position, BOOST_RV_REF(T) x)
+ template<class U>
+ iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x)
    {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position
- ,repeat_move_it(repeat_it(x, 1))
- ,repeat_move_it(repeat_it()));
- return iterator(this->members_.m_start + pos_n);
+ return this->priv_forward_range_insert
+ (p.get_ptr(), 1, container_detail::get_insert_value_proxy<T*>(this->alloc(), ::boost::forward<U>(x)));
    }
 
    template <class U>
- void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+ void priv_push_back(BOOST_FWD_REF(U) x)
    {
       if (this->members_.m_size < this->members_.m_capacity){
          //There is more memory, just construct a new object at the end
@@ -1391,7 +1349,7 @@
          ++this->members_.m_size;
       }
       else{
- this->insert(this->cend(), ::boost::forward<U>(x));
+ this->priv_insert(this->cend(), ::boost::forward<U>(x));
       }
    }
 
@@ -1409,9 +1367,8 @@
                   (allocate_new, this->size(), this->size(), real_cap, this->members_.m_start);
             if(real_cap < this->capacity()){
                //We will reuse insert code, so create a dummy input iterator
- T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
- container_detail::advanced_insert_aux_proxy<Allocator, boost::move_iterator<T*>, T*>
- proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+ container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
+ proxy(this->alloc(), ::boost::make_move_iterator((T *)0));
                #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
                ++this->num_alloc;
                #endif
@@ -1450,65 +1407,79 @@
       }
    }
 
- void priv_forward_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertionProxy>
+ iterator priv_forward_range_insert
+ (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy)
    {
       //Check if we have enough memory or try to expand current memory
- size_type remaining = this->members_.m_capacity - this->members_.m_size;
- bool same_buffer_start;
- std::pair<pointer, bool> ret;
- size_type real_cap = this->members_.m_capacity;
+ const size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ const size_type n_pos = pos - this->members_.m_start;
+ T *const raw_pos = container_detail::to_raw_pointer(pos);
 
       //Check if we already have room
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new
- //buffer or expand the old one.
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
+ if(alloc_version::value > 1){ //Version 2 allocator, compile time check
+ bool same_buffer_start = n <= remaining;
+ if (!same_buffer_start){
+ size_type real_cap = 0;
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ std::pair<pointer, bool> ret = (this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->members_.m_size + n, this->next_capacity(n), real_cap, this->members_.m_start));
 
- //Check for forward expansion
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
+ //Buffer reallocated
+ if(ret.second){
+ //Forward expansion, delay insertion
+ if(this->members_.m_start == ret.first){
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->members_.m_capacity = real_cap;
+ //Expand forward
+ this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
+ }
+ //Backwards (and possibly forward) expansion
+ else{
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
+ this->priv_range_insert_expand_backwards
+ ( container_detail::to_raw_pointer(ret.first)
+ , real_cap, raw_pos, n, insert_range_proxy);
+ }
+ }
+ //New buffer
+ else{
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( container_detail::to_raw_pointer(ret.first)
+ , real_cap, raw_pos, n, insert_range_proxy);
+ }
+ }
+ else{
+ //Expand forward
+ this->priv_range_insert_expand_forward
+ (raw_pos, n, insert_range_proxy);
          }
       }
-
- //If we had room or we have expanded forward
- if (same_buffer_start){
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_expand_fwd;
- #endif
- this->priv_range_insert_expand_forward
- (container_detail::to_raw_pointer(pos), n, interf);
- }
- //Backwards (and possibly forward) expansion
- else if(ret.second){
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_expand_bwd;
- #endif
- this->priv_range_insert_expand_backwards
- ( container_detail::to_raw_pointer(ret.first)
- , real_cap
- , container_detail::to_raw_pointer(pos)
- , n
- , interf);
- }
- //New buffer
- else{
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_alloc;
- #endif
- this->priv_range_insert_new_allocation
- ( container_detail::to_raw_pointer(ret.first)
- , real_cap
- , container_detail::to_raw_pointer(pos)
- , n
- , interf);
+ else{ //Version 1 allocator
+ if (n <= remaining){
+ this->priv_range_insert_expand_forward
+ (raw_pos, n, insert_range_proxy);
+ }
+ else{
+ const size_type new_cap = this->next_capacity(n);
+ T * new_buf = container_detail::to_raw_pointer(this->alloc().allocate(new_cap));
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( new_buf, new_cap, raw_pos, n, insert_range_proxy);
+ }
       }
+ return iterator(this->members_.m_start + n_pos);
    }
 
    //Absolutely experimental. This function might change, disappear or simply crash!
@@ -1660,15 +1631,21 @@
    }
 
    private:
- void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertionProxy>
+ void priv_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy)
    {
       //n can't be 0, because there is nothing to do in that case
       if(!n) return;
       //There is enough memory
- T* old_finish = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
+ T* const old_finish = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
       const size_type elems_after = old_finish - pos;
 
- if (elems_after >= n){
+ if (!elems_after){
+ //Copy first new elements in pos
+ insert_range_proxy.uninitialized_copy_n_and_update(pos, n);
+ this->members_.m_size += n;
+ }
+ else if (elems_after >= n){
          //New elements can be just copied.
          //Move to uninitialized memory last objects
          ::boost::container::uninitialized_move_alloc
@@ -1677,24 +1654,31 @@
          //Copy previous to last objects to the initialized end
          boost::move_backward(pos, old_finish - n, old_finish);
          //Insert new objects in the pos
- interf.copy_remaining_to(pos);
+ insert_range_proxy.copy_n_and_update(pos, n);
       }
       else {
- //The new elements don't fit in the [pos, end()) range. Copy
- //to the beginning of the unallocated zone the last new elements.
- interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
- this->members_.m_size += n - elems_after;
- //Copy old [pos, end()) elements to the uninitialized memory
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, old_finish, container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size);
- this->members_.m_size += elems_after;
- //Copy first new elements in pos
- interf.copy_remaining_to(pos);
+ //The new elements don't fit in the [pos, end()) range.
+
+ //Copy old [pos, end()) elements to the uninitialized memory (a gap is created)
+ ::boost::container::uninitialized_move_alloc(this->alloc(), pos, old_finish, pos + n);
+ BOOST_TRY{
+ //Copy first new elements in pos (gap is still there)
+ insert_range_proxy.copy_n_and_update(pos, elems_after);
+ //Copy to the beginning of the unallocated zone the last new elements (the gap is closed).
+ insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n - elems_after);
+ this->members_.m_size += n;
+ }
+ BOOST_CATCH(...){
+ this->destroy_n(pos + n, elems_after);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
       }
    }
 
+ template <class InsertionProxy>
    void priv_range_insert_new_allocation
- (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy)
    {
       //n can be zero, if we want to reallocate!
       T *new_finish = new_start;
@@ -1712,7 +1696,7 @@
          constructed_values_destroyer.increment_size(new_finish - old_finish);
       }
       //Initialize new objects, starting from previous point
- interf.uninitialized_copy_remaining_to(old_finish = new_finish);
+ insert_range_proxy.uninitialized_copy_n_and_update(old_finish = new_finish, n);
       new_finish += n;
       constructed_values_destroyer.increment_size(new_finish - old_finish);
       //Initialize from the rest of the old buffer,
@@ -1734,19 +1718,21 @@
       scoped_alloc.release();
    }
 
+ template <class InsertionProxy>
    void priv_range_insert_expand_backwards
- (T* new_start, size_type new_capacity,
- T* pos, const size_type n, advanced_insert_aux_int_t &interf)
+ (T* const new_start, const size_type new_capacity,
+ T* const pos, const size_type n, InsertionProxy insert_range_proxy)
    {
       //n can be zero to just expand capacity
       //Backup old data
- T* old_start = container_detail::to_raw_pointer(this->members_.m_start);
- T* old_finish = old_start + this->members_.m_size;
- size_type old_size = this->members_.m_size;
+ T* const old_start = container_detail::to_raw_pointer(this->members_.m_start);
+ T* const old_finish = old_start + this->members_.m_size;
+ const size_type old_size = this->members_.m_size;
 
       //We can have 8 possibilities:
- const size_type elemsbefore = (size_type)(pos - old_start);
- const size_type s_before = (size_type)(old_start - new_start);
+ const size_type elemsbefore = static_cast<size_type>(pos - old_start);
+ const size_type s_before = static_cast<size_type>(old_start - new_start);
+ const size_type before_plus_new = elemsbefore + n;
 
       //Update the vector buffer information to a safe state
       this->members_.m_start = new_start;
@@ -1757,15 +1743,16 @@
       //all the old objects to fulfill previous vector state
       typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
       //Check if s_before is big enough to hold the beginning of old data + new data
- if(difference_type(s_before) >= difference_type(elemsbefore + n)){
+ if(s_before >= before_plus_new){
          //Copy first old values before pos, after that the new objects
- ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
+ T *const new_elem_pos = ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
          this->members_.m_size = elemsbefore;
- interf.uninitialized_copy_remaining_to(new_start + elemsbefore);
+ insert_range_proxy.uninitialized_copy_n_and_update(new_elem_pos, n);
          this->members_.m_size += n;
          //Check if s_before is so big that even copying the old data + new data
          //there is a gap between the new data and the old data
- if(s_before >= (old_size + n)){
+ const size_type new_size = old_size + n;
+ if(s_before >= new_size){
             //Old situation:
             // _________________________________________________________
             //| raw_mem | old_begin | old_end |
@@ -1778,9 +1765,9 @@
             //
             //Now initialize the rest of memory with the last old values
             ::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, old_finish, new_start + elemsbefore + n);
+ (this->alloc(), pos, old_finish, new_start + before_plus_new);
             //All new elements correctly constructed, avoid new element destruction
- this->members_.m_size = old_size + n;
+ this->members_.m_size = new_size;
             //Old values destroyed automatically with "old_values_destroyer"
             //when "old_values_destroyer" goes out of scope unless the have trivial
             //destructor after move.
@@ -1801,17 +1788,17 @@
             //
             //Now initialize the rest of memory with the last old values
             //All new elements correctly constructed, avoid new element destruction
- size_type raw_gap = s_before - (elemsbefore + n);
+ const size_type raw_gap = s_before - before_plus_new;
             //Now initialize the rest of s_before memory with the
             //first of elements after new values
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, pos + raw_gap, new_start + elemsbefore + n);
+ ::boost::container::uninitialized_move_alloc_n
+ (this->alloc(), pos, raw_gap, new_start + before_plus_new);
             //Update size since we have a contiguous buffer
             this->members_.m_size = old_size + s_before;
             //All new elements correctly constructed, avoid old element destruction
             old_values_destroyer.release();
             //Now copy remaining last objects in the old buffer begin
- T *to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
+ T * const to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
             //Now destroy redundant elements except if they were moved and
             //they have trivial destructor after move
             size_type n_destroy = old_finish - to_destroy;
@@ -1840,7 +1827,7 @@
          //| old_begin + new + old_end | raw_mem |
          //|____________________________|____________________|
          //
- bool do_after = n > s_before;
+ const bool do_after = n > s_before;
 
          //Now we can have two situations: the raw_mem of the
          //beginning divides the old_begin, or the new elements:
@@ -1869,28 +1856,26 @@
             //|___________|_____|_________|_____________________|
             //
             //Copy the first part of old_begin to raw_mem
- T *start_n = old_start + difference_type(s_before);
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), old_start, start_n, new_start);
+ ::boost::container::uninitialized_move_alloc_n
+ (this->alloc(), old_start, s_before, new_start);
             //The buffer is all constructed until old_end,
             //release destroyer and update size
             old_values_destroyer.release();
             this->members_.m_size = old_size + s_before;
- //Now copy the second part of old_begin overwriting himself
- T* next = ::boost::move(start_n, pos, old_start);
+ //Now copy the second part of old_begin overwriting itself
+ T *const next = ::boost::move(old_start + s_before, pos, old_start);
             if(do_after){
                //Now copy the new_beg elements
- interf.copy_some_and_update(next, s_before, true);
+ insert_range_proxy.copy_n_and_update(next, s_before);
             }
             else{
                //Now copy the all the new elements
- interf.copy_remaining_to(next);
- T* move_start = next + n;
+ insert_range_proxy.copy_n_and_update(next, n);
                //Now displace old_end elements
- T* move_end = ::boost::move(pos, old_finish, move_start);
+ T* const move_end = ::boost::move(pos, old_finish, next + n);
                //Destroy remaining moved elements from old_end except if
                //they have trivial destructor after being moved
- difference_type n_destroy = s_before - n;
+ const size_type n_destroy = s_before - n;
                if(!value_traits::trivial_dctr_after_move)
                   this->destroy_n(move_end, n_destroy);
                this->members_.m_size -= n_destroy;
@@ -1923,30 +1908,30 @@
             //|___________|_____|_________|__________________________|
             //
             //First copy whole old_begin and part of new to raw_mem
- ::boost::container::uninitialized_move_alloc
+ T * const new_pos = ::boost::container::uninitialized_move_alloc
                (this->alloc(), old_start, pos, new_start);
             this->members_.m_size = elemsbefore;
-
- const size_type mid_n = difference_type(s_before) - elemsbefore;
- interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
- this->members_.m_size = old_size + s_before;
+ const size_type mid_n = s_before - elemsbefore;
+ insert_range_proxy.uninitialized_copy_n_and_update(new_pos, mid_n);
             //The buffer is all constructed until old_end,
- //release destroyer and update size
+ //release destroyer
+ this->members_.m_size = old_size + s_before;
             old_values_destroyer.release();
 
             if(do_after){
                //Copy new_beg part
- interf.copy_some_and_update(old_start, s_before - mid_n, true);
+ insert_range_proxy.copy_n_and_update(old_start, elemsbefore);
             }
             else{
                //Copy all new elements
- interf.copy_remaining_to(old_start);
- T* move_start = old_start + (n-mid_n);
+ const size_type rest_new = n - mid_n;
+ insert_range_proxy.copy_n_and_update(old_start, rest_new);
+ T* move_start = old_start + rest_new;
                //Displace old_end
                T* move_end = ::boost::move(pos, old_finish, move_start);
                //Destroy remaining moved elements from old_end except if they
                //have trivial destructor after being moved
- difference_type n_destroy = s_before - n;
+ size_type n_destroy = s_before - n;
                if(!value_traits::trivial_dctr_after_move)
                   this->destroy_n(move_end, n_destroy);
                this->members_.m_size -= n_destroy;
@@ -1954,9 +1939,6 @@
          }
 
          //This is only executed if two phase construction is needed
- //This can be executed without exception handling since we
- //have to just copy and append in raw memory and
- //old_values_destroyer has been released in phase 1.
          if(do_after){
             //The raw memory divides the new elements
             //
@@ -1975,11 +1957,11 @@
             //| old_begin + new | old_end |raw |
             //|_______________________________________|_________|____|
             //
- const size_type n_after = n - s_before;
- const difference_type elemsafter = old_size - elemsbefore;
+ const size_type n_after = n - s_before;
+ const size_type elemsafter = old_size - elemsbefore;
 
             //We can have two situations:
- if (elemsafter > difference_type(n_after)){
+ if (elemsafter >= n_after){
                //The raw_mem from end will divide displaced old_end
                //
                //Old situation:
@@ -1993,7 +1975,7 @@
                //|__________________________|_________|________|_________|
                //
                //First copy the part of old_end raw_mem
- T* finish_n = old_finish - difference_type(n_after);
+ T* finish_n = old_finish - n_after;
                ::boost::container::uninitialized_move_alloc
                   (this->alloc(), finish_n, old_finish, old_finish);
                this->members_.m_size += n_after;
@@ -2001,7 +1983,7 @@
                boost::move_backward(pos, finish_n, old_finish);
                //Now overwrite with new_end
                //The new_end part is [first + (n - n_after), last)
- interf.copy_remaining_to(pos);
+ insert_range_proxy.copy_n_and_update(pos, n_after);
             }
             else {
                //The raw_mem from end will divide new_end part
@@ -2016,16 +1998,38 @@
                //| old_begin + new_beg | new_end |old_end | raw_mem |
                //|__________________________|_______________|________|_________|
                //
+
+ const size_type mid_last_dist = n_after - elemsafter;
+ //First initialize data in raw memory
+
+ //Copy to the old_end part to the uninitialized zone leaving a gap.
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), pos, old_finish, old_finish + mid_last_dist);
+
+ BOOST_TRY{
+ //Copy the first part to the already constructed old_end zone
+ insert_range_proxy.copy_n_and_update(pos, elemsafter);
+ //Copy the rest to the uninitialized zone filling the gap
+ insert_range_proxy.uninitialized_copy_n_and_update(old_finish, mid_last_dist);
+ this->members_.m_size += n_after;
+ }
+ BOOST_CATCH(...){
+ this->destroy_n(pos, mid_last_dist);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+/*
                size_type mid_last_dist = n_after - elemsafter;
                //First initialize data in raw memory
+
                //The new_end part is [first + (n - n_after), last)
- interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ insert_range_proxy.uninitialized_copy_last_and_update(old_finish, elemsafter);
                this->members_.m_size += mid_last_dist;
                ::boost::container::uninitialized_move_alloc
                   (this->alloc(), pos, old_finish, old_finish + mid_last_dist);
                this->members_.m_size += n_after - mid_last_dist;
                //Now copy the part of new_end over constructed elements
- interf.copy_remaining_to(pos);
+ insert_range_proxy.copy_remaining_to(pos);*/
             }
          }
       }
@@ -2083,17 +2087,14 @@
 
 namespace boost {
 
-/*
 
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class Allocator>
 struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
 
-*/
 
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk