diff --git a/include/boost/multi_index/random_access_index.hpp b/include/boost/multi_index/random_access_index.hpp index 9c3586d..724ad1b 100644 --- a/include/boost/multi_index/random_access_index.hpp +++ b/include/boost/multi_index/random_access_index.hpp @@ -541,7 +541,7 @@ public: BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER( this->final(*this),this->final(x)); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - splice_impl(position,x,boost::is_copy_constructible()); + external_splice(position,x,boost::is_copy_constructible()); } template @@ -568,7 +568,8 @@ public: if(pn!=in)relocate(pn,in); } else{ - splice_impl(position,x,i,boost::is_copy_constructible()); + external_splice( + position,x,i,boost::is_copy_constructible()); } } @@ -596,29 +597,25 @@ public: BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - splice_impl( - position,x,first,last,boost::is_copy_constructible()); - } - - void splice( - iterator position,random_access_index& x, - iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(&x==this)relocate(position,first,last); + if(x.end().get_node()==this->header()){ /* same container */ + BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); + internal_splice(position,first,last); + } else{ - splice_impl( + external_splice( position,x,first,last,boost::is_copy_constructible()); } } + template + BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(random_access_index,Index,void) + splice( + iterator position,BOOST_RV_REF(Index) x, + iterator first,iterator last) + { + splice(position,static_cast(x),first,last); + } + void remove(value_param_type value) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; @@ -1104,11 +1101,11 @@ private: } template - void splice_impl( + void external_splice( iterator position,Index& x,boost::true_type /* copy-constructible value */) { if(get_allocator()==x.get_allocator()){ - splice_impl(position,x,boost::false_type()); + external_splice(position,x,boost::false_type()); } else{ /* backwards compatibility with old, non-transfer-based splice */ @@ -1131,7 +1128,7 @@ private: } template - void splice_impl( + void external_splice( iterator position,Index& x, boost::false_type /* copy-constructible value */) { @@ -1148,12 +1145,12 @@ private: } template - void splice_impl( + void external_splice( iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i, boost::true_type /* copy-constructible value */) { if(get_allocator()==x.get_allocator()){ - splice_impl(position,x,i,boost::false_type()); + external_splice(position,x,i,boost::false_type()); } else{ /* backwards compatibility with old, non-transfer-based splice */ @@ -1176,7 +1173,7 @@ private: } template - void splice_impl( + void external_splice( iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i, boost::false_type /* copy-constructible value */) { @@ -1188,15 +1185,32 @@ private: } } + template + void internal_splice(iterator position,Iterator first,Iterator last) + { + index_node_type* pn=position.get_node(); + while(first!=last){ + relocate(pn,static_cast((first++).get_node())); + } + } + + void internal_splice(iterator position,iterator first,iterator last) + { + index_node_type* pn=position.get_node(); + index_node_type* fn=static_cast(first.get_node()); + index_node_type* ln=static_cast(last.get_node()); + if(pn!=ln)relocate(pn,fn,ln); + } + template - void splice_impl( + void external_splice( iterator position,Index& x, BOOST_DEDUCED_TYPENAME Index::iterator first, BOOST_DEDUCED_TYPENAME Index::iterator last, boost::true_type /* copy-constructible value */) { if(get_allocator()==x.get_allocator()){ - splice_impl(position,x,first,last,boost::false_type()); + external_splice(position,x,first,last,boost::false_type()); } else{ /* backwards compatibility with old, non-transfer-based splice */ @@ -1218,7 +1232,7 @@ private: } template - void splice_impl( + void external_splice( iterator position,Index& x, BOOST_DEDUCED_TYPENAME Index::iterator first, BOOST_DEDUCED_TYPENAME Index::iterator last,