diff --git a/doc/container.qbk b/doc/container.qbk index 76a0fdf..71bb14e 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1321,6 +1321,7 @@ use [*Boost.Container]? There are several reasons for that: * Fixed bugs/issues: * [@https://github.com/boostorg/container/issues/126 GitHub #126: ['"flat_set.hpp and set.hpp in pmr have the same header guard"]]. + * [@https://github.com/boostorg/container/issues/128 GitHub #128: ['"moved from small_vector and static_vector calls destructor on elements in static part"]]. * [@https://github.com/boostorg/container/issues/129 GitHub #129: ['"Alias templates for small_flat_[multi]{set|map} using small_vector as container"]]. * [@https://github.com/boostorg/container/pull/135 GitHub #135: ['"Missing BOOST_NORETURN for user defined functions"]]. * [@https://github.com/boostorg/container/pull/137 GitHub #137: ['"RandomAccessIterator + 0"]]. diff --git a/include/boost/container/small_vector.hpp b/include/boost/container/small_vector.hpp index 6529a82..fcdf3f2 100644 --- a/include/boost/container/small_vector.hpp +++ b/include/boost/container/small_vector.hpp @@ -460,6 +460,7 @@ class small_vector_base this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end ())) ); + x.clear(); } } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index e82f278..8000017 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -591,6 +591,9 @@ struct vector_alloc_holder { ::boost::container::uninitialized_move_alloc_n (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start())); + ::boost::container::destroy_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size); + holder.m_size = 0; } template @@ -2385,6 +2388,9 @@ private: const size_type other_sz = static_cast(x.m_holder.m_size); boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); this->m_holder.m_size = other_sz; + //Not emptying the source container seems to be confusing for users as drop-in + //replacement for non-static vectors, so clear it. + x.clear(); } template @@ -2413,11 +2419,13 @@ private: this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity); this->m_holder.steal_resources(x.m_holder); } - //Else do a one by one move + //Else do a one by one move. Also, clear the source as users find confusing + //elements are still alive in the source container. else{ this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end() )) ); + x.clear(); } //Move allocator if needed dtl::move_alloc(this_alloc, x_alloc, dtl::bool_()); diff --git a/test/static_vector_test.cpp b/test/static_vector_test.cpp index 539eea8..9527190 100644 --- a/test/static_vector_test.cpp +++ b/test/static_vector_test.cpp @@ -495,11 +495,9 @@ void test_swap_and_move_nd() BOOST_TEST(v1.size() == N/2); BOOST_TEST(s1.size() == N); - //iG moving does not imply emptying source - //BOOST_TEST(v2.size() == 0); + BOOST_TEST(v2.size() == 0); BOOST_TEST(s2.size() == N); - //iG moving does not imply emptying source - //BOOST_TEST(v3.size() == 0); + BOOST_TEST(v3.size() == 0); BOOST_TEST(s3.size() == N); BOOST_TEST(v4.size() == N/2); BOOST_TEST(s4.size() == N);