diff --git a/include/boost/multi_index/random_access_index.hpp b/include/boost/multi_index/random_access_index.hpp index e0ac146..54b9d65 100644 --- a/include/boost/multi_index/random_access_index.hpp +++ b/include/boost/multi_index/random_access_index.hpp @@ -551,6 +551,20 @@ public: splice(position,static_cast(x)); } + template + BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(random_access_index,Index,void) + splice( + iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + splice_impl(position,x,i,boost::is_copy_constructible()); + } + void splice( iterator position,random_access_index& x,iterator i) { @@ -562,20 +576,7 @@ public: BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; if(&x==this)relocate(position,i); else{ - if(insert(position,*i).second){ - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following - * workaround is needed. Left it for all compilers as it does no - * harm. - */ - i.detach(); - x.erase(x.make_iterator(i.get_node())); -#else - x.erase(i); -#endif - - } + splice_impl(position,x,i,boost::is_copy_constructible()); } } @@ -1140,6 +1141,47 @@ private: relocate(position,begin()+n,end()); } + template + void splice_impl( + 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()); + } + else{ + /* backwards compatibility with old, non-transfer-based splice */ + + if(insert(position,*i).second){ + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the + * following workaround is needed. Left it for all compilers as it + * does no harm. + */ + + i.detach(); + x.erase(x.make_iterator(i.get_node())); +#else + x.erase(i); +#endif + } + } + } + + template + void splice_impl( + iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i, + boost::false_type /* copy-constructible value */) + { + BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x); + std::pair p=this->final_transfer_( + x,static_cast(i.get_node())); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + } + ptr_array ptrs; #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\