Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77480 - in trunk/boost/container: . allocator detail
From: igaztanaga_at_[hidden]
Date: 2012-03-22 14:46:59


Author: igaztanaga
Date: 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
New Revision: 77480
URL: http://svn.boost.org/trac/boost/changeset/77480

Log:
Experimental scoped_allocator support
Removed:
   trunk/boost/container/allocator/
Text files modified:
   trunk/boost/container/container_fwd.hpp | 2
   trunk/boost/container/deque.hpp | 44 +++++++++
   trunk/boost/container/detail/adaptive_node_pool_impl.hpp | 2
   trunk/boost/container/detail/advanced_insert_int.hpp | 129 +++++++++++++++++------------
   trunk/boost/container/detail/algorithms.hpp | 2
   trunk/boost/container/detail/allocation_type.hpp | 2
   trunk/boost/container/detail/config_begin.hpp | 3
   trunk/boost/container/detail/config_end.hpp | 2
   trunk/boost/container/detail/destroyers.hpp | 35 +++++++
   trunk/boost/container/detail/flat_tree.hpp | 22 ++++
   trunk/boost/container/detail/function_detector.hpp | 2
   trunk/boost/container/detail/iterators.hpp | 14 +-
   trunk/boost/container/detail/math_functions.hpp | 2
   trunk/boost/container/detail/mpl.hpp | 2
   trunk/boost/container/detail/multiallocation_chain.hpp | 2
   trunk/boost/container/detail/node_alloc_holder.hpp | 59 ++++--------
   trunk/boost/container/detail/node_pool_impl.hpp | 2
   trunk/boost/container/detail/pair.hpp | 105 +++++++++++++++---------
   trunk/boost/container/detail/pool_common.hpp | 2
   trunk/boost/container/detail/preprocessor.hpp | 12 ++
   trunk/boost/container/detail/stored_ref.hpp | 2
   trunk/boost/container/detail/transform_iterator.hpp | 2
   trunk/boost/container/detail/tree.hpp | 92 ++++++++++++++-------
   trunk/boost/container/detail/type_traits.hpp | 9 +
   trunk/boost/container/detail/utilities.hpp | 15 +++
   trunk/boost/container/detail/value_init.hpp | 2
   trunk/boost/container/detail/variadic_templates_tools.hpp | 2
   trunk/boost/container/detail/version_type.hpp | 2
   trunk/boost/container/detail/workaround.hpp | 7 +
   trunk/boost/container/flat_map.hpp | 50 +++++++++--
   trunk/boost/container/flat_set.hpp | 84 +++++++++++++++----
   trunk/boost/container/list.hpp | 59 ++++++++-----
   trunk/boost/container/map.hpp | 72 +++++++++++++---
   trunk/boost/container/set.hpp | 40 ++++++++
   trunk/boost/container/slist.hpp | 60 ++++++++-----
   trunk/boost/container/stable_vector.hpp | 170 +++++++++++++++++++++------------------
   trunk/boost/container/string.hpp | 34 +++++++
   trunk/boost/container/vector.hpp | 120 +++++++++++++++++++++++++++
   38 files changed, 886 insertions(+), 381 deletions(-)

Modified: trunk/boost/container/container_fwd.hpp
==============================================================================
--- trunk/boost/container/container_fwd.hpp (original)
+++ trunk/boost/container/container_fwd.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/deque.hpp
==============================================================================
--- trunk/boost/container/deque.hpp (original)
+++ trunk/boost/container/deque.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -44,7 +44,7 @@
 #include <boost/container/detail/iterators.hpp>
 #include <boost/container/detail/algorithms.hpp>
 #include <boost/container/detail/mpl.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/container/container_fwd.hpp>
 #include <cstddef>
 #include <iterator>
@@ -896,6 +896,46 @@
       : Base(boost::move(static_cast<Base&>(x)))
    { this->swap_members(x); }
 
+ //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocation
+ //! throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ deque(const deque& x, const allocator_type &a)
+ : Base(a)
+ {
+ if(x.size()){
+ this->priv_initialize_map(x.size());
+ boost::container::uninitialized_copy_alloc
+ (this->alloc(), x.begin(), x.end(), this->members_.m_start);
+ }
+ }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves mx's resources to *this if a == allocator_type().
+ //! Otherwise copies values from x to *this.
+ //!
+ //! <b>Throws</b>: If allocation or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
+ deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
+ : Base(a)
+ {
+ if(mx.alloc() == a){
+ this->swap_members(mx);
+ }
+ else{
+ if(mx.size()){
+ this->priv_initialize_map(mx.size());
+ boost::container::uninitialized_copy_alloc
+ (this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
+ }
+ }
+ }
+
    //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
    //! and inserts a copy of the range [first, last) in the deque.
    //!

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-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -17,7 +17,9 @@
 
 #include "config_begin.hpp"
 #include <boost/container/detail/workaround.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/aligned_storage.hpp>
 #include <boost/move/move.hpp>
 #include <iterator> //std::iterator_traits
 #include <boost/assert.hpp>
@@ -41,7 +43,6 @@
 struct advanced_insert_aux_proxy
    : public advanced_insert_aux_int<Iterator>
 {
- 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;
@@ -54,36 +55,36 @@
    {}
 
    virtual void copy_remaining_to(Iterator p)
- { ::boost::copy_or_move(first_, last_, p); }
+ { ::boost::copy_or_move(this->first_, this->last_, p); }
 
    virtual void uninitialized_copy_remaining_to(Iterator p)
- { ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p); }
+ { ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); }
 
    virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
- FwdIt mid = first_;
+ FwdIt mid = this->first_;
       std::advance(mid, division_count);
       if(first_n){
- ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
- first_ = mid;
+ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
+ this->first_ = mid;
       }
       else{
- ::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
- last_ = mid;
+ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
+ this->last_ = mid;
       }
    }
 
    virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
- FwdIt mid = first_;
+ FwdIt mid = this->first_;
       std::advance(mid, division_count);
       if(first_n){
- ::boost::copy_or_move(first_, mid, pos);
- first_ = mid;
+ ::boost::copy_or_move(this->first_, mid, pos);
+ this->first_ = mid;
       }
       else{
- ::boost::copy_or_move(mid, last_, pos);
- last_ = mid;
+ ::boost::copy_or_move(mid, this->last_, pos);
+ this->last_ = mid;
       }
    }
    A &a_;
@@ -95,7 +96,7 @@
 struct default_construct_aux_proxy
    : public advanced_insert_aux_int<Iterator>
 {
- typedef boost::container::allocator_traits<A> alloc_traits;
+ 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;
@@ -109,11 +110,11 @@
 
    virtual void copy_remaining_to(Iterator)
    { //This should never be called with any count
- BOOST_ASSERT(count_ == 0);
+ BOOST_ASSERT(this->count_ == 0);
    }
 
    virtual void uninitialized_copy_remaining_to(Iterator p)
- { this->priv_uninitialized_copy(p, count_); }
+ { this->priv_uninitialized_copy(p, this->count_); }
 
    virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
@@ -122,22 +123,22 @@
          new_count = division_count;
       }
       else{
- BOOST_ASSERT(difference_type(count_)>= division_count);
- new_count = count_ - division_count;
+ BOOST_ASSERT(difference_type(this->count_)>= division_count);
+ new_count = this->count_ - division_count;
       }
       this->priv_uninitialized_copy(pos, new_count);
    }
 
    virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
    {
- BOOST_ASSERT(count_ == 0);
+ BOOST_ASSERT(this->count_ == 0);
       size_type new_count;
       if(first_n){
          new_count = division_count;
       }
       else{
- BOOST_ASSERT(difference_type(count_)>= division_count);
- new_count = count_ - division_count;
+ BOOST_ASSERT(difference_type(this->count_)>= division_count);
+ new_count = this->count_ - division_count;
       }
       //This function should never called with a count different to zero
       BOOST_ASSERT(new_count == 0);
@@ -147,21 +148,21 @@
    private:
    void priv_uninitialized_copy(Iterator p, const size_type n)
    {
- BOOST_ASSERT(n <= count_);
+ BOOST_ASSERT(n <= this->count_);
       Iterator orig_p = p;
       size_type i = 0;
       try{
          for(; i < n; ++i, ++p){
- alloc_traits::construct(a_, container_detail::to_raw_pointer(&*p));
+ alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
          }
       }
       catch(...){
          while(i--){
- alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
+ alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
          }
          throw;
       }
- count_ -= n;
+ this->count_ -= n;
    }
    A &a_;
    size_type count_;
@@ -223,13 +224,13 @@
    {
       BOOST_ASSERT(division_count <=1);
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!used_){
- alloc_traits::construct( a_
+ if(!this->used_){
+ alloc_traits::construct( this->a_
                                    , container_detail::to_raw_pointer(&*p)
                                    , ::boost::container::container_detail::
- stored_ref<Args>::forward(get<IdxPack>(args_))...
+ stored_ref<Args>::forward(get<IdxPack>(this->args_))...
                                    );
- used_ = true;
+ this->used_ = true;
          }
       }
    }
@@ -237,13 +238,13 @@
    template<int ...IdxPack>
    void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
    {
- if(!used_){
- alloc_traits::construct( a_
+ if(!this->used_){
+ alloc_traits::construct( this->a_
                                 , container_detail::to_raw_pointer(&*p)
                                 , ::boost::container::container_detail::
- stored_ref<Args>::forward(get<IdxPack>(args_))...
+ stored_ref<Args>::forward(get<IdxPack>(this->args_))...
                                 );
- used_ = true;
+ this->used_ = true;
       }
    }
 
@@ -260,6 +261,7 @@
    : public advanced_insert_aux_non_movable_emplace<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;
@@ -283,8 +285,13 @@
    void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
    {
       if(!this->used_){
- *p = boost::move(value_type (
- ::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
+ 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::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
+ scoped_destructor<A> d(this->a_, vp);
+ *p = boost::move(*vp);
+ d.release();
          this->used_ = true;
       }
    }
@@ -295,8 +302,17 @@
       BOOST_ASSERT(division_count <=1);
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){
          if(!this->used_){
- *p = boost::move(value_type(
- ::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
+ 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::container::container_detail::stored_ref<Args>::forward(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;
          }
       }
@@ -337,13 +353,13 @@
                                                                                     \
    virtual void uninitialized_copy_remaining_to(Iterator p) \
    { \
- if(!used_){ \
+ if(!this->used_){ \
          alloc_traits::construct \
- ( a_ \
+ ( this->a_ \
             , container_detail::to_raw_pointer(&*p) \
             BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
             ); \
- used_ = true; \
+ this->used_ = true; \
       } \
    } \
                                                                                     \
@@ -352,13 +368,13 @@
    { \
       BOOST_ASSERT(division_count <=1); \
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!used_){ \
+ if(!this->used_){ \
             alloc_traits::construct \
- ( a_ \
+ ( this->a_ \
                , container_detail::to_raw_pointer(&*p) \
                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
                ); \
- used_ = true; \
+ this->used_ = true; \
          } \
       } \
    } \
@@ -382,6 +398,7 @@
          <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 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, _) ) \
@@ -391,10 +408,13 @@
    virtual void copy_remaining_to(Iterator p) \
    { \
       if(!this->used_){ \
- value_type v BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- *p = boost::move(v); \
+ aligned_storage<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; \
       } \
    } \
@@ -405,10 +425,13 @@
       BOOST_ASSERT(division_count <=1); \
       if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
          if(!this->used_){ \
- value_type v BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- *p = boost::move(v); \
+ aligned_storage<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; \
          } \
       } \

Modified: trunk/boost/container/detail/algorithms.hpp
==============================================================================
--- trunk/boost/container/detail/algorithms.hpp (original)
+++ trunk/boost/container/detail/algorithms.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/container/detail/allocation_type.hpp
==============================================================================
--- trunk/boost/container/detail/allocation_type.hpp (original)
+++ trunk/boost/container/detail/allocation_type.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/config_begin.hpp
==============================================================================
--- trunk/boost/container/detail/config_begin.hpp (original)
+++ trunk/boost/container/detail/config_begin.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -45,4 +45,5 @@
                                     // with /GR-; unpredictable behavior may result
    #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
    #pragma warning (disable : 4671) // the copy constructor is inaccessible
+ #pragma warning (disable : 4584) // X is already a base-class of Y
 #endif //BOOST_MSVC

Modified: trunk/boost/container/detail/config_end.hpp
==============================================================================
--- trunk/boost/container/detail/config_end.hpp (original)
+++ trunk/boost/container/detail/config_end.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/destroyers.hpp
==============================================================================
--- trunk/boost/container/detail/destroyers.hpp (original)
+++ trunk/boost/container/detail/destroyers.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -21,7 +21,7 @@
 #include <boost/container/detail/workaround.hpp>
 #include <boost/container/detail/version_type.hpp>
 #include <boost/container/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 
 namespace boost {
 namespace container {
@@ -85,6 +85,9 @@
 
    void increment_size(size_type inc)
    { m_n += inc; }
+
+ void increment_size_backwards(size_type inc)
+ { m_n += inc; m_p -= inc; }
    
    ~scoped_destructor_n()
    {
@@ -115,10 +118,38 @@
    void increment_size(size_type)
    {}
 
+ void increment_size_backwards(size_type)
+ {}
+
    void release()
    {}
 };
 
+template<class A>
+class scoped_destructor
+{
+ typedef boost::container::allocator_traits<A> AllocTraits;
+ public:
+ typedef typename A::value_type value_type;
+ scoped_destructor(A &a, value_type *pv)
+ : pv_(pv), a_(a)
+ {}
+
+ ~scoped_destructor()
+ {
+ if(pv_){
+ AllocTraits::destroy(a_, pv_);
+ }
+ }
+
+ void release()
+ { pv_ = 0; }
+
+ private:
+ value_type *pv_;
+ A &a_;
+};
+
 template <class Allocator>
 class allocator_destroyer
 {

Modified: trunk/boost/container/detail/flat_tree.hpp
==============================================================================
--- trunk/boost/container/detail/flat_tree.hpp (original)
+++ trunk/boost/container/detail/flat_tree.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -102,11 +102,19 @@
       {}
 
       Data(const Data &d)
- : value_compare(d), m_vect(d.m_vect)
+ : value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect)
       {}
 
       Data(BOOST_RV_REF(Data) d)
- : value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
+ : value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
+ {}
+
+ Data(const Data &d, const A &a)
+ : value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
+ {}
+
+ Data(BOOST_RV_REF(Data) d, const A &a)
+ : value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
       {}
 
       Data(const Compare &comp)
@@ -185,6 +193,14 @@
       : m_data(boost::move(x.m_data))
    { }
 
+ flat_tree(const flat_tree& x, const allocator_type &a)
+ : m_data(x.m_data, a)
+ { }
+
+ flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
+ : m_data(boost::move(x.m_data), a)
+ { }
+
    template <class InputIterator>
    flat_tree( ordered_range_t, InputIterator first, InputIterator last
             , const Compare& comp = Compare()

Modified: trunk/boost/container/detail/function_detector.hpp
==============================================================================
--- trunk/boost/container/detail/function_detector.hpp (original)
+++ trunk/boost/container/detail/function_detector.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2009-2011.
+// (C) Copyright Ion Gaztanaga 2009-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/container/detail/iterators.hpp
==============================================================================
--- trunk/boost/container/detail/iterators.hpp (original)
+++ trunk/boost/container/detail/iterators.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
@@ -21,7 +21,7 @@
 #include "config_begin.hpp"
 #include <boost/container/detail/workaround.hpp>
 #include <boost/move/move.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 
 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 #include <boost/container/detail/variadic_templates_tools.hpp>
@@ -513,7 +513,7 @@
    container_detail::tuple<Args&...> args_;
 };
 
-#else
+#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 
 #define BOOST_PP_LOCAL_MACRO(n) \
    BOOST_PP_EXPR_IF(n, template <) \
@@ -522,16 +522,16 @@
    struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
    { \
       BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
- BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
+ ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
+ BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
                                                                                        \
       template<class A, class T> \
       void operator()(A &a, T *ptr) \
       { \
          allocator_traits<A>::construct \
- (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
+ (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
       } \
- BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
+ BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
    }; \
    //!
 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)

Modified: trunk/boost/container/detail/math_functions.hpp
==============================================================================
--- trunk/boost/container/detail/math_functions.hpp (original)
+++ trunk/boost/container/detail/math_functions.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,7 +1,7 @@
 //////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Stephen Cleary 2000.
-// (C) Copyright Ion Gaztanaga 2007-2011.
+// (C) Copyright Ion Gaztanaga 2007-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/container/detail/mpl.hpp
==============================================================================
--- trunk/boost/container/detail/mpl.hpp (original)
+++ trunk/boost/container/detail/mpl.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/container/detail/multiallocation_chain.hpp
==============================================================================
--- trunk/boost/container/detail/multiallocation_chain.hpp (original)
+++ trunk/boost/container/detail/multiallocation_chain.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -27,7 +27,7 @@
 #include <boost/container/detail/version_type.hpp>
 #include <boost/container/detail/type_traits.hpp>
 #include <boost/container/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/destroyers.hpp>
 
@@ -36,6 +36,7 @@
 #endif
 
 #include <boost/container/detail/algorithms.hpp>
+#include <new>
 
 
 namespace boost {
@@ -259,47 +260,21 @@
 
    void deallocate_one(const NodePtr &p, allocator_v2)
    { this->node_alloc().deallocate_one(p); }
-/*
- template<class A, class Convertible1, class Convertible2>
- static void construct(A &a, const NodePtr &ptr,
- BOOST_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
- {
- typedef typename Node::hook_type hook_type;
- typedef typename Node::value_type::first_type first_type;
- typedef typename Node::value_type::second_type second_type;
- Node *nodeptr = container_detail::to_raw_pointer(ptr);
-
- //Hook constructor does not throw
- allocator_traits<A>::construct(a, static_cast<hook_type*>(nodeptr));
-
- //Now construct pair members_holder
- value_type *valueptr = &nodeptr->get_data();
- allocator_traits<A>::construct(a, &valueptr->first, boost::move(value.first));
- BOOST_TRY{
- allocator_traits<A>::construct(a, &valueptr->second, boost::move(value.second));
- }
- BOOST_CATCH(...){
- allocator_traits<A>::destroy(a, &valueptr->first);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-*/
+
    #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-/*
- template<class A, class ...Args>
- static void construct(A &a, const NodePtr &ptr, Args &&...args)
- {
- }
-*/
+
    template<class ...Args>
    NodePtr create_node(Args &&...args)
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
       allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward<Args>(args)...);
+ ( this->node_alloc()
+ , container_detail::addressof(p->m_data), boost::forward<Args>(args)...);
       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);
    }
 
@@ -313,9 +288,11 @@
       NodePtr p = this->allocate_one(); \
       Deallocator node_deallocator(p, this->node_alloc()); \
       allocator_traits<NodeAlloc>::construct \
- (this->node_alloc(), container_detail::to_raw_pointer(p) \
+ (this->node_alloc(), container_detail::addressof(p->m_data) \
             BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
       node_deallocator.release(); \
+ typedef typename Node::hook_type hook_type; \
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type; \
       return (p); \
    } \
    //!
@@ -329,8 +306,11 @@
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
- ::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
+ ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
       node_deallocator.release();
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
       return (p);
    }
 
@@ -364,8 +344,11 @@
                mem.pop_front();
                //This can throw
                constructed = 0;
- boost::container::construct_in_place(this->node_alloc(), p, beg);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
                ++constructed;
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
                //This can throw in some containers (predicate might throw)
                inserter(*p);
             }

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-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/pair.hpp
==============================================================================
--- trunk/boost/container/detail/pair.hpp (original)
+++ trunk/boost/container/detail/pair.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -62,6 +62,33 @@
 struct piecewise_construct_t { };
 static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
 
+/*
+template <class T1, class T2>
+struct pair
+{
+ template <class U, class V> pair(pair<U, V>&& p);
+ template <class... Args1, class... Args2>
+ pair(piecewise_construct_t, tuple<Args1...> first_args,
+ tuple<Args2...> second_args);
+
+ template <class U, class V> pair& operator=(const pair<U, V>& p);
+ pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
+ is_nothrow_move_assignable<T2>::value);
+ template <class U, class V> pair& operator=(pair<U, V>&& p);
+
+ void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
+ noexcept(swap(second, p.second)));
+};
+
+template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
+*/
+
+
 template <class T1, class T2>
 struct pair
 {
@@ -79,47 +106,40 @@
    pair()
       : first(), second()
    {}
-/*
- //pair from two values
- pair(const T1 &t1, const T2 &t2)
- : first(t1)
- , second(t2)
- {}
-
-
- //pair from two values
- pair(BOOST_RV_REF(T1) t1, BOOST_RV_REF(T2) t2)
- : first(::boost::move(t1))
- , second(::boost::move(t2))
- {}
-*/
- template<class U, class V>
- pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
- : first(::boost::forward<U>(u))
- , second(::boost::forward<V>(v))
- {}
 
    //pair copy assignment
    pair(const pair& x)
       : first(x.first), second(x.second)
    {}
 
+ //pair move constructor
+ pair(BOOST_RV_REF(pair) p)
+ : first(::boost::move(p.first)), second(::boost::move(p.second))
+ {}
+
    template <class D, class S>
    pair(const pair<D, S> &p)
       : first(p.first), second(p.second)
    {}
 
- //pair move constructor
- pair(BOOST_RV_REF(pair) p)
+ template <class D, class S>
+ pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
- template <class D, class S>
- pair(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
- : first(::boost::move(p.first)), second(::boost::move(p.second))
+ //pair from two values
+ pair(const T1 &t1, const T2 &t2)
+ : first(t1)
+ , second(t2)
    {}
 
- //std::pair copy constructor
+ template<class U, class V>
+ pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
+ : first(::boost::forward<U>(u))
+ , second(::boost::forward<V>(v))
+ {}
+
+ //And now compatibility with std::pair
    pair(const std::pair<T1, T2>& x)
       : first(x.first), second(x.second)
    {}
@@ -129,17 +149,20 @@
       : first(p.first), second(p.second)
    {}
 
- //std::pair move constructor
- template <class D, class S>
- pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
- pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ template <class D, class S>
+ pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
       : first(::boost::move(p.first)), second(::boost::move(p.second))
    {}
 
    //piecewise_construct missing
+ //template <class U, class V> pair(pair<U, V>&& p);
+ //template <class... Args1, class... Args2>
+ // pair(piecewise_construct_t, tuple<Args1...> first_args,
+ // tuple<Args2...> second_args);
 /*
    //Variadic versions
    template<class U>
@@ -179,14 +202,6 @@
       return *this;
    }
 
- template <class D, class S>
- pair& operator=(const pair<D, S>&p)
- {
- first = p.first;
- second = p.second;
- return *this;
- }
-
    //pair move assignment
    pair& operator=(BOOST_RV_REF(pair) p)
    {
@@ -196,7 +211,15 @@
    }
 
    template <class D, class S>
- pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+ pair& operator=(const pair<D, S>&p)
+ {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+
+ template <class D, class S>
+ pair& operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
    {
       first = ::boost::move(p.first);
       second = ::boost::move(p.second);
@@ -220,7 +243,7 @@
    }
 
    //std::pair move assignment
- pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
    {
       first = ::boost::move(p.first);
       second = ::boost::move(p.second);
@@ -228,7 +251,7 @@
    }
 
    template <class D, class S>
- pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
    {
       first = ::boost::move(p.first);
       second = ::boost::move(p.second);

Modified: trunk/boost/container/detail/pool_common.hpp
==============================================================================
--- trunk/boost/container/detail/pool_common.hpp (original)
+++ trunk/boost/container/detail/pool_common.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/container/detail/preprocessor.hpp (original)
+++ trunk/boost/container/detail/preprocessor.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -62,6 +62,10 @@
    //!
 #endif //#ifndef BOOST_NO_RVALUE_REFERENCES
 
+#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
+const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
+//!
+
 #ifndef BOOST_NO_RVALUE_REFERENCES
    #define BOOST_CONTAINER_PP_PARAM(U, u) \
    U && u \
@@ -152,7 +156,11 @@
 //!
 
 #define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
- BOOST_PP_CAT(class P, n) = void \
+ BOOST_PP_CAT(class P, n) = void \
+//!
+
+#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
+ BOOST_PP_CAT(class P, n) = default_type \
 //!
 
 #define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \

Modified: trunk/boost/container/detail/stored_ref.hpp
==============================================================================
--- trunk/boost/container/detail/stored_ref.hpp (original)
+++ trunk/boost/container/detail/stored_ref.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/transform_iterator.hpp
==============================================================================
--- trunk/boost/container/detail/transform_iterator.hpp (original)
+++ trunk/boost/container/detail/transform_iterator.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.

Modified: trunk/boost/container/detail/tree.hpp
==============================================================================
--- trunk/boost/container/detail/tree.hpp (original)
+++ trunk/boost/container/detail/tree.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -27,7 +27,7 @@
 #include <boost/container/detail/destroyers.hpp>
 #include <boost/container/detail/pair.hpp>
 #include <boost/container/detail/type_traits.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
 #include <boost/container/detail/preprocessor.hpp>
 #endif
@@ -90,43 +90,49 @@
>::type type;
 };
 
+//This trait is used to type-pun std::pair because in C++03
+//compilers std::pair is useless for C++11 features
 template<class T>
-struct rbtree_type
+struct rbtree_internal_data_type
 {
    typedef T type;
 };
 
 template<class T1, class T2>
-struct rbtree_type< std::pair<T1, T2> >
+struct rbtree_internal_data_type< std::pair<T1, T2> >
 {
    typedef pair<T1, T2> type;
 };
 
+
+//The node to be store in the tree
 template <class T, class VoidPointer>
 struct rbtree_node
    : public rbtree_hook<VoidPointer>::type
 {
- private:
- BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
+ //private:
+ //BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
 
    public:
    typedef typename rbtree_hook<VoidPointer>::type hook_type;
 
    typedef T value_type;
- typedef typename rbtree_type<T>::type internal_type;
+ typedef typename rbtree_internal_data_type<T>::type internal_type;
 
    typedef rbtree_node<T, VoidPointer> node_type;
 
- rbtree_node()
- : m_data()
- {}
+ private:
+ rbtree_node();
+ rbtree_node (const rbtree_node &);
+ rbtree_node & operator=(const rbtree_node &);
 
+/*
    rbtree_node(const rbtree_node &other)
       : m_data(other.m_data)
    {}
 
    rbtree_node(BOOST_RV_REF(rbtree_node) other)
- : m_data(boost::move(other.m_data))
+ : m_data(::boost::move(other.m_data))
    {}
 
    #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -152,8 +158,9 @@
    { do_assign(other.m_data); return *this; }
 
    rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
- { do_move(other.m_data); return *this; }
-
+ { do_move_assign(other.m_data); return *this; }
+*/
+ public:
    T &get_data()
    {
       T* ptr = reinterpret_cast<T*>(&this->m_data);
@@ -166,7 +173,7 @@
       return *ptr;
    }
 
- private:
+// private:
    internal_type m_data;
 
    template<class A, class B>
@@ -188,22 +195,22 @@
    { m_data = v; }
 
    template<class A, class B>
- void do_move(std::pair<const A, B> &p)
+ void do_move_assign(std::pair<const A, B> &p)
    {
- const_cast<A&>(m_data.first) = boost::move(p.first);
- m_data.second = boost::move(p.second);
+ const_cast<A&>(m_data.first) = ::boost::move(p.first);
+ m_data.second = ::boost::move(p.second);
    }
 
    template<class A, class B>
- void do_move(pair<const A, B> &p)
+ void do_move_assign(pair<const A, B> &p)
    {
- const_cast<A&>(m_data.first) = boost::move(p.first);
- m_data.second = boost::move(p.second);
+ const_cast<A&>(m_data.first) = ::boost::move(p.first);
+ m_data.second = ::boost::move(p.second);
    }
 
    template<class V>
- void do_move(V &v)
- { m_data = boost::move(v); }
+ void do_move_assign(V &v)
+ { m_data = ::boost::move(v); }
 };
 
 }//namespace container_detail {
@@ -282,7 +289,7 @@
             //First recycle a node (this can't throw)
             try{
                //This can throw
- *p = other;
+ p->do_assign(other.m_data);
                return p;
             }
             catch(...){
@@ -295,7 +302,7 @@
             }
          }
          else{
- return m_holder.create_node(other);
+ return m_holder.create_node(other.m_data);
          }
       }
 
@@ -319,7 +326,7 @@
             //First recycle a node (this can't throw)
             try{
                //This can throw
- *p = boost::move(other);
+ p->do_move_assign(const_cast<Node &>(other).m_data);
                return p;
             }
             catch(...){
@@ -332,7 +339,7 @@
             }
          }
          else{
- return m_holder.create_node(other);
+ return m_holder.create_node(other.m_data);
          }
       }
 
@@ -478,8 +485,10 @@
       iterator(){}
 
       //Pointer like operators
- reference operator*() const { return this->m_it->get_data(); }
- pointer operator->() const { return pointer(&this->m_it->get_data()); }
+ reference operator*() const
+ { return this->m_it->get_data(); }
+ pointer operator->() const
+ { return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data()); }
 
       //Increment / Decrement
       iterator& operator++()
@@ -532,9 +541,28 @@
    }
 
    rbtree(BOOST_RV_REF(rbtree) x)
- : AllocHolder(boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
+ : AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
    {}
 
+ rbtree(const rbtree& x, const allocator_type &a)
+ : AllocHolder(a, x.key_comp())
+ {
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ }
+
+ rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
+ : AllocHolder(a, x.key_comp())
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->icont().swap(x.icont());
+ }
+ else{
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ }
+ }
+
    ~rbtree()
    {} //AllocHolder clears the tree
 
@@ -552,7 +580,7 @@
          //Transfer all the nodes to a temporary tree
          //If anything goes wrong, all the nodes will be destroyed
          //automatically
- Icont other_tree(boost::move(this->icont()));
+ Icont other_tree(::boost::move(this->icont()));
 
          //Now recreate the source tree reusing nodes stored by other_tree
          this->icont().clone_from
@@ -578,7 +606,7 @@
          if(this_alloc == x_alloc){
             //Destroy and swap pointers
             this->clear();
- this->icont() = boost::move(x.icont());
+ this->icont() = ::boost::move(x.icont());
             //Move allocator if needed
             this->AllocHolder::move_assign_alloc(x);
          }
@@ -587,7 +615,7 @@
             //Transfer all the nodes to a temporary tree
             //If anything goes wrong, all the nodes will be destroyed
             //automatically
- Icont other_tree(boost::move(this->icont()));
+ Icont other_tree(::boost::move(this->icont()));
 
             //Now recreate the source tree reusing nodes stored by other_tree
             this->icont().clone_from

Modified: trunk/boost/container/detail/type_traits.hpp
==============================================================================
--- trunk/boost/container/detail/type_traits.hpp (original)
+++ trunk/boost/container/detail/type_traits.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,13 @@
 
 struct nat{};
 
+template <typename U>
+struct LowPriorityConversion
+{
+ // Convertible from T with user-defined-conversion rank.
+ LowPriorityConversion(const U&) { }
+};
+
 //boost::alignment_of yields to 10K lines of preprocessed code, so we
 //need an alternative
 template <typename T> struct alignment_of;

Modified: trunk/boost/container/detail/utilities.hpp
==============================================================================
--- trunk/boost/container/detail/utilities.hpp (original)
+++ trunk/boost/container/detail/utilities.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -21,13 +21,23 @@
 #include <boost/move/move.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/type_traits.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <algorithm>
 
 namespace boost {
 namespace container {
 namespace container_detail {
 
+template <typename T>
+inline T* addressof(T& obj)
+{
+ return static_cast<T*>(
+ static_cast<void*>(
+ const_cast<char*>(
+ &reinterpret_cast<const char&>(obj)
+ )));
+}
+
 template<class T>
 const T &max_value(const T &a, const T &b)
 { return a > b ? a : b; }
@@ -262,6 +272,7 @@
    return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
 }
 
+
 } //namespace container {
 } //namespace boost {
 

Modified: trunk/boost/container/detail/value_init.hpp
==============================================================================
--- trunk/boost/container/detail/value_init.hpp (original)
+++ trunk/boost/container/detail/value_init.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/container/detail/variadic_templates_tools.hpp
==============================================================================
--- trunk/boost/container/detail/variadic_templates_tools.hpp (original)
+++ trunk/boost/container/detail/variadic_templates_tools.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/version_type.hpp
==============================================================================
--- trunk/boost/container/detail/version_type.hpp (original)
+++ trunk/boost/container/detail/version_type.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/container/detail/workaround.hpp
==============================================================================
--- trunk/boost/container/detail/workaround.hpp (original)
+++ trunk/boost/container/detail/workaround.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -26,6 +26,11 @@
    #define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
 #endif
 
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
+ && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
+ #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
+#endif
+
 #include <boost/container/detail/config_end.hpp>
 
 #endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP

Modified: trunk/boost/container/flat_map.hpp
==============================================================================
--- trunk/boost/container/flat_map.hpp (original)
+++ trunk/boost/container/flat_map.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -26,7 +26,7 @@
 #include <boost/container/detail/flat_tree.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/container/detail/mpl.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/move/move.hpp>
 
 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -209,23 +209,38 @@
    //! <b>Effects</b>: Copy constructs a flat_map.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_map(const flat_map<Key,T,Pred,A>& x)
+ flat_map(const flat_map& x)
       : m_flat_tree(x.m_flat_tree) {}
 
    //! <b>Effects</b>: Move constructs a flat_map.
    //! Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    flat_map(BOOST_RV_REF(flat_map) x)
       : m_flat_tree(boost::move(x.m_flat_tree))
    {}
 
+ //! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_map(const flat_map& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
+ flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
+ : m_flat_tree(boost::move(x.m_flat_tree), a)
+ {}
+
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_map<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
+ flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
    { m_flat_tree = x.m_flat_tree; return *this; }
 
    //! <b>Effects</b>: Move constructs a flat_map.
@@ -234,7 +249,7 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- flat_map<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_map) mx)
+ flat_map& operator=(BOOST_RV_REF(flat_map) mx)
    { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
 
    //! <b>Effects</b>: Returns the comparison object out
@@ -960,28 +975,43 @@
    //! <b>Effects</b>: Copy constructs a flat_multimap.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_multimap(const flat_multimap<Key,T,Pred,A>& x)
+ flat_multimap(const flat_multimap& x)
       : m_flat_tree(x.m_flat_tree) { }
 
    //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    flat_multimap(BOOST_RV_REF(flat_multimap) x)
       : m_flat_tree(boost::move(x.m_flat_tree))
    { }
 
+ //! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multimap(const flat_multimap& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
+ : m_flat_tree(boost::move(x.m_flat_tree), a)
+ { }
+
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_multimap<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
+ flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
    //!
    //! <b>Complexity</b>: Constant.
- flat_multimap<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_multimap) mx)
+ flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx)
       { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
 
    //! <b>Effects</b>: Returns the comparison object out

Modified: trunk/boost/container/flat_set.hpp
==============================================================================
--- trunk/boost/container/flat_set.hpp (original)
+++ trunk/boost/container/flat_set.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -100,14 +100,14 @@
    typedef typename tree_t::allocator_type allocator_type;
    typedef typename tree_t::stored_allocator_type stored_allocator_type;
 
- //! <b>Effects</b>: Defatuls constructs an empty flat_map.
+ //! <b>Effects</b>: Default constructs an empty flat_set.
    //!
    //! <b>Complexity</b>: Constant.
    explicit flat_set()
       : m_flat_tree()
    {}
 
- //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! <b>Effects</b>: Constructs an empty flat_set using the specified
    //! comparison object and allocator.
    //!
    //! <b>Complexity</b>: Constant.
@@ -116,7 +116,7 @@
       : m_flat_tree(comp, a)
    {}
 
- //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
    //! allocator, and inserts elements from the range [first ,last ).
    //!
    //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
@@ -143,31 +143,47 @@
       : m_flat_tree(ordered_range, first, last, comp, a)
    {}
 
- //! <b>Effects</b>: Copy constructs a map.
+ //! <b>Effects</b>: Copy constructs a set.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_set(const flat_set<T,Pred,A>& x)
- : m_flat_tree(x.m_flat_tree) {}
+ flat_set(const flat_set& x)
+ : m_flat_tree(x.m_flat_tree)
+ {}
 
- //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
+ //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    flat_set(BOOST_RV_REF(flat_set) mx)
       : m_flat_tree(boost::move(mx.m_flat_tree))
    {}
 
+ //! <b>Effects</b>: Copy constructs a set using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set(const flat_set& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a set using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
+ flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a)
+ : m_flat_tree(boost::move(mx.m_flat_tree), a)
+ {}
+
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_set<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
+ flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
- //! <b>Effects</b>: Makes *this a copy of x.
+ //! <b>Effects</b>: Makes *this a copy of the previous value of xx.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_set<T,Pred,A>& operator=(BOOST_RV_REF(flat_set) mx)
+ flat_set& operator=(BOOST_RV_REF(flat_set) mx)
    { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
 
    //! <b>Effects</b>: Returns the comparison object out
@@ -729,7 +745,7 @@
    typedef typename tree_t::allocator_type allocator_type;
    typedef typename tree_t::stored_allocator_type stored_allocator_type;
 
- //! <b>Effects</b>: Defatuls constructs an empty flat_map.
+ //! <b>Effects</b>: Default constructs an empty flat_multiset.
    //!
    //! <b>Complexity</b>: Constant.
    explicit flat_multiset()
@@ -761,17 +777,47 @@
       : m_flat_tree(ordered_range, first, last, comp, a)
    {}
 
- flat_multiset(const flat_multiset<T,Pred,A>& x)
- : m_flat_tree(x.m_flat_tree) {}
+ //! <b>Effects</b>: Copy constructs a flat_multiset.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset(const flat_multiset& x)
+ : m_flat_tree(x.m_flat_tree)
+ {}
 
- flat_multiset(BOOST_RV_REF(flat_multiset) x)
- : m_flat_tree(boost::move(x.m_flat_tree))
+ //! <b>Effects</b>: Move constructs a flat_multiset. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_multiset(BOOST_RV_REF(flat_multiset) mx)
+ : m_flat_tree(boost::move(mx.m_flat_tree))
+ {}
+
+ //! <b>Effects</b>: Copy constructs a flat_multiset using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset(const flat_multiset& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
    {}
 
- flat_multiset<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
+ //! <b>Effects</b>: Move constructs a flat_multiset using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
+ flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a)
+ : m_flat_tree(boost::move(mx.m_flat_tree), a)
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
- flat_multiset<T,Pred,A>& operator=(BOOST_RV_REF(flat_multiset) mx)
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
    { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
 
    //! <b>Effects</b>: Returns the comparison object out

Modified: trunk/boost/container/list.hpp
==============================================================================
--- trunk/boost/container/list.hpp (original)
+++ trunk/boost/container/list.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -65,30 +65,13 @@
 struct list_node
    : public list_hook<VoidPointer>::type
 {
+ private:
+ list_node();
+ list_node(const list_node &);
+ list_node & operator=(const list_node &);
 
- list_node()
- : m_data()
- {}
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- template<class ...Args>
- list_node(Args &&...args)
- : m_data(boost::forward<Args>(args)...)
- {}
-
- #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- list_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
+ public:
+ typedef typename list_hook<VoidPointer>::type hook_type;
    T m_data;
 };
 
@@ -374,6 +357,34 @@
       : AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
    {}
 
+ //! <b>Effects</b>: Copy constructs a list using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ list(const list& x, const allocator_type &a)
+ : AllocHolder(a)
+ { this->insert(this->cbegin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor sing the specified allocator.
+ //! Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ list(BOOST_RV_REF(list) x, const allocator_type &a)
+ : AllocHolder(a)
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->icont().swap(x.icont());
+ }
+ else{
+ this->insert(this->cbegin(), x.begin(), x.end());
+ }
+ }
+
    //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
    //! and inserts a copy of the range [first, last) in the list.
    //!

Modified: trunk/boost/container/map.hpp
==============================================================================
--- trunk/boost/container/map.hpp (original)
+++ trunk/boost/container/map.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -158,7 +158,7 @@
       : m_tree(first, last, comp, a, true)
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
@@ -175,29 +175,52 @@
       : m_tree(ordered_range, first, last, comp, a)
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Copy constructs a map.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- map(const map<Key,T,Pred,A>& x)
+ map(const map& x)
       : m_tree(x.m_tree)
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    map(BOOST_RV_REF(map) x)
       : m_tree(boost::move(x.m_tree))
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Copy constructs a map using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ map(const map& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Move constructs a map using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ map(BOOST_RV_REF(map) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Makes *this a copy of x.
@@ -833,7 +856,7 @@
       : m_tree(comp, a)
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
@@ -848,7 +871,7 @@
       : m_tree(first, last, comp, a, false)
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
@@ -864,27 +887,48 @@
       : m_tree(ordered_range, first, last, comp, a)
    {}
 
-
    //! <b>Effects</b>: Copy constructs a multimap.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- multimap(const multimap<Key,T,Pred,A>& x)
+ multimap(const multimap& x)
       : m_tree(x.m_tree)
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    multimap(BOOST_RV_REF(multimap) x)
       : m_tree(boost::move(x.m_tree))
    {
       //Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Copy constructs a multimap.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multimap(const multimap& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Move constructs a multimap using the specified allocator.
+ //! Constructs *this using x's resources.
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
    }
 
    //! <b>Effects</b>: Makes *this a copy of x.

Modified: trunk/boost/container/set.hpp
==============================================================================
--- trunk/boost/container/set.hpp (original)
+++ trunk/boost/container/set.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -144,16 +144,31 @@
 
    //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    set(BOOST_RV_REF(set) x)
       : m_tree(boost::move(x.m_tree))
    {}
 
- //! <b>Effects</b>: Makes *this a copy of x.
+ //! <b>Effects</b>: Copy constructs a set using the specified allocator.
    //!
    //! <b>Complexity</b>: Linear in x.size().
+ set(const set& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a set using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ set(BOOST_RV_REF(set) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
    set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
    { m_tree = x.m_tree; return *this; }
 
@@ -716,13 +731,30 @@
 
    //! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
    //!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
    //!
    //! <b>Postcondition</b>: x is emptied.
    multiset(BOOST_RV_REF(multiset) x)
       : m_tree(boost::move(x.m_tree))
    {}
 
+ //! <b>Effects</b>: Copy constructs a multiset using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multiset(const multiset& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a multiset using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {}
+
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().

Modified: trunk/boost/container/slist.hpp
==============================================================================
--- trunk/boost/container/slist.hpp (original)
+++ trunk/boost/container/slist.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -65,31 +65,13 @@
 struct slist_node
    : public slist_hook<VoidPointer>::type
 {
+ private:
+ slist_node();
+ slist_node(const slist_node &);
+ slist_node & operator=(const slist_node &);
 
- slist_node()
- : m_data()
- {}
-
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- template<class ...Args>
- slist_node(Args &&...args)
- : m_data(boost::forward<Args>(args)...)
- {}
-
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
+ public:
+ typedef typename slist_hook<VoidPointer>::type hook_type;
    T m_data;
 };
 
@@ -391,6 +373,34 @@
       : AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
    {}
 
+ //! <b>Effects</b>: Copy constructs a list using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ slist(const slist& x, const allocator_type &a)
+ : AllocHolder(a)
+ { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves x's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ slist(BOOST_RV_REF(slist) x, const allocator_type &a)
+ : AllocHolder(a)
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->icont().swap(x.icont());
+ }
+ else{
+ this->insert(this->cbegin(), x.begin(), x.end());
+ }
+ }
+
    //! <b>Effects</b>: Makes *this contain the same elements as x.
    //!
    //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy

Modified: trunk/boost/container/stable_vector.hpp
==============================================================================
--- trunk/boost/container/stable_vector.hpp (original)
+++ trunk/boost/container/stable_vector.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -34,7 +34,7 @@
 #include <boost/container/detail/utilities.hpp>
 #include <boost/container/detail/iterators.hpp>
 #include <boost/container/detail/algorithms.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 
 #include <algorithm>
@@ -78,10 +78,6 @@
    { return ptr;}
 };
 
-template<class Ptr>
-inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
-{ return smart_ptr_type<Ptr>::get(ptr); }
-
 template <class C>
 class clear_on_destroy
 {
@@ -110,13 +106,10 @@
 
 template<class VoidPtr>
 struct node_type_base
-{/*
- node_type_base(VoidPtr p)
- : up(p)
- {}*/
+{
    node_type_base()
    {}
- void set_pointer(VoidPtr p)
+ void set_pointer(const VoidPtr &p)
    { up = p; }
 
    VoidPtr up;
@@ -126,33 +119,12 @@
 struct node_type
    : public node_type_base<VoidPointer>
 {
- node_type()
- : value()
- {}
-
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- template<class ...Args>
- node_type(Args &&...args)
- : value(boost::forward<Args>(args)...)
- {}
-
- #else //BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif//BOOST_CONTAINER_PERFECT_FORWARDING
-
- void set_pointer(VoidPointer p)
- { node_type_base<VoidPointer>::set_pointer(p); }
+ private:
+ node_type();
+ node_type(const node_type &);
+ node_type & operator=(const node_type &);
 
+ public:
    T value;
 };
 
@@ -206,17 +178,17 @@
    private:
    static node_type_ptr_t node_ptr_cast(const void_ptr &p)
    {
- return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
    }
 
    static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
    {
- return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return const_node_type_ptr_t(static_cast<const node_type_t*>(container_detail::to_raw_pointer(p)));
    }
 
    static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
    {
- return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
+ return void_ptr_ptr(static_cast<void_ptr*>(container_detail::to_raw_pointer(p)));
    }
 
    reference dereference() const
@@ -353,35 +325,37 @@
 
 /// @endcond
 
-//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
-//!drop-in replacement implemented as a node container, offering iterator and reference
-//!stability.
+//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
+//! drop-in replacement implemented as a node container, offering iterator and reference
+//! stability.
 //!
-//!More details taken the author's blog: ( Introducing stable_vector)
+//! More details taken the author's blog:
+//! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
+//! Introducing stable_vector</a>)
 //!
-//!We present stable_vector, a fully STL-compliant stable container that provides
-//!most of the features of std::vector except element contiguity.
+//! We present stable_vector, a fully STL-compliant stable container that provides
+//! most of the features of std::vector except element contiguity.
 //!
-//!General properties: stable_vector satisfies all the requirements of a container,
-//!a reversible container and a sequence and provides all the optional operations
-//!present in std::vector. Like std::vector, iterators are random access.
-//!stable_vector does not provide element contiguity; in exchange for this absence,
-//!the container is stable, i.e. references and iterators to an element of a stable_vector
-//!remain valid as long as the element is not erased, and an iterator that has been
-//!assigned the return value of end() always remain valid until the destruction of
-//!the associated stable_vector.
+//! General properties: stable_vector satisfies all the requirements of a container,
+//! a reversible container and a sequence and provides all the optional operations
+//! present in std::vector. Like std::vector, iterators are random access.
+//! stable_vector does not provide element contiguity; in exchange for this absence,
+//! the container is stable, i.e. references and iterators to an element of a stable_vector
+//! remain valid as long as the element is not erased, and an iterator that has been
+//! assigned the return value of end() always remain valid until the destruction of
+//! the associated stable_vector.
 //!
-//!Operation complexity: The big-O complexities of stable_vector operations match
-//!exactly those of std::vector. In general, insertion/deletion is constant time at
-//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
-//!does not internally perform any value_type destruction, copy or assignment
-//!operations other than those exactly corresponding to the insertion of new
-//!elements or deletion of stored elements, which can sometimes compensate in terms
-//!of performance for the extra burden of doing more pointer manipulation and an
-//!additional allocation per element.
+//! Operation complexity: The big-O complexities of stable_vector operations match
+//! exactly those of std::vector. In general, insertion/deletion is constant time at
+//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
+//! does not internally perform any value_type destruction, copy or assignment
+//! operations other than those exactly corresponding to the insertion of new
+//! elements or deletion of stored elements, which can sometimes compensate in terms
+//! of performance for the extra burden of doing more pointer manipulation and an
+//! additional allocation per element.
 //!
-//!Exception safety: As stable_vector does not internally copy elements around, some
-//!operations provide stronger exception safety guarantees than in std::vector:
+//! Exception safety: As stable_vector does not internally copy elements around, some
+//! operations provide stronger exception safety guarantees than in std::vector:
 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 template <class T, class A = std::allocator<T> >
 #else
@@ -524,7 +498,7 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- explicit stable_vector(const A& al)
+ explicit stable_vector(const allocator_type& al)
       : internal_data(al),impl(al)
    {
       STABLE_VECTOR_CHECK_INVARIANT;
@@ -538,7 +512,7 @@
    //!
    //! <b>Complexity</b>: Linear to n.
    explicit stable_vector(size_type n)
- : internal_data(A()),impl(A())
+ : internal_data(),impl()
    {
       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
       this->resize(n);
@@ -553,7 +527,7 @@
    //! throws or T's default or copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to n.
- stable_vector(size_type n, const T& t, const A& al=A())
+ stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
       : internal_data(al),impl(al)
    {
       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -570,7 +544,7 @@
    //!
    //! <b>Complexity</b>: Linear to the range [first, last).
    template <class InputIterator>
- stable_vector(InputIterator first,InputIterator last,const A& al=A())
+ stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
       : internal_data(al),impl(al)
    {
       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -607,6 +581,40 @@
       this->priv_swap_members(x);
    }
 
+ //! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ stable_vector(const stable_vector& x, const allocator_type &a)
+ : internal_data(a), impl(a)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), x.begin(), x.end());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
+ stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
+ : internal_data(a), impl(a)
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->priv_swap_members(x);
+ }
+ else{
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), x.begin(), x.end());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+ }
+
    //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
    //! and used memory is deallocated.
    //!
@@ -709,7 +717,7 @@
    //! <b>Throws</b>: If allocator's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- allocator_type get_allocator()const {return node_alloc();}
+ allocator_type get_allocator()const {return this->node_alloc();}
 
    //! <b>Effects</b>: Returns a reference to the internal allocator.
    //!
@@ -1137,7 +1145,7 @@
    void emplace_back(Args &&...args)
    {
       typedef emplace_functor<Args...> EmplaceFunctor;
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
       EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
       this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
    }
@@ -1157,7 +1165,7 @@
       //Just call more general insert(pos, size, value) and return iterator
       size_type pos_n = position - cbegin();
       typedef emplace_functor<Args...> EmplaceFunctor;
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
       EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
       this->insert(position, EmplaceIterator(ef), EmplaceIterator());
       return iterator(this->begin() + pos_n);
@@ -1172,7 +1180,7 @@
       typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
          BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
             EmplaceFunctor; \
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
       EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
                         BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
                         BOOST_PP_RPAREN_IF(n); \
@@ -1186,7 +1194,7 @@
       typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
          BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
             EmplaceFunctor; \
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
       EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
                         BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
                         BOOST_PP_RPAREN_IF(n); \
@@ -1482,12 +1490,12 @@
 
    static node_type_ptr_t node_ptr_cast(const void_ptr &p)
    {
- return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
    }
 
    static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
    {
- return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return node_type_base_ptr_t(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p)));
    }
 
    static value_type& value(const void_ptr &p)
@@ -1529,7 +1537,9 @@
    {
       node_type_ptr_t p = this->allocate_one();
       try{
- boost::container::construct_in_place(this->node_alloc(), &*p, it);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), it);
+ //This does not throw
+ ::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
          p->set_pointer(up);
       }
       catch(...){
@@ -1621,7 +1631,9 @@
             p = mem.front();
             mem.pop_front();
             //This can throw
- boost::container::construct_in_place(this->node_alloc(), &*p, first);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+ //This does not throw
+ ::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
             p->set_pointer(void_ptr_ptr(&it[i]));
             ++first;
             it[i] = p;
@@ -1650,7 +1662,9 @@
                break;
             }
             //This can throw
- boost::container::construct_in_place(this->node_alloc(), &*p, first);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+ //This does not throw
+ ::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
             p->set_pointer(void_ptr_ptr(&it[i]));
             ++first;
             it[i]=p;

Modified: trunk/boost/container/string.hpp
==============================================================================
--- trunk/boost/container/string.hpp (original)
+++ trunk/boost/container/string.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -43,7 +43,7 @@
 #include <boost/container/detail/algorithms.hpp>
 #include <boost/container/detail/version_type.hpp>
 #include <boost/container/detail/allocation_type.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/container/detail/mpl.hpp>
 #include <boost/move/move.hpp>
 #include <boost/static_assert.hpp>
@@ -620,12 +620,12 @@
    //!
    //! <b>Postcondition</b>: x == *this.
    //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //! <b>Throws</b>: If allocator_type's default constructor throws.
    basic_string(const basic_string& s)
       : base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
    { this->priv_range_initialize(s.begin(), s.end()); }
 
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //! <b>Effects</b>: Move constructor. Moves s's resources to *this.
    //!
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
@@ -634,6 +634,32 @@
       : base_t(boost::move((base_t&)s))
    {}
 
+ //! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocation throws.
+ basic_string(const basic_string& s, const allocator_type &a)
+ : base_t(a)
+ { this->priv_range_initialize(s.begin(), s.end()); }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves s's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocation throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == s.get_allocator(), linear otherwise.
+ basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
+ : base_t(a)
+ {
+ if(a == this->alloc()){
+ this->swap_data(s);
+ }
+ else{
+ this->priv_range_initialize(s.begin(), s.end());
+ }
+ }
+
    //! <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,

Modified: trunk/boost/container/vector.hpp
==============================================================================
--- trunk/boost/container/vector.hpp (original)
+++ trunk/boost/container/vector.hpp 2012-03-22 14:46:55 EDT (Thu, 22 Mar 2012)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -38,7 +38,7 @@
 #include <boost/container/detail/iterators.hpp>
 #include <boost/container/detail/algorithms.hpp>
 #include <boost/container/detail/destroyers.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/container/container_fwd.hpp>
 #include <boost/move/move.hpp>
 #include <boost/move/move_helpers.hpp>
@@ -46,6 +46,7 @@
 #include <boost/container/detail/mpl.hpp>
 #include <boost/container/detail/type_traits.hpp>
 #include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/assert.hpp>
 
 namespace boost {
 namespace container {
@@ -540,6 +541,40 @@
       : base_t(boost::move(mx.alloc()))
    { this->swap_members(mx); }
 
+ //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocation
+ //! throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ vector(const vector &x, const allocator_type &a)
+ : base_t(a)
+ {
+ this->assign( container_detail::to_raw_pointer(x.members_.m_start)
+ , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
+ }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves mx's resources to *this if a == allocator_type().
+ //! Otherwise copies values from x to *this.
+ //!
+ //! <b>Throws</b>: If allocation or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
+ vector(BOOST_RV_REF(vector) mx, const allocator_type &a)
+ : base_t(a)
+ {
+ if(mx.alloc() == a){
+ this->swap_members(mx);
+ }
+ else{
+ this->assign( container_detail::to_raw_pointer(mx.members_.m_start)
+ , container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size));
+ }
+ }
+
    //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
    //! and inserts a copy of the range [first, last) in the vector.
    //!
@@ -1428,6 +1463,87 @@
       }
    }
 
+ private:
+ template<class BiDirIt>
+ void insert_at_ordered_positions(const size_type *positions, size_type element_count, BiDirIt end)
+ {
+ const size_type old_size_pos = this->size();
+ this->reserve(old_size_pos + element_count);
+ T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
+ size_type insertions_left = element_count;
+ size_type next_pos = old_size_pos;
+ size_type hole_size = element_count;
+
+ //Exception rollback. If any copy throws before the hole is filled, values
+ //already inserted/copied at the end of the buffer will be destroyed.
+ typename value_traits::ArrayDestructor past_hole_values_destroyer
+ (begin_ptr + old_size_pos + element_count, this->alloc(), size_type(0u));
+ //Loop for each insertion backwards, first moving the elements after the insertion point,
+ //then inserting the element.
+ while(insertions_left){
+ const size_type pos = positions[insertions_left - 1];
+ BOOST_ASSERT(pos <= old_size_pos);
+ //Shift the range after the insertion point, function will take care if the shift
+ //crosses the size() boundary, using copy/move or uninitialized copy/move if necessary.
+ size_type new_hole_size = shift_range(pos, next_pos, this->size(), insertions_left);
+ if(new_hole_size > 0){
+ //The hole was reduced by shift_range so expand exception rollback range backwards
+ past_hole_values_destroyer.increment_size_backwards(next_pos - pos);
+ //Insert the new value in the hole
+ allocator_traits_type::construct(this->alloc(), begin_ptr + pos + insertions_left - 1, *(--end));
+ --new_hole_size;
+ if(new_hole_size == 0){
+ //Hole was just filled, disable exception rollback and change vector size
+ past_hole_values_destroyer.release();
+ this->members_.m_size += element_count;
+ }
+ else{
+ //The hole was reduced by the new insertion by one
+ past_hole_values_destroyer.increment_size_backwards(size_type(1u));
+ }
+ }
+ else{
+ if(hole_size){
+ //Hole was just filled by shift_range, disable exception rollback and change vector size
+ past_hole_values_destroyer.release();
+ this->members_.m_size += element_count;
+ }
+ //Insert the new value in the already constructed range
+ begin_ptr[pos + insertions_left - 1] = *(--end);
+ }
+ --insertions_left;
+ hole_size = new_hole_size;
+ next_pos = pos;
+ }
+ }
+
+ size_type shift_range(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
+ {
+ BOOST_ASSERT(first_pos <= last_pos);
+ BOOST_ASSERT(last_pos <= limit_pos);
+ //
+ T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
+
+ size_type hole_size = 0;
+ if((last_pos + shift_count) < limit_pos){
+ //All inside
+ boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count);
+ }
+ else if((first_pos + shift_count) >= limit_pos){
+ //All outside
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count);
+ hole_size = last_pos + shift_count - limit_pos;
+ }
+ else{
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), begin_ptr + limit_pos - shift_count, begin_ptr + last_pos, begin_ptr + limit_pos);
+ boost::move_backward(begin_ptr + first_pos, begin_ptr + limit_pos - shift_count, begin_ptr + limit_pos + shift_count);
+ }
+ return hole_size;
+ }
+
+ private:
    void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
    {
       //n can't be 0, because there is nothing to do in that case


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