refactored merge algorithm into multi_index_container

This commit is contained in:
joaquintides 2021-08-05 18:22:18 +02:00
parent 3b6079d13b
commit c2f282ffb6
7 changed files with 47 additions and 30 deletions

View File

@ -177,9 +177,9 @@ protected:
return x;
}
template<typename Index>
template<typename MultiIndexContainer>
final_node_type* insert_(
const value_type& v,final_node_type*& x,Index* p)
const value_type& v,final_node_type*& x,MultiIndexContainer* p)
{
p->final_extract_for_merge_(x);
return x;
@ -255,6 +255,10 @@ protected:
final_type& final(){return *static_cast<final_type*>(this);}
const final_type& final()const{return *static_cast<const final_type*>(this);}
template<typename Index>
static typename Index::final_type& final(Index& x) /* cross-index access */
{return static_cast<typename Index::final_type&>(x);}
final_node_type* final_header()const{return final().header();}
bool final_empty_()const{return final().empty_();}
@ -274,9 +278,6 @@ protected:
std::pair<final_node_type*,bool> final_insert_nh_(final_node_handle_type& nh)
{return final().insert_nh_(nh);}
template<typename Index>
void final_merge_(final_node_type* x,Index& i){return final().merge_(x,i);}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> final_emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
@ -326,6 +327,9 @@ protected:
void final_delete_all_nodes_(){final().delete_all_nodes_();}
void final_clear_(){final().clear_();}
template<typename Index>
void final_merge_(Index& x){return final().merge_(x);}
void final_swap_(final_type& x){final().swap_(x);}
bool final_replace_(

View File

@ -152,7 +152,7 @@ class ordered_index_impl:
#endif
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
/* access to final_extract_for_merge_ from external containers */
/* cross-index access */
template <typename,typename,typename> friend class index_base;
#endif
@ -557,16 +557,7 @@ public:
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
typedef typename Index::iterator source_iterator;
source_iterator first=x.begin(),last=x.end();
if(static_cast<final_node_type*>(last.get_node())!=
static_cast<final_node_type*>(this->header())){ /* different cntners */
while(first!=last){
this->final_merge_(
static_cast<final_node_type*>((first++).get_node()),x);
}
}
this->final_merge_(x);
}
template<typename Index>

View File

@ -107,7 +107,7 @@ class hashed_index:
#endif
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
/* access to final_extract_for_merge_ from external containers */
/* cross-index access */
template <typename,typename,typename> friend class index_base;
#endif

View File

@ -98,7 +98,7 @@ class random_access_index:
#endif
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
/* access to final_extract_for_merge_ from external containers */
/* cross-index access */
template <typename,typename,typename> friend class index_base;
#endif

View File

@ -88,7 +88,7 @@ class sequenced_index:
#endif
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
/* access to final_extract_for_merge_ from external containers */
/* cross-index access */
template <typename,typename,typename> friend class index_base;
#endif

View File

@ -767,13 +767,6 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
}
}
template<typename Index>
void merge_(final_node_type* x,Index& i)
{
final_node_type* res=super::insert_(x->value(),x,&i);
if(res==x)++node_count;
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
@ -965,6 +958,23 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
node_count=0;
}
template<typename Index>
void merge_(Index& x)
{
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){
final_node_type* n=static_cast<final_node_type*>((first++).get_node());
if(super::insert_(n->value(),n,&super::final(x))==n)++node_count;
}
}
}
void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
{
swap_(

View File

@ -414,9 +414,21 @@ void test_merge()
sequenced<>,
ranked_non_unique<identity<int> >
>
> container;
> container1;
container c1,c2;
typedef multi_index_container<
int,
indexed_by<
ordered_non_unique<identity<int> >,
hashed_non_unique<identity<int> >,
random_access<>,
sequenced<>,
ranked_non_unique<identity<int>, std::greater<int> >
>
> container2;
container1 c1;
container2 c2;
for(int i=0;i<5;++i){
c1.insert(i);
c2.insert(2*i);
@ -426,7 +438,7 @@ void test_merge()
BOOST_TEST(c1.size()==10&&c2.size()==0);
c1.merge(c1.get<2>());
BOOST_TEST(c1.size()==10&&c2.size()==0);
c2.merge(c1.get<2>());
c2.merge(c1.get<4>());
BOOST_TEST(c1.size()==0&&c2.size()==10);
c2.merge(c2);
BOOST_TEST(c2.size()==10);
@ -434,7 +446,7 @@ void test_merge()
BOOST_TEST(c2.size()==10);
c2.merge(boost::move(c2.get<3>()));
BOOST_TEST(c2.size()==10);
c2.merge(static_cast<BOOST_RV_REF(container)>(container(c2)));
c2.merge(static_cast<BOOST_RV_REF(container2)>(container2(c2)));
BOOST_TEST(c2.size()==20);
}