diff --git a/include/boost/multi_index/detail/index_base.hpp b/include/boost/multi_index/detail/index_base.hpp index d00de37..bd31558 100644 --- a/include/boost/multi_index/detail/index_base.hpp +++ b/include/boost/multi_index/detail/index_base.hpp @@ -332,7 +332,14 @@ protected: void final_clear_(){final().clear_();} template - void final_merge_(Index& x){return final().merge_(x);} + void final_transfer_range_(Index& x) + {final_transfer_range_(x,x.begin(),x.end());} + template + void final_transfer_range_( + Index& x, + BOOST_DEDUCED_TYPENAME Index::iterator first, + BOOST_DEDUCED_TYPENAME Index::iterator last) + {final().transfer_range_(x,first,last);} void final_swap_(final_type& x){final().swap_(x);} diff --git a/include/boost/multi_index/detail/ord_index_impl.hpp b/include/boost/multi_index/detail/ord_index_impl.hpp index d0e8a84..1a5b40c 100644 --- a/include/boost/multi_index/detail/ord_index_impl.hpp +++ b/include/boost/multi_index/detail/ord_index_impl.hpp @@ -542,8 +542,9 @@ public: { BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - - this->final_merge_(x); + if(x.end().get_node()!=this->header()){ /* different containers */ + this->final_transfer_range_(x); + } } template diff --git a/include/boost/multi_index/hashed_index.hpp b/include/boost/multi_index/hashed_index.hpp index 108cbc8..ff84151 100644 --- a/include/boost/multi_index/hashed_index.hpp +++ b/include/boost/multi_index/hashed_index.hpp @@ -521,8 +521,9 @@ public: { BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - - this->final_merge_(x); + if(x.end().get_node()!=this->header()){ /* different containers */ + this->final_transfer_range_(x); + } } template diff --git a/include/boost/multi_index/random_access_index.hpp b/include/boost/multi_index/random_access_index.hpp index 724ad1b..f7a2103 100644 --- a/include/boost/multi_index/random_access_index.hpp +++ b/include/boost/multi_index/random_access_index.hpp @@ -541,7 +541,9 @@ public: BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER( this->final(*this),this->final(x)); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - external_splice(position,x,boost::is_copy_constructible()); + external_splice( + position,x,x.begin(),x.end(), + boost::is_copy_constructible()); } template @@ -1100,50 +1102,6 @@ private: return std::pair(make_iterator(p.first),p.second); } - template - void external_splice( - iterator position,Index& x,boost::true_type /* copy-constructible value */) - { - if(get_allocator()==x.get_allocator()){ - external_splice(position,x,boost::false_type()); - } - else{ - /* backwards compatibility with old, non-transfer-based splice */ - - iterator first=x.begin(),last=x.end(); - size_type n=size(); - BOOST_TRY{ - while(first!=last){ - if(push_back(*first).second)first=x.erase(first); - else ++first; - } - } - BOOST_CATCH(...){ - relocate(position,begin()+n,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,begin()+n,end()); - } - } - - template - void external_splice( - iterator position,Index& x, - boost::false_type /* copy-constructible value */) - { - BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); - size_type n=size(); - BOOST_TRY{ - this->final_merge_(x); - } - BOOST_CATCH(...){ - relocate(position,begin()+n,end()); - } - BOOST_CATCH_END - relocate(position,begin()+n,end()); - } - template void external_splice( iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i, @@ -1241,10 +1199,7 @@ private: BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); size_type n=size(); BOOST_TRY{ - while(first!=last){ - this->final_transfer_( - x,static_cast((first++).get_node())); - } + this->final_transfer_range_(x,first,last); } BOOST_CATCH(...){ relocate(position,begin()+n,end()); diff --git a/include/boost/multi_index/sequenced_index.hpp b/include/boost/multi_index/sequenced_index.hpp index 2c22fcf..d70ccff 100644 --- a/include/boost/multi_index/sequenced_index.hpp +++ b/include/boost/multi_index/sequenced_index.hpp @@ -492,7 +492,9 @@ public: BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER( this->final(*this),this->final(x)); BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - external_splice(position,x,boost::is_copy_constructible()); + external_splice( + position,x,x.begin(),x.end(), + boost::is_copy_constructible()); } template @@ -1013,49 +1015,6 @@ private: return std::pair(make_iterator(p.first),p.second); } - template - void external_splice( - iterator position,Index& x,boost::true_type /* copy-constructible value */) - { - if(get_allocator()==x.get_allocator()){ - external_splice(position,x,boost::false_type()); - } - else{ - /* backwards compatibility with old, non-transfer-based splice */ - - iterator first=x.begin(),last=x.end(); - while(first!=last){ - if(insert(position,*first).second)first=x.erase(first); - else ++first; - } - } - } - - template - void external_splice( - iterator position,Index& x, - boost::false_type /* copy-constructible value */) - { - BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); - if(position==end()){ - this->final_merge_(x); - } - else{ - iterator first=end(); - --first; - BOOST_TRY{ - this->final_merge_(x); - } - BOOST_CATCH(...){ - ++first; - relink(position.get_node(),first.get_node(),header()); - } - BOOST_CATCH_END - ++first; - relink(position.get_node(),first.get_node(),header()); - } - } - template void external_splice( iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i, @@ -1143,19 +1102,13 @@ private: { BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); if(position==end()){ - while(first!=last){ - this->final_transfer_( - x,static_cast((first++).get_node())); - } + this->final_transfer_range_(x,first,last); } else{ iterator first_to_relink=end(); --first_to_relink; BOOST_TRY{ - while(first!=last){ - this->final_transfer_( - x,static_cast((first++).get_node())); - } + this->final_transfer_range_(x,first,last); } BOOST_CATCH(...){ ++first_to_relink; diff --git a/include/boost/multi_index_container.hpp b/include/boost/multi_index_container.hpp index 9b76255..bd5a847 100644 --- a/include/boost/multi_index_container.hpp +++ b/include/boost/multi_index_container.hpp @@ -972,18 +972,13 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: } template - void merge_(Index& x) + void transfer_range_( + Index& x, + BOOST_DEDUCED_TYPENAME Index::iterator first, + BOOST_DEDUCED_TYPENAME Index::iterator last) { - typedef typename Index::iterator source_iterator; - - source_iterator last=x.end(); - - if(last.get_node()!=this->header()){ /* different containers */ - source_iterator first=x.begin(); - - while(first!=last){ - transfer_(x,static_cast((first++).get_node())); - } + while(first!=last){ + transfer_(x,static_cast((first++).get_node())); } }