diff --git a/doc/container.qbk b/doc/container.qbk index 2c66420..333bc09 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -718,9 +718,11 @@ use [*Boost.Container]? There are several reasons for that: * 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]. + [@https://svn.boost.org/trac/boost/ticket/9092 #9092]. [endsect] diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index 986b62f..e2dd4ee 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -736,7 +736,6 @@ class deque : protected deque_base } //If unequal allocators, then do a one by one move else{ - typedef typename std::iterator_traits::iterator_category ItCat; this->assign( boost::make_move_iterator(x.begin()) , boost::make_move_iterator(x.end())); } diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index 896f161..7f35b93 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -323,21 +323,21 @@ class flat_tree // insert/erase std::pair insert_unique(const value_type& val) { + std::pair ret; insert_commit_data data; - std::pair ret = this->priv_insert_unique_prepare(val, data); - if(ret.second){ - ret.first = this->priv_insert_commit(data, val); - } + ret.second = this->priv_insert_unique_prepare(val, data); + ret.first = ret.second ? this->priv_insert_commit(data, val) + : iterator(vector_iterator_get_ptr(data.position)); return ret; } std::pair insert_unique(BOOST_RV_REF(value_type) val) { + std::pair ret; insert_commit_data data; - std::pair ret = this->priv_insert_unique_prepare(val, data); - if(ret.second){ - ret.first = this->priv_insert_commit(data, boost::move(val)); - } + ret.second = this->priv_insert_unique_prepare(val, data); + ret.first = ret.second ? this->priv_insert_commit(data, boost::move(val)) + : iterator(vector_iterator_get_ptr(data.position)); return ret; } @@ -357,22 +357,20 @@ class flat_tree iterator insert_unique(const_iterator pos, const value_type& val) { + std::pair ret; insert_commit_data data; - std::pair ret = this->priv_insert_unique_prepare(pos, val, data); - if(ret.second){ - ret.first = this->priv_insert_commit(data, val); - } - return ret.first; + return this->priv_insert_unique_prepare(pos, val, data) + ? this->priv_insert_commit(data, val) + : iterator(vector_iterator_get_ptr(data.position)); } - iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) mval) + iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) val) { + std::pair ret; insert_commit_data data; - std::pair ret = this->priv_insert_unique_prepare(pos, mval, data); - if(ret.second){ - ret.first = this->priv_insert_commit(data, boost::move(mval)); - } - return ret.first; + return this->priv_insert_unique_prepare(pos, val, data) + ? this->priv_insert_commit(data, boost::move(val)) + : iterator(vector_iterator_get_ptr(data.position)); } iterator insert_equal(const_iterator pos, const value_type& val) @@ -553,13 +551,7 @@ class flat_tree stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); value_destructor d(a, val); - insert_commit_data data; - std::pair ret = - this->priv_insert_unique_prepare(val, data); - if(ret.second){ - ret.first = this->priv_insert_commit(data, boost::move(val)); - } - return ret; + return this->insert_unique(::boost::move(val)); } template @@ -570,12 +562,7 @@ class flat_tree stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); value_destructor d(a, val); - insert_commit_data data; - std::pair ret = this->priv_insert_unique_prepare(hint, val, data); - if(ret.second){ - ret.first = this->priv_insert_commit(data, boost::move(val)); - } - return ret.first; + return this->insert_unique(hint, ::boost::move(val)); } template @@ -586,9 +573,7 @@ class flat_tree stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); value_destructor d(a, val); - iterator i = this->upper_bound(KeyOfValue()(val)); - i = this->m_data.m_vect.insert(i, boost::move(val)); - return i; + return this->insert_equal(::boost::move(val)); } template @@ -599,10 +584,7 @@ class flat_tree stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_traits::construct(a, &val, ::boost::forward(args)... ); value_destructor d(a, val); - insert_commit_data data; - this->priv_insert_equal_prepare(hint, val, data); - iterator i = this->priv_insert_commit(data, boost::move(val)); - return i; + return this->insert_equal(hint, ::boost::move(val)); } #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING @@ -618,12 +600,7 @@ class flat_tree stored_allocator_traits::construct(a, &val \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ value_destructor d(a, val); \ - insert_commit_data data; \ - std::pair ret = this->priv_insert_unique_prepare(val, data); \ - if(ret.second){ \ - ret.first = this->priv_insert_commit(data, boost::move(val)); \ - } \ - return ret; \ + return this->insert_unique(::boost::move(val)); \ } \ \ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ @@ -635,13 +612,8 @@ class flat_tree stored_allocator_type &a = this->get_stored_allocator(); \ stored_allocator_traits::construct(a, &val \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ - value_destructor d(a, val); \ - insert_commit_data data; \ - std::pair ret = this->priv_insert_unique_prepare(hint, val, data); \ - if(ret.second){ \ - ret.first = this->priv_insert_commit(data, boost::move(val)); \ - } \ - return ret.first; \ + value_destructor d(a, val); \ + return this->insert_unique(hint, ::boost::move(val)); \ } \ \ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ @@ -653,9 +625,7 @@ class flat_tree stored_allocator_traits::construct(a, &val \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ value_destructor d(a, val); \ - iterator i = this->upper_bound(KeyOfValue()(val)); \ - i = this->m_data.m_vect.insert(i, boost::move(val)); \ - return i; \ + return this->insert_equal(::boost::move(val)); \ } \ \ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ @@ -668,12 +638,8 @@ class flat_tree stored_allocator_traits::construct(a, &val \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \ value_destructor d(a, val); \ - insert_commit_data data; \ - this->priv_insert_equal_prepare(hint, val, data); \ - iterator i = this->priv_insert_commit(data, boost::move(val)); \ - return i; \ + return this->insert_equal(hint, ::boost::move(val)); \ } \ - //! #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #include BOOST_PP_LOCAL_ITERATE() @@ -798,21 +764,19 @@ class flat_tree } } - std::pair priv_insert_unique_prepare + bool priv_insert_unique_prepare (const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data) { const value_compare &value_comp = this->m_data; commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val)); - return std::pair - ( iterator(vector_iterator_get_ptr(commit_data.position)) - , commit_data.position == e || value_comp(val, *commit_data.position)); + return commit_data.position == e || value_comp(val, *commit_data.position); } - std::pair priv_insert_unique_prepare + bool priv_insert_unique_prepare (const value_type& val, insert_commit_data &commit_data) - { return this->priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); } + { return this->priv_insert_unique_prepare(this->cbegin(), this->cend(), val, commit_data); } - std::pair priv_insert_unique_prepare + bool priv_insert_unique_prepare (const_iterator pos, const value_type& val, insert_commit_data &commit_data) { //N1780. Props to Howard Hinnant! @@ -827,37 +791,33 @@ class flat_tree //else // insert val before lower_bound(val) const value_compare &value_comp = this->m_data; - - if(pos == this->cend() || value_comp(val, *pos)){ - if(pos != this->cbegin() && !value_comp(val, pos[-1])){ - if(value_comp(pos[-1], val)){ - commit_data.position = pos; - return std::pair(iterator(vector_iterator_get_ptr(pos)), true); - } - else{ - return std::pair(iterator(vector_iterator_get_ptr(pos)), false); - } + const const_iterator cend_it = this->cend(); + if(pos == cend_it || value_comp(val, *pos)){ //Check if val should go before end + const const_iterator cbeg = this->cbegin(); + commit_data.position = pos; + if(pos == cbeg){ //If container is empty then insert it in the beginning + return true; + } + const_iterator prev(pos); + --prev; + if(value_comp(*prev, val)){ //If previous element was less, then it should go between prev and pos + return true; + } + else if(!value_comp(val, *prev)){ //If previous was equal then insertion should fail + commit_data.position = prev; + return false; + } + else{ //Previous was bigger so insertion hint was pointless, dispatch to hintless insertion + //but reduce the search between beg and prev as prev is bigger than val + return this->priv_insert_unique_prepare(cbeg, prev, val, commit_data); } - return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data); } - - // Works, but increases code complexity - //Next check - //else if (value_comp(*pos, val) && !value_comp(pos[1], val)){ - // if(value_comp(val, pos[1])){ - // commit_data.position = pos+1; - // return std::pair(pos+1, true); - // } - // else{ - // return std::pair(pos+1, false); - // } - //} else{ - //[... pos ... val ... ] //The hint is before the insertion position, so insert it - //in the remaining range - return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data); + //in the remaining range [pos, end) + return this->priv_insert_unique_prepare(pos, cend_it, val, commit_data); } + //return priv_insert_unique_prepare(val, commit_data); } template diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp index f9f2108..e594959 100644 --- a/include/boost/container/scoped_allocator.hpp +++ b/include/boost/container/scoped_allocator.hpp @@ -583,8 +583,10 @@ class scoped_allocator_adaptor_base }; typedef OuterAlloc outer_allocator_type; - typedef scoped_allocator_adaptor inner_allocator_type; - typedef allocator_traits inner_traits_type; + typedef scoped_allocator_adaptor inner_allocator_type; + typedef allocator_traits inner_traits_type; + typedef scoped_allocator_adaptor + scoped_allocator_type; typedef boost::integral_constant< bool, outer_traits_type::propagate_on_container_copy_assignment::value || @@ -635,7 +637,7 @@ class scoped_allocator_adaptor_base , m_inner(other.inner_allocator()) {} - protected: + public: struct internal_type_t{}; template @@ -670,6 +672,9 @@ class scoped_allocator_adaptor_base 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 @@ class scoped_allocator_adaptor_base const outer_allocator_type &outer_allocator() const { return static_cast(*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 @@ class scoped_allocator_adaptor_base inner_allocator_type; \ + typedef scoped_allocator_adaptor scoped_allocator_type; \ typedef allocator_traits inner_traits_type; \ typedef boost::integral_constant< \ bool, \ @@ -790,7 +809,7 @@ class scoped_allocator_adaptor_base \ @@ -824,6 +843,9 @@ class scoped_allocator_adaptor_basem_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 @@ class scoped_allocator_adaptor_base(*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 @@ class scoped_allocator_adaptor_base typedef OuterAlloc outer_allocator_type; typedef allocator_traits outer_traits_type; typedef scoped_allocator_adaptor inner_allocator_type; + typedef inner_allocator_type scoped_allocator_type; typedef allocator_traits inner_traits_type; typedef typename outer_traits_type:: propagate_on_container_copy_assignment propagate_on_container_copy_assignment; @@ -922,7 +953,7 @@ class scoped_allocator_adaptor_base : outer_allocator_type(other.outer_allocator()) {} - protected: + public: struct internal_type_t{}; template @@ -948,6 +979,9 @@ class scoped_allocator_adaptor_base 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(*this); } @@ -959,6 +993,17 @@ class scoped_allocator_adaptor_base const outer_allocator_type &outer_allocator() const { return static_cast(*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 @@ class scoped_allocator_adaptor , 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 @@ class scoped_allocator_adaptor {} scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) - { - base_type::operator=(static_cast(other)); - return *this; - } + { return static_cast(base_type::operator=(static_cast(other))); } scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) - { - base_type::operator=(boost::move(static_cast(other))); - return *this; - } + { return static_cast(base_type::operator=(boost::move(static_cast(other)))); } + + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: swaps *this with r. + //! + void swap(scoped_allocator_adaptor &r); //! Effects: swaps *this with r. //! - void swap(scoped_allocator_adaptor &r) - { - base_type::swap(r); - } - - //! Effects: 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); //! Returns: //! `static_cast(*this)`. - outer_allocator_type & outer_allocator() - { return *this; } + outer_allocator_type & outer_allocator(); //! Returns: //! `static_cast(*this)`. - const outer_allocator_type &outer_allocator() const - { return *this; } + const outer_allocator_type &outer_allocator() const; //! Returns: //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. - inner_allocator_type& inner_allocator() - { return base_type::inner_allocator(); } + inner_allocator_type& inner_allocator(); //! Returns: //! *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 //! Returns: //! `allocator_traits::max_size(outer_allocator())`. @@ -1244,18 +1278,14 @@ class scoped_allocator_adaptor outer_traits_type::deallocate(this->outer_allocator(), p, n); } + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: Allocator new scoped_allocator_adaptor object where each allocator //! A in the adaptor is initialized from the result of calling //! `allocator_traits::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 @@ class scoped_allocator_adaptor //template //void construct(pair* p, piecewise_construct_t, tuple x, tuple y); - private: + public: + //Internal function template scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) : base_type(internal_type_t(), ::boost::forward(outer), inner) diff --git a/test/expand_bwd_test_template.hpp b/test/expand_bwd_test_template.hpp index c1f26e1..7014466 100644 --- a/test/expand_bwd_test_template.hpp +++ b/test/expand_bwd_test_template.hpp @@ -183,7 +183,6 @@ bool test_assign_with_expand_bwd() { typedef typename VectorWithExpandBwdAllocator::value_type value_type; typedef typename boost::remove_volatile::type non_volatile_value_type; - typedef std::vector Vect; const int MemorySize = 200; const int Offset[] = { 50, 50, 50}; diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp index 146285c..aac8a27 100644 --- a/test/flat_tree_test.cpp +++ b/test/flat_tree_test.cpp @@ -638,76 +638,3 @@ int main() #include -/* -#include -#include -#include -#include -#include - -struct Request -{ - Request() {}; - - //Move semantics... - Request(BOOST_RV_REF(Request) r) : rvals() //Move constructor - { - rvals.swap(r.rvals); - }; - - Request& operator=(BOOST_RV_REF(Request) r) //Move assignment - { - if (this != &r){ - rvals.swap(r.rvals); - } - return *this; - }; - - // Values I want to be moved, not copied. - boost::container::vector rvals; - - private: - // Mark this class movable but not copyable - BOOST_MOVABLE_BUT_NOT_COPYABLE(Request) -}; - -typedef boost::container::flat_map Requests; -//typedef boost::container::map Requests2; - -int -main() { - Requests req; - std::pair ret = req.insert( Requests::value_type( 7, Request() ) ); - std::cout << "Insert success for req: " << ret.second << std::endl; - - //Requests2 req2; - //std::pair ret2 = req2.insert( Requests2::value_type( 7, Request() ) ); - //std::cout << "Insert success for req2: " << ret2.second << std::endl; - - return 0; -} -*/ -/* -#include -#include -#include - -using namespace std; - -int main(int , char *[]) -{ - double d[] = {0, 0.2, 0.8, 1, 2, 3, 4}; - boost::container::flat_set set; - - set.insert(0); - set.insert(set.end(), 1); - set.insert(set.end(), 3); - set.insert(boost::container::ordered_unique_range_t(), d, d + sizeof(d)/sizeof(*d)); - boost::container::flat_set::iterator it(set.begin()); - boost::container::flat_set::iterator const itend(set.end()); - while(it != itend) - cout << *it++ << endl; - - return 0; -} -*/ \ No newline at end of file diff --git a/test/scoped_allocator_adaptor_test.cpp b/test/scoped_allocator_adaptor_test.cpp index 61e8c7b..3464aa4 100644 --- a/test/scoped_allocator_adaptor_test.cpp +++ b/test/scoped_allocator_adaptor_test.cpp @@ -36,16 +36,20 @@ class test_allocator 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 test_allocator(BOOST_RV_REF_BEG test_allocator BOOST_RV_REF_END) + : m_move_contructed(true), m_move_assigned(false) {} template @@ -53,10 +57,15 @@ class test_allocator {} 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 @@ class test_allocator void deallocate(T*p, std::size_t) { delete []static_cast(static_cast(p)); } + + bool m_move_contructed; + bool m_move_assigned; }; template @@ -252,7 +264,6 @@ int main() typedef test_allocator, 1> InnerAlloc1; typedef test_allocator, 2> InnerAlloc2; typedef test_allocator, 11> Inner11IdAlloc1; - typedef test_allocator, 12> Inner12IdAlloc2; typedef test_allocator, 0, false> OuterAllocFalsePropagate; typedef test_allocator, 0, true> OuterAllocTruePropagate; @@ -277,11 +288,6 @@ int main() , InnerAlloc1 > ScopedScoped1Inner; - typedef scoped_allocator_adaptor - < scoped_allocator_adaptor - - , InnerAlloc1, InnerAlloc2 - > ScopedScoped2Inner; typedef scoped_allocator_adaptor< Rebound9OuterAlloc > Rebound9Scoped0Inner; typedef scoped_allocator_adaptor< Rebound9OuterAlloc , InnerAlloc1 > Rebound9Scoped1Inner; @@ -481,6 +487,64 @@ int main() 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 @@ int main() } ////////////////////////////////////////////////////////////////////////////////// - //Now test recursive OuterAllocator types (OuterAllocator is an scoped_allocator) + //Now test recursive OuterAllocator types (OuterAllocator is a scoped_allocator) ////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// @@ -1102,17 +1166,8 @@ int main() 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