$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78148 - in branches/release: boost/container boost/container/detail boost/intrusive/detail libs/container/test libs/intrusive/test
From: igaztanaga_at_[hidden]
Date: 2012-04-22 17:23:52
Author: igaztanaga
Date: 2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
New Revision: 78148
URL: http://svn.boost.org/trac/boost/changeset/78148
Log:
Fixes for scoped_allocator
Text files modified: 
   branches/release/boost/container/detail/flat_tree.hpp                         |    85 ++++++--                                
   branches/release/boost/container/flat_map.hpp                                 |    84 ++++++--                                
   branches/release/boost/container/list.hpp                                     |     4                                         
   branches/release/boost/container/map.hpp                                      |    68 +++++++                                 
   branches/release/boost/container/scoped_allocator.hpp                         |    71 +++++-                                  
   branches/release/boost/container/slist.hpp                                    |     4                                         
   branches/release/boost/container/stable_vector.hpp                            |     4                                         
   branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp |     4                                         
   branches/release/libs/container/test/scoped_allocator_usage_test.cpp          |   384 +++++++++++++++++++++++++++++++++++---- 
   branches/release/libs/intrusive/test/has_member_function_callable_with.cpp    |     2                                         
   10 files changed, 604 insertions(+), 106 deletions(-)
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-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -32,6 +32,8 @@
 #include <boost/container/vector.hpp>
 #include <boost/container/detail/value_init.hpp>
 #include <boost/container/detail/destroyers.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/aligned_storage.hpp>
 
 namespace boost {
 
@@ -173,6 +175,10 @@
    //!Standard extension
    typedef allocator_type                             stored_allocator_type;
 
+   private:
+   typedef allocator_traits<stored_allocator_type> stored_allocator_traits;
+
+   public:
    flat_tree()
       : m_data()
    { }
@@ -377,44 +383,65 @@
    template <class... Args>
    std::pair<iterator, bool> emplace_unique(Args&&... args)
    {
-      value_type && val = value_type(boost::forward<Args>(args)...);
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+      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)... );
+      scoped_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;
    }
 
    template <class... Args>
    iterator emplace_hint_unique(const_iterator hint, Args&&... args)
    {
-      value_type && val = value_type(boost::forward<Args>(args)...);
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+      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)... );
+      scoped_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;
    }
 
    template <class... Args>
    iterator emplace_equal(Args&&... args)
    {
-      value_type &&val = value_type(boost::forward<Args>(args)...);
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+      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)... );
+      scoped_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;
    }
 
    template <class... Args>
    iterator emplace_hint_equal(const_iterator hint, Args&&... args)
    {
-      value_type &&val = value_type(boost::forward<Args>(args)...);
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+      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)... );
+      scoped_destructor<stored_allocator_type> d(a, &val);
       insert_commit_data data;
       this->priv_insert_equal_prepare(hint, val, data);
-      return priv_insert_commit(data, boost::move(val));
+      iterator i = priv_insert_commit(data, boost::move(val));
+      d.release();
+      return i;
    }
 
    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -424,15 +451,18 @@
    std::pair<iterator, bool>                                                              \
       emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                  \
    {                                                                                      \
-      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
-         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
-            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
-      value_type &val = vval;                                                             \
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;             \
+      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_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                \
+      scoped_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;                                                                         \
    }                                                                                      \
                                                                                           \
@@ -440,27 +470,33 @@
    iterator emplace_hint_unique(const_iterator hint                                       \
                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))      \
    {                                                                                      \
-      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
-         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
-            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
-      value_type &val = vval;                                                             \
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;             \
+      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_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                \
+      scoped_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;                                                                   \
    }                                                                                      \
                                                                                           \
    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
    iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))             \
    {                                                                                      \
-      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
-         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
-            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
-      value_type &val = vval;                                                             \
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;             \
+      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_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                \
+      scoped_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;                                                                           \
    }                                                                                      \
                                                                                           \
@@ -468,14 +504,19 @@
    iterator emplace_hint_equal(const_iterator hint                                        \
                       BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))        \
    {                                                                                      \
-      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
-         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
-            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
-      value_type &val = vval;                                                             \
+      aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;             \
+      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_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                \
+      scoped_destructor<stored_allocator_type> d(a, &val);                                \
       insert_commit_data data;                                                            \
       this->priv_insert_equal_prepare(hint, val, data);                                   \
-      return priv_insert_commit(data, boost::move(val));                                  \
+      iterator i = priv_insert_commit(data, boost::move(val));                            \
+      d.release();                                                                        \
+      return i;                                                                           \
    }                                                                                      \
+
    //!
    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
    #include BOOST_PP_LOCAL_ITERATE()
Modified: branches/release/boost/container/flat_map.hpp
==============================================================================
--- branches/release/boost/container/flat_map.hpp	(original)
+++ branches/release/boost/container/flat_map.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -300,14 +300,6 @@
    const_iterator begin() const 
       { return container_detail::force<const_iterator>(m_flat_tree.begin()); }
 
-   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   //! 
-   //! <b>Complexity</b>: Constant.
-   const_iterator cbegin() const 
-      { return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
-
    //! <b>Effects</b>: Returns an iterator to the end of the container.
    //! 
    //! <b>Throws</b>: Nothing.
@@ -324,14 +316,6 @@
    const_iterator end() const 
       { return container_detail::force<const_iterator>(m_flat_tree.end()); }
 
-   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
-   //! 
-   //! <b>Throws</b>: Nothing.
-   //! 
-   //! <b>Complexity</b>: Constant.
-   const_iterator cend() const 
-      { return container_detail::force<const_iterator>(m_flat_tree.cend()); }
-
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
    //! of the reversed container. 
    //! 
@@ -350,15 +334,6 @@
    const_reverse_iterator rbegin() const 
       { return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
 
-   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
-   //! of the reversed container. 
-   //! 
-   //! <b>Throws</b>: Nothing.
-   //! 
-   //! <b>Complexity</b>: Constant.
-   const_reverse_iterator crbegin() const 
-      { return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
-
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed container. 
    //! 
@@ -377,6 +352,31 @@
    const_reverse_iterator rend() const 
       { return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
 
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const 
+      { return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const 
+      { return container_detail::force<const_iterator>(m_flat_tree.cend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const 
+      { return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
    //! of the reversed container. 
    //! 
@@ -1119,6 +1119,40 @@
    const_reverse_iterator rend() const 
       { return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
 
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const 
+      { return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const 
+      { return container_detail::force<const_iterator>(m_flat_tree.cend()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const 
+      { return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const 
+      { return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); }
+
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //! 
    //! <b>Throws</b>: Nothing.
Modified: branches/release/boost/container/list.hpp
==============================================================================
--- branches/release/boost/container/list.hpp	(original)
+++ branches/release/boost/container/list.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -65,6 +65,10 @@
 struct list_node
    :  public list_hook<VoidPointer>::type
 {
+   private:
+   list_node();
+
+   public:
    typedef typename list_hook<VoidPointer>::type hook_type;
    T m_data;
 };
Modified: branches/release/boost/container/map.hpp
==============================================================================
--- branches/release/boost/container/map.hpp	(original)
+++ branches/release/boost/container/map.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -276,6 +276,14 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const 
+   { return this->cbegin(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const 
    { return m_tree.begin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -292,6 +300,14 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator end() const 
+   { return this->cend(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const 
    { return m_tree.end(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
@@ -310,6 +326,15 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin() const 
+   { return this->crbegin(); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const 
    { return m_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -328,6 +353,15 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const 
+   { return this->crend(); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const 
    { return m_tree.rend(); }
 
    //! <b>Effects</b>: Returns true if the container contains no elements.
@@ -984,6 +1018,14 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const 
+   { return this->cbegin(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cbegin() const 
    { return m_tree.begin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -1000,6 +1042,14 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_iterator end() const 
+   { return this->cend(); }
+
+   //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_iterator cend() const 
    { return m_tree.end(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
@@ -1018,6 +1068,15 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin() const 
+   { return this->crbegin(); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crbegin() const 
    { return m_tree.rbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1036,6 +1095,15 @@
    //! 
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const 
+   { return this->crend(); }
+
+   //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! <b>Throws</b>: Nothing.
+   //! 
+   //! <b>Complexity</b>: Constant.
+   const_reverse_iterator crend() const 
    { return m_tree.rend(); }
 
    //! <b>Effects</b>: Returns true if the container contains no elements.
Modified: branches/release/boost/container/scoped_allocator.hpp
==============================================================================
--- branches/release/boost/container/scoped_allocator.hpp	(original)
+++ branches/release/boost/container/scoped_allocator.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -674,6 +674,20 @@
       , inner(other.inner_allocator())
       {}
 
+   protected:
+   struct internal_type_t{};
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base
+      ( internal_type_t
+      , BOOST_FWD_REF(OuterA2) outerAlloc
+      , const inner_allocator_type &inner)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      , m_inner(inner)
+   {}
+
+   public:
+
    scoped_allocator_adaptor_base &operator=
       (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
    {
@@ -772,17 +786,17 @@
    scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc                              \
       BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _))                  \
       : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))                             \
-      , inner(BOOST_PP_ENUM_PARAMS(n, q))                                                       \
+      , m_inner(BOOST_PP_ENUM_PARAMS(n, q))                                                     \
       {}                                                                                        \
                                                                                                 \
    scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)                    \
       : outer_allocator_type(other.outer_allocator())                                           \
-      , inner(other.inner_allocator())                                                          \
+      , m_inner(other.inner_allocator())                                                        \
       {}                                                                                        \
                                                                                                 \
    scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)             \
       : outer_allocator_type(::boost::move(other.outer_allocator()))                            \
-      , inner(::boost::move(other.inner_allocator()))                                           \
+      , m_inner(::boost::move(other.inner_allocator()))                                         \
       {}                                                                                        \
                                                                                                 \
    template <class OuterA2>                                                                     \
@@ -793,7 +807,7 @@
             , BOOST_CONTAINER_PP_IDENTITY, nat)                                                 \
          >& other)                                                                              \
       : outer_allocator_type(other.outer_allocator())                                           \
-      , inner(other.inner_allocator())                                                          \
+      , m_inner(other.inner_allocator())                                                        \
       {}                                                                                        \
                                                                                                 \
    template <class OuterA2>                                                                     \
@@ -805,29 +819,42 @@
             , BOOST_CONTAINER_PP_IDENTITY, nat)                                                 \
          > BOOST_RV_REF_END other)                                                              \
       : outer_allocator_type(other.outer_allocator())                                           \
-      , inner(other.inner_allocator())                                                          \
+      , m_inner(other.inner_allocator())                                                        \
       {}                                                                                        \
                                                                                                 \
+   protected:                                                                                   \
+   struct internal_type_t{};                                                                    \
+                                                                                                \
+   template <class OuterA2>                                                                     \
+   scoped_allocator_adaptor_base                                                                \
+      ( internal_type_t                                                                         \
+      , BOOST_FWD_REF(OuterA2) outerAlloc                                                       \
+      , const inner_allocator_type &inner)                                                      \
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))                             \
+      , m_inner(inner)                                                                          \
+   {}                                                                                           \
+                                                                                                \
+   public:                                                                                      \
    scoped_allocator_adaptor_base &operator=                                                     \
       (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)                              \
    {                                                                                            \
       outer_allocator_type::operator=(other.outer_allocator());                                 \
-      inner = other.inner_allocator();                                                          \
+      m_inner = other.inner_allocator();                                                        \
       return *this;                                                                             \
    }                                                                                            \
                                                                                                 \
    scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)  \
    {                                                                                            \
       outer_allocator_type::operator=(boost::move(other.outer_allocator()));                    \
-      inner = ::boost::move(other.inner_allocator());                                           \
+      m_inner = ::boost::move(other.inner_allocator());                                         \
       return *this;                                                                             \
    }                                                                                            \
                                                                                                 \
    inner_allocator_type&       inner_allocator()                                                \
-      { return inner; }                                                                         \
+      { return m_inner; }                                                                       \
                                                                                                 \
    inner_allocator_type const& inner_allocator() const                                          \
-      { return inner; }                                                                         \
+      { return m_inner; }                                                                       \
                                                                                                 \
    outer_allocator_type      & outer_allocator()                                                \
       { return static_cast<outer_allocator_type&>(*this); }                                     \
@@ -836,7 +863,7 @@
       { return static_cast<const outer_allocator_type&>(*this); }                               \
                                                                                                 \
    private:                                                                                     \
-   inner_allocator_type inner;                                                                  \
+   inner_allocator_type m_inner;                                                                \
 };                                                                                              \
 //!
 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -920,6 +947,15 @@
       : outer_allocator_type(other.outer_allocator())
       {}
 
+   protected:
+   struct internal_type_t{};
+
+   template <class OuterA2>
+   scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
+      : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
+      {}
+  
+   public:
    scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
    {
       outer_allocator_type::operator=(other.outer_allocator());
@@ -1221,8 +1257,9 @@
    scoped_allocator_adaptor select_on_container_copy_construction() const
    {
       return scoped_allocator_adaptor
-         (outer_traits_type::select_on_container_copy_construction(this->outer_allocator()),
-          outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
+         (internal_type_t()
+         ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
+         ,outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
          );
    }
    /// @cond
@@ -1309,11 +1346,11 @@
 
    template <class T1, class T2, class U, class V>
    void construct(std::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
-   {  this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<U>(y));   }
+   {  this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<V>(y));   }
 
    template <class T1, class T2, class U, class V>
    void construct(container_detail::pair<T1, T2>* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
-   {  this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<U>(y));   }
+   {  this->construct_pair(p, ::boost::forward<U>(x), ::boost::forward<V>(y));   }
    
    template <class T1, class T2, class U, class V>
    void construct(std::pair<T1, T2>* p, const std::pair<U, V>& x)
@@ -1391,6 +1428,12 @@
    //template <class T1, class T2, class... Args1, class... Args2>
    //void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
 
+   private:
+   template <class OuterA2>
+   scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
+      : base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
+   {}
+
    /// @endcond
 };
 
Modified: branches/release/boost/container/slist.hpp
==============================================================================
--- branches/release/boost/container/slist.hpp	(original)
+++ branches/release/boost/container/slist.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -65,6 +65,10 @@
 struct slist_node
    :  public slist_hook<VoidPointer>::type
 {
+   private:
+   slist_node();
+
+   public:
    typedef typename slist_hook<VoidPointer>::type hook_type;
    T m_data;
 };
Modified: branches/release/boost/container/stable_vector.hpp
==============================================================================
--- branches/release/boost/container/stable_vector.hpp	(original)
+++ branches/release/boost/container/stable_vector.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -119,6 +119,10 @@
 struct node_type
    : public node_type_base<VoidPointer>
 {
+   private:
+   node_type();
+
+   public:
    T value;
 };
 
Modified: branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp	(original)
+++ branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -164,7 +164,7 @@
             };
             #endif   //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
 
-         #else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
+         #else //#if !defined(_MSC_VER) || (_MSC_VER < 1600)
             template<typename Fun>
             struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
                <Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
@@ -180,7 +180,7 @@
                static const bool value = sizeof(Test<Fun>(0))
                                     == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
             };
-         #endif   //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
+         #endif   //#if !defined(_MSC_VER) || (_MSC_VER < 1600)
 
       #else   //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
 
Modified: branches/release/libs/container/test/scoped_allocator_usage_test.cpp
==============================================================================
--- branches/release/libs/container/test/scoped_allocator_usage_test.cpp	(original)
+++ branches/release/libs/container/test/scoped_allocator_usage_test.cpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -1,8 +1,18 @@
+#include <boost/container/detail/config_begin.hpp>
 #include <memory>
-#include <string>
 
 #include <boost/move/move.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/container/deque.hpp>
+#include <boost/container/list.hpp>
+#include <boost/container/slist.hpp>
+#include <boost/container/stable_vector.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
 #include <boost/container/map.hpp>
+#include <boost/container/set.hpp>
+#include <boost/container/detail/mpl.hpp>
+
 #include <boost/container/scoped_allocator.hpp>
 
 template <typename Ty>
@@ -14,82 +24,372 @@
         typedef typename std::allocator<Ty>::size_type size_type;
 
         SimpleAllocator(int value)
-		: _value(value)
+		: m_state(value)
         {}
 
         template <typename T>
         SimpleAllocator(const SimpleAllocator<T> &other)
-		: _value(other._value)
+		: m_state(other.m_state)
         {}
 
         pointer allocate(size_type n)
         {
-		return _allocator.allocate(n);
+		return m_allocator.allocate(n);
         }
+
         void deallocate(pointer p, size_type n)
         {
-		_allocator.deallocate(p, n);
+		m_allocator.deallocate(p, n);
         }
-private:
-	int _value;
-	std::allocator<Ty> _allocator;
+
+   int get_value() const
+   {  return m_state;   }
+
+   private:
+	int m_state;
+	std::allocator<Ty> m_allocator;
 
         template <typename T> friend class SimpleAllocator;
 };
 
-template <typename Ty>
-class ScopedAllocator : public boost::container::scoped_allocator_adaptor<SimpleAllocator<Ty> >
+class alloc_int
 {
-private:
-	typedef boost::container::scoped_allocator_adaptor<SimpleAllocator<Ty> > Base;
+   private: // Not copyable
 
-public:
-	ScopedAllocator(int value)
-		: Base(SimpleAllocator<Ty>(value))
-	{}
-};
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(alloc_int)
 
-class Resource
-{
-private: // Not copyable
-	Resource(const Resource &);
-	Resource &operator=(const Resource &);
-public:
+   public:
         typedef SimpleAllocator<int> allocator_type;
 
-	Resource(BOOST_RV_REF(Resource)other)
-		: _value(other._value), _allocator(boost::move(other._allocator))
+	alloc_int(BOOST_RV_REF(alloc_int)other)
+		: m_value(other.m_value), m_allocator(boost::move(other.m_allocator))
         {
-		other._value = -1;
+		other.m_value = -1;
         }
 
-	Resource(BOOST_RV_REF(Resource)other, const allocator_type &allocator)
-		: _value(other._value), _allocator(allocator)
+	alloc_int(BOOST_RV_REF(alloc_int)other, const allocator_type &allocator)
+		: m_value(other.m_value), m_allocator(allocator)
         {
-		other._value = -1;
+		other.m_value = -1;
         }
 
-	Resource(int value, const allocator_type &allocator)
-		: _value(value), _allocator(allocator)
+	alloc_int(int value, const allocator_type &allocator)
+		: m_value(value), m_allocator(allocator)
         {}
-private:
-	int _value;
-	allocator_type _allocator;
+
+	alloc_int & operator=(BOOST_RV_REF(alloc_int)other)
+	{
+		other.m_value = other.m_value;
+      return *this;
+	}
+
+   int get_allocator_state() const
+   {  return m_allocator.get_value();  }
+
+   int get_value() const
+   {  return m_value;   }
+
+   friend bool operator < (const alloc_int &l, const alloc_int &r)
+   {  return l.m_value < r.m_value;  }
+
+   friend bool operator == (const alloc_int &l, const alloc_int &r)
+   {  return l.m_value == r.m_value;  }
+
+   private:
+	int m_value;
+	allocator_type m_allocator;
 };
 
-typedef std::pair<const std::string, Resource> MapNode;
+using namespace ::boost::container;
 
-typedef boost::container::scoped_allocator_adaptor<SimpleAllocator<MapNode> > MapAllocator;
+//general allocator
+typedef scoped_allocator_adaptor<SimpleAllocator<alloc_int> > AllocIntAllocator;
 
-typedef boost::container::map<std::string, Resource, std::less<std::string>, MapAllocator> Map;
+//[multi]map/set
+typedef std::pair<const alloc_int, alloc_int> MapNode;
+typedef scoped_allocator_adaptor<SimpleAllocator<MapNode> > MapAllocator;
+typedef map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> Map;
+typedef set<alloc_int, std::less<alloc_int>, AllocIntAllocator> Set;
+typedef multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> MultiMap;
+typedef multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> MultiSet;
+
+//[multi]flat_map/set
+typedef std::pair<alloc_int, alloc_int> FlatMapNode;
+typedef scoped_allocator_adaptor<SimpleAllocator<FlatMapNode> > FlatMapAllocator;
+typedef flat_map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMap;
+typedef flat_set<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatSet;
+typedef flat_multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMultiMap;
+typedef flat_multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatMultiSet;
+
+//vector, deque, list, slist, stable_vector.
+typedef vector<alloc_int, AllocIntAllocator>          Vector;
+typedef deque<alloc_int, AllocIntAllocator>           Deque;
+typedef list<alloc_int, AllocIntAllocator>            List;
+typedef slist<alloc_int, AllocIntAllocator>           Slist;
+typedef stable_vector<alloc_int, AllocIntAllocator>   StableVector;
+
+/////////
+//is_unique_assoc
+/////////
 
-int main()
+template<class T>
+struct is_unique_assoc
 {
-	Map map1(std::less<std::string>(), SimpleAllocator<MapNode>(5));
+   static const bool value = false;
+};
+
+template<class K, class V, class C, class A>
+struct is_unique_assoc< map<K, V, C, A> >
+{
+   static const bool value = true;
+};
 
-	map1.emplace("foo", 42);
-	map1.emplace("bar", 11);
+template<class K, class V, class C, class A>
+struct is_unique_assoc< flat_map<K, V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_unique_assoc< set<V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_unique_assoc< flat_set<V, C, A> >
+{
+   static const bool value = true;
+};
+
+
+/////////
+//is_map
+/////////
+
+template<class T>
+struct is_map
+{
+   static const bool value = false;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< map<K, V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< flat_map<K, V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< multimap<K, V, C, A> >
+{
+   static const bool value = true;
+};
 
-	//Map map2 = map1;
+template<class K, class V, class C, class A>
+struct is_map< flat_multimap<K, V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class T>
+struct is_set
+{
+   static const bool value = false;
+};
+
+template<class V, class C, class A>
+struct is_set< set<V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_set< flat_set<V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_set< multiset<V, C, A> >
+{
+   static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_set< flat_multiset<V, C, A> >
+{
+   static const bool value = true;
+};
+
+/////////
+//container_wrapper
+/////////
+
+template< class Container
+        , bool Assoc = is_set<Container>::value || is_map<Container>::value
+        , bool UniqueAssoc = is_unique_assoc<Container>::value
+        , bool Map  = is_map<Container>::value
+        >
+struct container_wrapper
+   : public Container
+{
+   typedef typename Container::allocator_type   allocator_type;
+   
+   container_wrapper(const allocator_type &a)
+      : Container(a)
+   {}
+};
+
+template<class Container>  //map
+struct container_wrapper<Container, true, true, true>
+   : public Container
+{
+   typedef typename Container::allocator_type   allocator_type;
+   typedef typename Container::key_compare      key_compare;
+   typedef typename Container::value_type       value_type;
+   typedef typename Container::const_iterator   const_iterator;
+   typedef typename Container::iterator         iterator;
+
+   container_wrapper(const allocator_type &a)
+      : Container(key_compare(), a)
+   {}
+
+   template<class Arg>
+   iterator emplace(const_iterator, const Arg &arg)
+   {
+      return this->Container::emplace(arg, arg).first;
+   }
+};
+
+template<class Container>  //set
+struct container_wrapper<Container, true, true, false>
+   : public Container
+{
+   typedef typename Container::allocator_type   allocator_type;
+   typedef typename Container::key_compare      key_compare;
+   typedef typename Container::value_type       value_type;
+   typedef typename Container::const_iterator   const_iterator;
+   typedef typename Container::iterator         iterator;
+
+   container_wrapper(const allocator_type &a)
+      : Container(key_compare(), a)
+   {}
+
+   template<class Arg>
+   iterator emplace(const_iterator, const Arg &arg)
+   {
+      return this->Container::emplace(arg).first;
+   }
+};
+
+template<class Container>  //multimap
+struct container_wrapper<Container, true, false, true>
+   : public Container
+{
+   typedef typename Container::value_type       value_type;
+   typedef typename Container::key_compare      key_compare;
+   typedef typename Container::allocator_type   allocator_type;
+   typedef typename Container::const_iterator   const_iterator;
+   typedef typename Container::iterator         iterator;
+
+   container_wrapper(const allocator_type &a)
+      : Container(key_compare(), a)
+   {}
+
+   template<class Arg>
+   iterator emplace(const_iterator, const Arg &arg)
+   {
+      return this->Container::emplace(arg, arg);
+   }
+};
+
+//multiset
+template<class Container>  //multimap
+struct container_wrapper<Container, true, false, false>
+   : public Container
+{
+   typedef typename Container::value_type       value_type;
+   typedef typename Container::key_compare      key_compare;
+   typedef typename Container::allocator_type   allocator_type;
+   typedef typename Container::const_iterator   const_iterator;
+   typedef typename Container::iterator         iterator;
+
+   container_wrapper(const allocator_type &a)
+      : Container(key_compare(), a)
+   {}
+
+   template<class Arg>
+   iterator emplace(const_iterator, const Arg &arg)
+   {
+      return this->Container::emplace(arg);
+   }
+};
+
+bool test_value_and_state_equals(const alloc_int &r, int value, int state)
+{  return r.get_value() == value && r.get_allocator_state() == state;  }
+
+template<class F, class S>
+bool test_value_and_state_equals(const container_detail::pair<F, S> &p, int value, int state)
+{  return test_value_and_state_equals(p.first, value, state) && test_alloc_state_equals(p.second, value, state);  }
+
+template<class F, class S>
+bool test_value_and_state_equals(const std::pair<F, S> &p, int value, int state)
+{  return test_value_and_state_equals(p.first, value, state) && test_value_and_state_equals(p.second, value, state);  }
+
+template<class Container>
+bool one_level_allocator_propagation_test()
+{
+   typedef container_wrapper<Container> ContainerWrapper;
+   typedef typename ContainerWrapper::iterator iterator;
+	ContainerWrapper c(SimpleAllocator<MapNode>(5));
+
+   c.clear();
+	iterator it = c.emplace(c.cbegin(), 42);
+
+   if(!test_value_and_state_equals(*it, 42, 5))
+      return false;
+
+   return true;
+}
+
+int main()
+{
+   //unique assoc
+   if(!one_level_allocator_propagation_test<FlatMap>())
+      return 1;
+   if(!one_level_allocator_propagation_test<Map>())
+      return 1;
+   if(!one_level_allocator_propagation_test<FlatSet>())
+      return 1;
+   if(!one_level_allocator_propagation_test<Set>())
+      return 1;
+   //multi assoc
+   if(!one_level_allocator_propagation_test<FlatMultiMap>())
+      return 1;
+   if(!one_level_allocator_propagation_test<MultiMap>())
+      return 1;
+   if(!one_level_allocator_propagation_test<FlatMultiSet>())
+      return 1;
+   if(!one_level_allocator_propagation_test<MultiSet>())
+      return 1;
+   //sequence containers
+   if(!one_level_allocator_propagation_test<Vector>())
+      return 1;
+   if(!one_level_allocator_propagation_test<Deque>())
+      return 1;
+   if(!one_level_allocator_propagation_test<List>())
+      return 1;
+   if(!one_level_allocator_propagation_test<Slist>())
+      return 1;
+   if(!one_level_allocator_propagation_test<StableVector>())
+      return 1;
         return 0;
 }
+
+#include <boost/container/detail/config_end.hpp>
Modified: branches/release/libs/intrusive/test/has_member_function_callable_with.cpp
==============================================================================
--- branches/release/libs/intrusive/test/has_member_function_callable_with.cpp	(original)
+++ branches/release/libs/intrusive/test/has_member_function_callable_with.cpp	2012-04-22 17:23:50 EDT (Sun, 22 Apr 2012)
@@ -94,7 +94,7 @@
    namespace intrusive{
    namespace intrusive_detail{
 
-      #if !defined(_MSC_VER) || (_MSC_VER != 1600)
+      #if !defined(_MSC_VER) || (_MSC_VER < 1600)
 
          #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)