Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85537 - in trunk: boost/container libs/container/doc libs/container/test
From: igaztanaga_at_[hidden]
Date: 2013-08-31 17:49:27


Author: igaztanaga
Date: 2013-08-31 17:49:26 EDT (Sat, 31 Aug 2013)
New Revision: 85537
URL: http://svn.boost.org/trac/boost/changeset/85537

Log:
Fixes #9064

Text files modified:
   trunk/boost/container/deque.hpp | 1
   trunk/boost/container/scoped_allocator.hpp | 105 +++++++++++++++++++++++++--------------
   trunk/libs/container/doc/container.qbk | 5 +
   trunk/libs/container/test/scoped_allocator_adaptor_test.cpp | 91 +++++++++++++++++++++++++++------
   4 files changed, 144 insertions(+), 58 deletions(-)

Modified: trunk/boost/container/deque.hpp
==============================================================================
--- trunk/boost/container/deque.hpp Sat Aug 31 16:09:11 2013 (r85536)
+++ trunk/boost/container/deque.hpp 2013-08-31 17:49:26 EDT (Sat, 31 Aug 2013) (r85537)
@@ -736,7 +736,6 @@
          }
          //If unequal allocators, then do a one by one move
          else{
- typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
             this->assign( boost::make_move_iterator(x.begin())
                         , boost::make_move_iterator(x.end()));
          }

Modified: trunk/boost/container/scoped_allocator.hpp
==============================================================================
--- trunk/boost/container/scoped_allocator.hpp Sat Aug 31 16:09:11 2013 (r85536)
+++ trunk/boost/container/scoped_allocator.hpp 2013-08-31 17:49:26 EDT (Sat, 31 Aug 2013) (r85537)
@@ -583,8 +583,10 @@
    };
 
    typedef OuterAlloc outer_allocator_type;
- typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
- typedef allocator_traits<inner_allocator_type> inner_traits_type;
+ typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
+ typedef allocator_traits<inner_allocator_type> inner_traits_type;
+ typedef scoped_allocator_adaptor
+ <OuterAlloc, InnerAllocs...> scoped_allocator_type;
    typedef boost::integral_constant<
       bool,
       outer_traits_type::propagate_on_container_copy_assignment::value ||
@@ -635,7 +637,7 @@
       , m_inner(other.inner_allocator())
       {}
 
- protected:
+ public:
    struct internal_type_t{};
 
    template <class OuterA2>
@@ -670,6 +672,9 @@
       boost::container::swap_dispatch(this->m_inner, r.inner_allocator());
    }
 
+ friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
+ { l.swap(r); }
+
    inner_allocator_type& inner_allocator()
       { return m_inner; }
 
@@ -682,6 +687,15 @@
    const outer_allocator_type &outer_allocator() const
       { return static_cast<const outer_allocator_type&>(*this); }
 
+ scoped_allocator_type select_on_container_copy_construction() const
+ {
+ return scoped_allocator_type
+ (internal_type_t()
+ ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
+ ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
+ );
+ }
+
    private:
    inner_allocator_type m_inner;
 };
@@ -730,6 +744,11 @@
          ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
          , BOOST_CONTAINER_PP_IDENTITY, nat) \
> inner_allocator_type; \
+ typedef scoped_allocator_adaptor<OuterAlloc, BOOST_PP_ENUM_PARAMS(n, Q) \
+ BOOST_PP_ENUM_TRAILING \
+ ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
+ , BOOST_CONTAINER_PP_IDENTITY, nat) \
+ > scoped_allocator_type; \
    typedef allocator_traits<inner_allocator_type> inner_traits_type; \
    typedef boost::integral_constant< \
       bool, \
@@ -790,7 +809,7 @@
       , m_inner(other.inner_allocator()) \
       {} \
                                                                                                 \
- protected: \
+ public: \
    struct internal_type_t{}; \
                                                                                                 \
    template <class OuterA2> \
@@ -824,6 +843,9 @@
       boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); \
    } \
                                                                                                 \
+ friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) \
+ { l.swap(r); } \
+ \
    inner_allocator_type& inner_allocator() \
       { return m_inner; } \
                                                                                                 \
@@ -836,6 +858,14 @@
    const outer_allocator_type &outer_allocator() const \
       { return static_cast<const outer_allocator_type&>(*this); } \
                                                                                                 \
+ scoped_allocator_type select_on_container_copy_construction() const \
+ { \
+ return scoped_allocator_type \
+ (internal_type_t() \
+ ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) \
+ ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) \
+ ); \
+ } \
    private: \
    inner_allocator_type m_inner; \
 }; \
@@ -874,6 +904,7 @@
    typedef OuterAlloc outer_allocator_type;
    typedef allocator_traits<OuterAlloc> outer_traits_type;
    typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
+ typedef inner_allocator_type scoped_allocator_type;
    typedef allocator_traits<inner_allocator_type> inner_traits_type;
    typedef typename outer_traits_type::
       propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
@@ -922,7 +953,7 @@
       : outer_allocator_type(other.outer_allocator())
       {}
 
- protected:
+ public:
    struct internal_type_t{};
 
    template <class OuterA2>
@@ -948,6 +979,9 @@
       boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator());
    }
 
+ friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
+ { l.swap(r); }
+
    inner_allocator_type& inner_allocator()
       { return static_cast<inner_allocator_type&>(*this); }
 
@@ -959,6 +993,17 @@
 
    const outer_allocator_type &outer_allocator() const
       { return static_cast<const outer_allocator_type&>(*this); }
+
+ scoped_allocator_type select_on_container_copy_construction() const
+ {
+ return scoped_allocator_type
+ (internal_type_t()
+ ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
+ //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
+ //as inner_allocator() is equal to *this and that would trigger an infinite loop
+ , this->inner_allocator()
+ );
+ }
 };
 
 } //namespace container_detail {
@@ -1040,7 +1085,7 @@
       , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
       #endif
> base_type;
- typedef typename base_type::internal_type_t internal_type_t;
+ typedef typename base_type::internal_type_t internal_type_t;
    /// @endcond
    typedef OuterAlloc outer_allocator_type;
    //! Type: For exposition only
@@ -1164,48 +1209,37 @@
       {}
 
    scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
- {
- base_type::operator=(static_cast<const base_type &>(other));
- return *this;
- }
+ { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
 
    scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
- {
- base_type::operator=(boost::move(static_cast<scoped_allocator_adaptor&>(other)));
- return *this;
- }
+ { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(static_cast<base_type&>(other)))); }
 
+ #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
    //! <b>Effects</b>: swaps *this with r.
    //!
- void swap(scoped_allocator_adaptor &r)
- {
- base_type::swap(r);
- }
+ void swap(scoped_allocator_adaptor &r);
 
    //! <b>Effects</b>: swaps *this with r.
    //!
- friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r)
- { l.swap(r); }
+ friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
 
    //! <b>Returns</b>:
    //! `static_cast<OuterAlloc&>(*this)`.
- outer_allocator_type & outer_allocator()
- { return *this; }
+ outer_allocator_type & outer_allocator();
 
    //! <b>Returns</b>:
    //! `static_cast<const OuterAlloc&>(*this)`.
- const outer_allocator_type &outer_allocator() const
- { return *this; }
+ const outer_allocator_type &outer_allocator() const;
 
    //! <b>Returns</b>:
    //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
- inner_allocator_type& inner_allocator()
- { return base_type::inner_allocator(); }
+ inner_allocator_type& inner_allocator();
 
    //! <b>Returns</b>:
    //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
- inner_allocator_type const& inner_allocator() const
- { return base_type::inner_allocator(); }
+ inner_allocator_type const& inner_allocator() const;
+
+ #endif //BOOST_CONTAINER_DOXYGEN_INVOKED
 
    //! <b>Returns</b>:
    //! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
@@ -1244,18 +1278,14 @@
       outer_traits_type::deallocate(this->outer_allocator(), p, n);
    }
 
+ #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
    //! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator
    //! A in the adaptor is initialized from the result of calling
    //! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
    //! the corresponding allocator in *this.
- scoped_allocator_adaptor select_on_container_copy_construction() const
- {
- return scoped_allocator_adaptor
- (internal_type_t()
- ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
- ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
- );
- }
+ scoped_allocator_adaptor select_on_container_copy_construction() const;
+ #endif //BOOST_CONTAINER_DOXYGEN_INVOKED
+
    /// @cond
    base_type &base() { return *this; }
 
@@ -1426,7 +1456,8 @@
    //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:
+ public:
+ //Internal function
    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)

Modified: trunk/libs/container/doc/container.qbk
==============================================================================
--- trunk/libs/container/doc/container.qbk Sat Aug 31 16:09:11 2013 (r85536)
+++ trunk/libs/container/doc/container.qbk 2013-08-31 17:49:26 EDT (Sat, 31 Aug 2013) (r85537)
@@ -718,9 +718,10 @@
 
 * Implemented [link container.main_features.scary_iterators SCARY iterators].
 
-* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/8892 #8892],
+* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/8269 #8269],
               [@https://svn.boost.org/trac/boost/ticket/8473 #8473],
- [@https://svn.boost.org/trac/boost/ticket/8269 #8269].
+ [@https://svn.boost.org/trac/boost/ticket/8892 #8892],
+ [@https://svn.boost.org/trac/boost/ticket/9064 #9064].
 
 [endsect]
 

Modified: trunk/libs/container/test/scoped_allocator_adaptor_test.cpp
==============================================================================
--- trunk/libs/container/test/scoped_allocator_adaptor_test.cpp Sat Aug 31 16:09:11 2013 (r85536)
+++ trunk/libs/container/test/scoped_allocator_adaptor_test.cpp 2013-08-31 17:49:26 EDT (Sat, 31 Aug 2013) (r85537)
@@ -36,16 +36,20 @@
    typedef T value_type;
 
    test_allocator()
+ : m_move_contructed(false), m_move_assigned(false)
    {}
 
    test_allocator(const test_allocator&)
+ : m_move_contructed(false), m_move_assigned(false)
    {}
 
    test_allocator(BOOST_RV_REF(test_allocator) )
+ : m_move_contructed(true), m_move_assigned(false)
    {}
 
    template<class U>
    test_allocator(BOOST_RV_REF_BEG test_allocator<U, Id, Propagate> BOOST_RV_REF_END)
+ : m_move_contructed(true), m_move_assigned(false)
    {}
 
    template<class U>
@@ -53,10 +57,15 @@
    {}
 
    test_allocator & operator=(BOOST_COPY_ASSIGN_REF(test_allocator))
- { return *this; }
+ {
+ return *this;
+ }
 
    test_allocator & operator=(BOOST_RV_REF(test_allocator))
- { return *this; }
+ {
+ m_move_assigned = true;
+ return *this;
+ }
 
    std::size_t max_size() const
    { return std::size_t(Id); }
@@ -66,6 +75,9 @@
 
    void deallocate(T*p, std::size_t)
    { delete []static_cast<char*>(static_cast<void*>(p)); }
+
+ bool m_move_contructed;
+ bool m_move_assigned;
 };
 
 template <class T1, class T2, unsigned int Id, bool Propagate>
@@ -252,7 +264,6 @@
    typedef test_allocator<tagged_integer<1>, 1> InnerAlloc1;
    typedef test_allocator<tagged_integer<2>, 2> InnerAlloc2;
    typedef test_allocator<tagged_integer<1>, 11> Inner11IdAlloc1;
- typedef test_allocator<tagged_integer<1>, 12> Inner12IdAlloc2;
 
    typedef test_allocator<tagged_integer<0>, 0, false> OuterAllocFalsePropagate;
    typedef test_allocator<tagged_integer<0>, 0, true> OuterAllocTruePropagate;
@@ -277,11 +288,6 @@
          <Outer10IdAlloc, Inner11IdAlloc1>
       , InnerAlloc1
> ScopedScoped1Inner;
- typedef scoped_allocator_adaptor
- < scoped_allocator_adaptor
- <Outer10IdAlloc, Inner11IdAlloc1, Inner12IdAlloc2>
- , InnerAlloc1, InnerAlloc2
- > ScopedScoped2Inner;
    typedef scoped_allocator_adaptor< Rebound9OuterAlloc > Rebound9Scoped0Inner;
    typedef scoped_allocator_adaptor< Rebound9OuterAlloc
                                    , InnerAlloc1 > Rebound9Scoped1Inner;
@@ -481,6 +487,64 @@
       Scoped1Inner s1i;
    }
 
+ //Copy constructor/assignment
+ {
+ Scoped0Inner s0i;
+ Scoped1Inner s1i;
+ Scoped2Inner s2i;
+
+ Scoped0Inner s0i_b(s0i);
+ Scoped1Inner s1i_b(s1i);
+ Scoped2Inner s2i_b(s2i);
+
+ if(!(s0i == s0i_b) ||
+ !(s1i == s1i_b) ||
+ !(s2i == s2i_b)
+ ){
+ return 1;
+ }
+
+ s0i_b = s0i;
+ s1i_b = s1i;
+ s2i_b = s2i;
+
+ if(!(s0i == s0i_b) ||
+ !(s1i == s1i_b) ||
+ !(s2i == s2i_b)
+ ){
+ return 1;
+ }
+ }
+
+ //Copy/move constructor/assignment
+ {
+ Scoped0Inner s0i;
+ Scoped1Inner s1i;
+ Scoped2Inner s2i;
+
+ Scoped0Inner s0i_b(::boost::move(s0i));
+ Scoped1Inner s1i_b(::boost::move(s1i));
+ Scoped2Inner s2i_b(::boost::move(s2i));
+
+ if(!(s0i_b.outer_allocator().m_move_contructed) ||
+ !(s1i_b.outer_allocator().m_move_contructed) ||
+ !(s2i_b.outer_allocator().m_move_contructed)
+ ){
+ return 1;
+ }
+
+ s0i_b = ::boost::move(s0i);
+ s1i_b = ::boost::move(s1i);
+ s2i_b = ::boost::move(s2i);
+
+ if(!(s0i_b.outer_allocator().m_move_assigned) ||
+ !(s1i_b.outer_allocator().m_move_assigned) ||
+ !(s2i_b.outer_allocator().m_move_assigned)
+ ){
+ return 1;
+ }
+ }
+
    //inner_allocator()
    {
       Scoped0Inner s0i;
@@ -880,7 +944,7 @@
       }
 
       //////////////////////////////////////////////////////////////////////////////////
- //Now test recursive OuterAllocator types (OuterAllocator is an scoped_allocator)
+ //Now test recursive OuterAllocator types (OuterAllocator is a scoped_allocator)
       //////////////////////////////////////////////////////////////////////////////////
 
       ////////////////////////////////////////////////////////////
@@ -1102,17 +1166,8 @@
          using boost::container::container_detail::pair;
          typedef test_allocator< pair< tagged_integer<0>
                                , tagged_integer<0> >, 0> OuterPairAlloc;
- typedef test_allocator< pair< tagged_integer<1>
- , tagged_integer<1> >, 1> InnerPairAlloc1;
- typedef test_allocator< pair< tagged_integer<2>
- , tagged_integer<2> >, 2> InnerPairAlloc2;
          //
          typedef scoped_allocator_adaptor < OuterPairAlloc > ScopedPair0Inner;
- typedef scoped_allocator_adaptor < OuterPairAlloc
- , InnerPairAlloc1 > ScopedPair1Inner;
- typedef scoped_allocator_adaptor < OuterPairAlloc
- , InnerPairAlloc1
- , InnerPairAlloc2 > ScopedPair2Inner;
 
          ScopedPair0Inner s0i;
          //Check construction with 0 user arguments


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