Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79555 - in branches/release/boost/container: . detail
From: igaztanaga_at_[hidden]
Date: 2012-07-16 04:29:54


Author: igaztanaga
Date: 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
New Revision: 79555
URL: http://svn.boost.org/trac/boost/changeset/79555

Log:
Merged from trunk
Added:
   branches/release/boost/container/scoped_allocator_fwd.hpp (contents, props changed)
Properties modified:
   branches/release/boost/container/ (props changed)
Text files modified:
   branches/release/boost/container/allocator_traits.hpp | 4
   branches/release/boost/container/detail/destroyers.hpp | 59 +++++++++++++++++
   branches/release/boost/container/detail/flat_tree.hpp | 24 ++----
   branches/release/boost/container/detail/tree.hpp | 4
   branches/release/boost/container/flat_map.hpp | 138 +++++++++++++++++++++++----------------
   branches/release/boost/container/scoped_allocator.hpp | 42 -----------
   branches/release/boost/container/string.hpp | 1
   7 files changed, 155 insertions(+), 117 deletions(-)

Modified: branches/release/boost/container/allocator_traits.hpp
==============================================================================
--- branches/release/boost/container/allocator_traits.hpp (original)
+++ branches/release/boost/container/allocator_traits.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -213,8 +213,8 @@
    static void deallocate(Alloc &a, pointer p, size_type n)
    { return a.deallocate(p, n); }
 
- //! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
- //! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
+ //! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
+ //! otherwise, invokes `a.allocate(n)`
    static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
    {
       const bool value = boost::container::container_detail::

Modified: branches/release/boost/container/detail/destroyers.hpp
==============================================================================
--- branches/release/boost/container/detail/destroyers.hpp (original)
+++ branches/release/boost/container/detail/destroyers.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -65,6 +65,44 @@
    {}
 };
 
+template <class Allocator>
+struct scoped_destroy_deallocator
+{
+ typedef boost::container::allocator_traits<Allocator> AllocTraits;
+ typedef typename AllocTraits::pointer pointer;
+ typedef typename AllocTraits::size_type size_type;
+ typedef container_detail::integral_constant<unsigned,
+ boost::container::container_detail::
+ version<Allocator>::value> alloc_version;
+ typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
+
+ scoped_destroy_deallocator(pointer p, Allocator& a)
+ : m_ptr(p), m_alloc(a) {}
+
+ ~scoped_destroy_deallocator()
+ {
+ if(m_ptr){
+ AllocTraits::destroy(m_alloc, container_detail::to_raw_pointer(m_ptr));
+ priv_deallocate(m_ptr, alloc_version());
+ }
+ }
+
+ void release()
+ { m_ptr = 0; }
+
+ private:
+
+ void priv_deallocate(const pointer &p, allocator_v1)
+ { AllocTraits::deallocate(m_alloc, p, 1); }
+
+ void priv_deallocate(const pointer &p, allocator_v2)
+ { m_alloc.deallocate_one(p); }
+
+ pointer m_ptr;
+ Allocator& m_alloc;
+};
+
 
 //!A deleter for scoped_ptr that destroys
 //!an object using a STL allocator.
@@ -150,6 +188,27 @@
    A &a_;
 };
 
+
+template<class A>
+class value_destructor
+{
+ typedef boost::container::allocator_traits<A> AllocTraits;
+ public:
+ typedef typename A::value_type value_type;
+ value_destructor(A &a, value_type &rv)
+ : rv_(rv), a_(a)
+ {}
+
+ ~value_destructor()
+ {
+ AllocTraits::destroy(a_, &rv_);
+ }
+
+ private:
+ value_type &rv_;
+ A &a_;
+};
+
 template <class Allocator>
 class allocator_destroyer
 {

Modified: branches/release/boost/container/detail/flat_tree.hpp
==============================================================================
--- branches/release/boost/container/detail/flat_tree.hpp (original)
+++ branches/release/boost/container/detail/flat_tree.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -395,14 +395,13 @@
       value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
       stored_allocator_type &a = this->get_stored_allocator();
       stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
- scoped_destructor<stored_allocator_type> d(a, &val);
+ value_destructor<stored_allocator_type> d(a, val);
       insert_commit_data data;
       std::pair<iterator,bool> ret =
          priv_insert_unique_prepare(val, data);
       if(ret.second){
          ret.first = priv_insert_commit(data, boost::move(val));
       }
- d.release();
       return ret;
    }
 
@@ -413,13 +412,12 @@
       value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
       stored_allocator_type &a = this->get_stored_allocator();
       stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
- scoped_destructor<stored_allocator_type> d(a, &val);
+ value_destructor<stored_allocator_type> d(a, val);
       insert_commit_data data;
       std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
       if(ret.second){
          ret.first = priv_insert_commit(data, boost::move(val));
       }
- d.release();
       return ret.first;
    }
 
@@ -430,10 +428,9 @@
       value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
       stored_allocator_type &a = this->get_stored_allocator();
       stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
- scoped_destructor<stored_allocator_type> d(a, &val);
+ value_destructor<stored_allocator_type> d(a, val);
       iterator i = this->upper_bound(KeyOfValue()(val));
       i = this->m_data.m_vect.insert(i, boost::move(val));
- d.release();
       return i;
    }
 
@@ -444,11 +441,10 @@
       value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
       stored_allocator_type &a = this->get_stored_allocator();
       stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
- scoped_destructor<stored_allocator_type> d(a, &val);
+ value_destructor<stored_allocator_type> d(a, val);
       insert_commit_data data;
       this->priv_insert_equal_prepare(hint, val, data);
       iterator i = priv_insert_commit(data, boost::move(val));
- d.release();
       return i;
    }
 
@@ -464,13 +460,12 @@
       stored_allocator_type &a = this->get_stored_allocator(); \
       stored_allocator_traits::construct(a, &val \
          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- scoped_destructor<stored_allocator_type> d(a, &val); \
+ value_destructor<stored_allocator_type> d(a, val); \
       insert_commit_data data; \
       std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
       if(ret.second){ \
          ret.first = priv_insert_commit(data, boost::move(val)); \
       } \
- d.release(); \
       return ret; \
    } \
                                                                                           \
@@ -483,13 +478,12 @@
       stored_allocator_type &a = this->get_stored_allocator(); \
       stored_allocator_traits::construct(a, &val \
          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- scoped_destructor<stored_allocator_type> d(a, &val); \
+ value_destructor<stored_allocator_type> d(a, val); \
       insert_commit_data data; \
       std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
       if(ret.second){ \
          ret.first = priv_insert_commit(data, boost::move(val)); \
       } \
- d.release(); \
       return ret.first; \
    } \
                                                                                           \
@@ -501,10 +495,9 @@
       stored_allocator_type &a = this->get_stored_allocator(); \
       stored_allocator_traits::construct(a, &val \
          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- scoped_destructor<stored_allocator_type> d(a, &val); \
+ value_destructor<stored_allocator_type> d(a, val); \
       iterator i = this->upper_bound(KeyOfValue()(val)); \
       i = this->m_data.m_vect.insert(i, boost::move(val)); \
- d.release(); \
       return i; \
    } \
                                                                                           \
@@ -517,11 +510,10 @@
       stored_allocator_type &a = this->get_stored_allocator(); \
       stored_allocator_traits::construct(a, &val \
          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- scoped_destructor<stored_allocator_type> d(a, &val); \
+ value_destructor<stored_allocator_type> d(a, val); \
       insert_commit_data data; \
       this->priv_insert_equal_prepare(hint, val, data); \
       iterator i = priv_insert_commit(data, boost::move(val)); \
- d.release(); \
       return i; \
    } \
 

Modified: branches/release/boost/container/detail/tree.hpp
==============================================================================
--- branches/release/boost/container/detail/tree.hpp (original)
+++ branches/release/boost/container/detail/tree.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -745,12 +745,14 @@
    {
       value_type &v = p->get_data();
       insert_commit_data data;
+ scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc());
       std::pair<iterator,bool> ret =
          this->insert_unique_check(KeyOfValue()(v), data);
       if(!ret.second){
- Destroyer(this->node_alloc())(p);
          return ret;
       }
+ //No throw insertion part, release rollback
+ destroy_deallocator.release();
       return std::pair<iterator,bool>
          ( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
          , true );

Modified: branches/release/boost/container/flat_map.hpp
==============================================================================
--- branches/release/boost/container/flat_map.hpp (original)
+++ branches/release/boost/container/flat_map.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -264,21 +264,21 @@
    //!
    //! <b>Complexity</b>: Constant.
    key_compare key_comp() const
- { return container_detail::force<key_compare>(m_flat_tree.key_comp()); }
+ { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
 
    //! <b>Effects</b>: Returns an object of value_compare constructed out
    //! of the comparison object.
    //!
    //! <b>Complexity</b>: Constant.
    value_compare value_comp() const
- { return value_compare(container_detail::force<key_compare>(m_flat_tree.key_comp())); }
+ { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
 
    //! <b>Effects</b>: Returns a copy of the Allocator that
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
    allocator_type get_allocator() const
- { return container_detail::force<allocator_type>(m_flat_tree.get_allocator()); }
+ { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
 
    const stored_allocator_type &get_stored_allocator() const
       { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
@@ -300,7 +300,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const
- { return container_detail::force<const_iterator>(m_flat_tree.begin()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
    //!
@@ -316,7 +316,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return container_detail::force<const_iterator>(m_flat_tree.end()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed container.
@@ -325,7 +325,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reverse_iterator rbegin()
- { return container_detail::force<reverse_iterator>(m_flat_tree.rbegin()); }
+ { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
    //! of the reversed container.
@@ -334,7 +334,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed container.
@@ -343,7 +343,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reverse_iterator rend()
- { return container_detail::force<reverse_iterator>(m_flat_tree.rend()); }
+ { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
    //! of the reversed container.
@@ -352,7 +352,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
    //!
@@ -360,7 +360,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cbegin() const
- { return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
    //!
@@ -368,7 +368,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cend() const
- { return container_detail::force<const_iterator>(m_flat_tree.cend()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
    //! of the reversed container.
@@ -377,7 +377,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator crbegin() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
    //! of the reversed container.
@@ -386,7 +386,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator crend() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
 
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
@@ -477,7 +477,7 @@
    //!
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    std::pair<iterator,bool> insert(const value_type& x)
- { return container_detail::force<std::pair<iterator,bool> >(
+ { return container_detail::force_copy<std::pair<iterator,bool> >(
          m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
 
    //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
@@ -492,7 +492,7 @@
    //!
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
- { return container_detail::force<std::pair<iterator,bool> >(
+ { return container_detail::force_copy<std::pair<iterator,bool> >(
       m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); }
 
    //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
@@ -508,7 +508,7 @@
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
    {
- return container_detail::force<std::pair<iterator,bool> >
+ return container_detail::force_copy<std::pair<iterator,bool> >
       (m_flat_tree.insert_unique(boost::move(x)));
    }
 
@@ -524,8 +524,11 @@
    //!
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    iterator insert(const_iterator position, const value_type& x)
- { return container_detail::force_copy<iterator>(
- m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), container_detail::force<impl_value_type>(x))); }
+ {
+ return container_detail::force_copy<iterator>(
+ m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(position)
+ , container_detail::force<impl_value_type>(x)));
+ }
 
    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -539,7 +542,7 @@
    iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
    {
       return container_detail::force_copy<iterator>
- (m_flat_tree.insert_unique( container_detail::force<impl_const_iterator>(position)
+ (m_flat_tree.insert_unique( container_detail::force_copy<impl_const_iterator>(position)
                                    , boost::move(container_detail::force<impl_value_type>(x))));
    }
 
@@ -555,7 +558,7 @@
    iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
    {
       return container_detail::force_copy<iterator>(
- m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(x)));
+ m_flat_tree.insert_unique(container_detail::force_copy<impl_const_iterator>(position), boost::move(x)));
    }
 
    //! <b>Requires</b>: first, last are not iterators into *this.
@@ -620,8 +623,11 @@
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    template <class... Args>
    iterator emplace_hint(const_iterator hint, Args&&... args)
- { return container_detail::force_copy<iterator>
- (m_flat_tree.emplace_hint_unique(container_detail::force<impl_const_iterator>(hint), boost::forward<Args>(args)...)); }
+ {
+ return container_detail::force_copy<iterator>
+ (m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
+ , boost::forward<Args>(args)...));
+ }
 
    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
 
@@ -635,7 +641,7 @@
    iterator emplace_hint(const_iterator hint \
                          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
    { return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \
- (container_detail::force<impl_const_iterator>(hint) \
+ (container_detail::force_copy<impl_const_iterator>(hint) \
                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
    //!
    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -654,7 +660,10 @@
    //! <b>Note</b>: Invalidates elements with keys
    //! not less than the erased element.
    iterator erase(const_iterator position)
- { return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(position))); }
+ {
+ return container_detail::force_copy<iterator>
+ (m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(position)));
+ }
 
    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
    //!
@@ -674,8 +683,11 @@
    //! <b>Complexity</b>: Logarithmic search time plus erasure time
    //! linear to the elements with bigger keys.
    iterator erase(const_iterator first, const_iterator last)
- { return container_detail::force_copy<iterator>
- (m_flat_tree.erase(container_detail::force<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); }
+ {
+ return container_detail::force_copy<iterator>(
+ m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
+ , container_detail::force_copy<impl_const_iterator>(last)));
+ }
 
    //! <b>Effects</b>: erase(a.begin(),a.end()).
    //!
@@ -706,7 +718,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic.s
    const_iterator find(const key_type& x) const
- { return container_detail::force<const_iterator>(m_flat_tree.find(x)); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
 
    //! <b>Returns</b>: The number of elements with key equivalent to x.
    //!
@@ -726,7 +738,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    const_iterator lower_bound(const key_type& x) const
- { return container_detail::force<const_iterator>(m_flat_tree.lower_bound(x)); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
 
    //! <b>Returns</b>: An iterator pointing to the first element with key not less
    //! than x, or end() if such an element is not found.
@@ -740,7 +752,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    const_iterator upper_bound(const key_type& x) const
- { return container_detail::force<const_iterator>(m_flat_tree.upper_bound(x)); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
 
    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
    //!
@@ -1050,21 +1062,21 @@
    //!
    //! <b>Complexity</b>: Constant.
    key_compare key_comp() const
- { return container_detail::force<key_compare>(m_flat_tree.key_comp()); }
+ { return container_detail::force_copy<key_compare>(m_flat_tree.key_comp()); }
 
    //! <b>Effects</b>: Returns an object of value_compare constructed out
    //! of the comparison object.
    //!
    //! <b>Complexity</b>: Constant.
    value_compare value_comp() const
- { return value_compare(container_detail::force<key_compare>(m_flat_tree.key_comp())); }
+ { return value_compare(container_detail::force_copy<key_compare>(m_flat_tree.key_comp())); }
 
    //! <b>Effects</b>: Returns a copy of the Allocator that
    //! was passed to the object's constructor.
    //!
    //! <b>Complexity</b>: Constant.
    allocator_type get_allocator() const
- { return container_detail::force<allocator_type>(m_flat_tree.get_allocator()); }
+ { return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
 
    const stored_allocator_type &get_stored_allocator() const
       { return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
@@ -1086,7 +1098,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const
- { return container_detail::force<const_iterator>(m_flat_tree.begin()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
    //!
@@ -1102,7 +1114,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return container_detail::force<const_iterator>(m_flat_tree.end()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed container.
@@ -1111,7 +1123,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reverse_iterator rbegin()
- { return container_detail::force<reverse_iterator>(m_flat_tree.rbegin()); }
+ { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
    //! of the reversed container.
@@ -1120,7 +1132,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed container.
@@ -1129,7 +1141,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reverse_iterator rend()
- { return container_detail::force<reverse_iterator>(m_flat_tree.rend()); }
+ { return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
    //! of the reversed container.
@@ -1138,7 +1150,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
    //!
@@ -1146,7 +1158,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cbegin() const
- { return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
    //!
@@ -1154,7 +1166,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cend() const
- { return container_detail::force<const_iterator>(m_flat_tree.cend()); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
    //! of the reversed container.
@@ -1163,7 +1175,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator crbegin() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
    //! of the reversed container.
@@ -1172,7 +1184,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator crend() const
- { return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); }
+ { return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
 
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
@@ -1214,7 +1226,10 @@
    //!
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    iterator insert(const value_type& x)
- { return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x))); }
+ {
+ return container_detail::force_copy<iterator>(
+ m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x)));
+ }
 
    //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
    //! the iterator pointing to the newly inserted element.
@@ -1248,8 +1263,11 @@
    //!
    //! <b>Note</b>: If an element is inserted it might invalidate elements.
    iterator insert(const_iterator position, const value_type& x)
- { return container_detail::force_copy<iterator>
- (m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position), container_detail::force<impl_value_type>(x))); }
+ {
+ return container_detail::force_copy<iterator>
+ (m_flat_tree.insert_equal( container_detail::force_copy<impl_const_iterator>(position)
+ , container_detail::force<impl_value_type>(x)));
+ }
 
    //! <b>Effects</b>: Inserts a value move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -1265,7 +1283,7 @@
    iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
    {
       return container_detail::force_copy<iterator>
- (m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position)
+ (m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(position)
                                   , boost::move(x)));
    }
 
@@ -1283,7 +1301,7 @@
    iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
    {
       return container_detail::force_copy<iterator>(
- m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position), boost::move(x)));
+ m_flat_tree.insert_equal(container_detail::force_copy<impl_const_iterator>(position), boost::move(x)));
    }
 
    //! <b>Requires</b>: first, last are not iterators into *this.
@@ -1344,7 +1362,7 @@
    iterator emplace_hint(const_iterator hint, Args&&... args)
    {
       return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
- (container_detail::force<impl_const_iterator>(hint), boost::forward<Args>(args)...));
+ (container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
    }
 
    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -1359,7 +1377,7 @@
    iterator emplace_hint(const_iterator hint \
                          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
    { return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal \
- (container_detail::force<impl_const_iterator>(hint) \
+ (container_detail::force_copy<impl_const_iterator>(hint) \
                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
    //!
    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -1378,7 +1396,10 @@
    //! <b>Note</b>: Invalidates elements with keys
    //! not less than the erased element.
    iterator erase(const_iterator position)
- { return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(position))); }
+ {
+ return container_detail::force_copy<iterator>(
+ m_flat_tree.erase(container_detail::force_copy<impl_const_iterator>(position)));
+ }
 
    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
    //!
@@ -1398,8 +1419,11 @@
    //! <b>Complexity</b>: Logarithmic search time plus erasure time
    //! linear to the elements with bigger keys.
    iterator erase(const_iterator first, const_iterator last)
- { return container_detail::force_copy<iterator>
- (m_flat_tree.erase(container_detail::force<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); }
+ {
+ return container_detail::force_copy<iterator>
+ (m_flat_tree.erase( container_detail::force_copy<impl_const_iterator>(first)
+ , container_detail::force_copy<impl_const_iterator>(last)));
+ }
 
    //! <b>Effects</b>: erase(a.begin(),a.end()).
    //!
@@ -1430,7 +1454,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic.
    const_iterator find(const key_type& x) const
- { return container_detail::force<const_iterator>(m_flat_tree.find(x)); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.find(x)); }
 
    //! <b>Returns</b>: The number of elements with key equivalent to x.
    //!
@@ -1450,7 +1474,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    const_iterator lower_bound(const key_type& x) const
- { return container_detail::force<const_iterator>(m_flat_tree.lower_bound(x)); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
 
    //! <b>Returns</b>: An iterator pointing to the first element with key not less
    //! than x, or end() if such an element is not found.
@@ -1464,20 +1488,20 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    const_iterator upper_bound(const key_type& x) const
- { return container_detail::force<const_iterator>(m_flat_tree.upper_bound(x)); }
+ { return container_detail::force_copy<const_iterator>(m_flat_tree.upper_bound(x)); }
 
    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
    //!
    //! <b>Complexity</b>: Logarithmic
    std::pair<iterator,iterator> equal_range(const key_type& x)
- { return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+ { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
 
    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
    //!
    //! <b>Complexity</b>: Logarithmic
    std::pair<const_iterator,const_iterator>
       equal_range(const key_type& x) const
- { return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+ { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
 
    //! <b>Effects</b>: Number of elements for which memory has been allocated.
    //! capacity() is always greater than or equal to size().

Modified: branches/release/boost/container/scoped_allocator.hpp
==============================================================================
--- branches/release/boost/container/scoped_allocator.hpp (original)
+++ branches/release/boost/container/scoped_allocator.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -23,6 +23,7 @@
 
 #include <boost/container/detail/config_begin.hpp>
 #include <boost/container/detail/workaround.hpp>
+#include <boost/container/scoped_allocator_fwd.hpp>
 #include <boost/type_traits/integral_constant.hpp>
 #include <boost/container/allocator_traits.hpp>
 #include <boost/container/detail/type_traits.hpp>
@@ -31,50 +32,9 @@
 #include <boost/container/detail/pair.hpp>
 #include <boost/move/move.hpp>
 
-#if defined(BOOST_NO_VARIADIC_TEMPLATES)
-#include <boost/container/detail/preprocessor.hpp>
-#endif
 
 namespace boost { namespace container {
 
-#if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
-
-#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
-
-template <typename OuterAlloc, typename ...InnerAllocs>
-class scoped_allocator_adaptor;
-
-#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
-
-template <typename ...InnerAllocs>
-class scoped_allocator_adaptor;
-
-template <typename OuterAlloc, typename ...InnerAllocs>
-class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
-
-#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
-
-
-#else // #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
-template <typename OuterAlloc
-BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
->
-class scoped_allocator_adaptor;
-
-#endif
-
-//! The allocator_arg_t struct is an empty structure type used as a unique type to
-//! disambiguate constructor and function overloading. Specifically, several types
-//! have constructors with allocator_arg_t as the first argument, immediately followed
-//! by an argument of a type that satisfies the Allocator requirements
-struct allocator_arg_t{};
-
-//! A instance of type allocator_arg_t
-//!
-static const allocator_arg_t allocator_arg = allocator_arg_t();
-
 //! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed
 //! with an allocator as its last constructor argument. Ideally, all constructors of T (including the
 //! copy and move constructors) should have a variant that accepts a final argument of

Added: branches/release/boost/container/scoped_allocator_fwd.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/scoped_allocator_fwd.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -0,0 +1,83 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
+#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
+
+#if (defined MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#if defined(BOOST_NO_VARIADIC_TEMPLATES)
+#include <boost/container/detail/preprocessor.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#endif
+
+namespace boost { namespace container {
+
+///@cond
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+ #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+ template <typename OuterAlloc, typename ...InnerAllocs>
+ class scoped_allocator_adaptor;
+
+ #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+ template <typename ...InnerAllocs>
+ class scoped_allocator_adaptor;
+
+ template <typename OuterAlloc, typename ...InnerAllocs>
+ class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
+
+ #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+
+
+#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template <typename OuterAlloc
+BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
+ , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
+>
+class scoped_allocator_adaptor;
+
+#endif
+
+///@endcond
+
+//! The allocator_arg_t struct is an empty structure type used as a unique type to
+//! disambiguate constructor and function overloading. Specifically, several types
+//! have constructors with allocator_arg_t as the first argument, immediately followed
+//! by an argument of a type that satisfies the Allocator requirements
+struct allocator_arg_t{};
+
+//! A instance of type allocator_arg_t
+//!
+static const allocator_arg_t allocator_arg = allocator_arg_t();
+
+template <class T>
+struct constructible_with_allocator_suffix;
+
+template <class T>
+struct constructible_with_allocator_prefix;
+
+template <typename T, typename Alloc>
+struct uses_allocator;
+
+}} // namespace boost { namespace container {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP

Modified: branches/release/boost/container/string.hpp
==============================================================================
--- branches/release/boost/container/string.hpp (original)
+++ branches/release/boost/container/string.hpp 2012-07-16 04:29:51 EDT (Mon, 16 Jul 2012)
@@ -47,6 +47,7 @@
 #include <boost/container/detail/mpl.hpp>
 #include <boost/move/move.hpp>
 #include <boost/static_assert.hpp>
+#include <boost/functional/hash.hpp>
 
 #include <functional>
 #include <string>


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