mirror of
https://github.com/boostorg/multi_index.git
synced 2025-05-11 05:14:05 +00:00
added partial merge functionality to key-based indices
plus fixed a compile-time error with legacy splice code when applied to different-type indices
This commit is contained in:
parent
4d15bf41fa
commit
dc480499a2
@ -331,9 +331,6 @@ protected:
|
|||||||
void final_delete_all_nodes_(){final().delete_all_nodes_();}
|
void final_delete_all_nodes_(){final().delete_all_nodes_();}
|
||||||
void final_clear_(){final().clear_();}
|
void final_clear_(){final().clear_();}
|
||||||
|
|
||||||
template<typename Index>
|
|
||||||
void final_transfer_range_(Index& x)
|
|
||||||
{final_transfer_range_(x,x.begin(),x.end());}
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
void final_transfer_range_(
|
void final_transfer_range_(
|
||||||
Index& x,
|
Index& x,
|
||||||
|
@ -238,11 +238,9 @@ protected:
|
|||||||
typedef typename call_traits<
|
typedef typename call_traits<
|
||||||
key_type>::param_type key_param_type;
|
key_type>::param_type key_param_type;
|
||||||
|
|
||||||
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
/* needed to avoid commas in some macros */
|
||||||
* expansion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef std::pair<iterator,bool> emplace_return_type;
|
typedef std::pair<iterator,bool> pair_return_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -305,7 +303,7 @@ public:
|
|||||||
/* modifiers */
|
/* modifiers */
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||||
emplace_return_type,emplace,emplace_impl)
|
pair_return_type,emplace,emplace_impl)
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||||
iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
||||||
@ -540,17 +538,69 @@ public:
|
|||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||||
merge(Index& x)
|
merge(Index& x)
|
||||||
{
|
{
|
||||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
merge(x,x.begin(),x.end());
|
||||||
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
|
||||||
if(x.end().get_node()!=this->header()){ /* different containers */
|
|
||||||
this->final_transfer_range_(x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||||
merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
|
merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||||
|
ordered_index_impl,Index,pair_return_type)
|
||||||
|
merge(Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
|
{
|
||||||
|
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_ORD_INDEX_CHECK_INVARIANT;
|
||||||
|
if(x.end().get_node()==this->header()){ /* same container */
|
||||||
|
return std::pair<iterator,bool>(
|
||||||
|
make_iterator(static_cast<final_node_type*>(i.get_node())),true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
std::pair<final_node_type*,bool> p=this->final_transfer_(
|
||||||
|
x,static_cast<final_node_type*>(i.get_node()));
|
||||||
|
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||||
|
ordered_index_impl,Index,pair_return_type)
|
||||||
|
merge(BOOST_RV_REF(Index) x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
|
{
|
||||||
|
return merge(static_cast<Index&>(x),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||||
|
merge(
|
||||||
|
Index& x,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||||
|
{
|
||||||
|
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_ORD_INDEX_CHECK_INVARIANT;
|
||||||
|
if(x.end().get_node()!=this->header()){ /* different containers */
|
||||||
|
this->final_transfer_range_(x,first,last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(ordered_index_impl,Index,void)
|
||||||
|
merge(
|
||||||
|
BOOST_RV_REF(Index) x,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||||
|
{
|
||||||
|
merge(static_cast<Index&>(x),first,last);
|
||||||
|
}
|
||||||
|
|
||||||
/* observers */
|
/* observers */
|
||||||
|
|
||||||
key_from_value key_extractor()const{return key;}
|
key_from_value key_extractor()const{return key;}
|
||||||
|
@ -206,11 +206,9 @@ private:
|
|||||||
typedef typename call_traits<
|
typedef typename call_traits<
|
||||||
key_type>::param_type key_param_type;
|
key_type>::param_type key_param_type;
|
||||||
|
|
||||||
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
/* needed to avoid commas in some macros */
|
||||||
* expansion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef std::pair<iterator,bool> emplace_return_type;
|
typedef std::pair<iterator,bool> pair_return_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -280,7 +278,7 @@ public:
|
|||||||
/* modifiers */
|
/* modifiers */
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||||
emplace_return_type,emplace,emplace_impl)
|
pair_return_type,emplace,emplace_impl)
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||||
iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
||||||
@ -519,17 +517,67 @@ public:
|
|||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||||
merge(Index& x)
|
merge(Index& x)
|
||||||
{
|
{
|
||||||
BOOST_MULTI_INDEX_CHECK_EQUAL_ALLOCATORS(*this,x);
|
merge(x,x.begin(),x.end());
|
||||||
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
|
|
||||||
if(x.end().get_node()!=this->header()){ /* different containers */
|
|
||||||
this->final_transfer_range_(x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||||
merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
|
merge(BOOST_RV_REF(Index) x){merge(static_cast<Index&>(x));}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,pair_return_type)
|
||||||
|
merge(Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
|
{
|
||||||
|
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_HASHED_INDEX_CHECK_INVARIANT;
|
||||||
|
if(x.end().get_node()==this->header()){ /* same container */
|
||||||
|
return std::pair<iterator,bool>(
|
||||||
|
make_iterator(static_cast<final_node_type*>(i.get_node())),true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
std::pair<final_node_type*,bool> p=this->final_transfer_(
|
||||||
|
x,static_cast<final_node_type*>(i.get_node()));
|
||||||
|
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,pair_return_type)
|
||||||
|
merge(BOOST_RV_REF(Index) x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
|
{
|
||||||
|
return merge(static_cast<Index&>(x),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||||
|
merge(
|
||||||
|
Index& x,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||||
|
{
|
||||||
|
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_HASHED_INDEX_CHECK_INVARIANT;
|
||||||
|
if(x.end().get_node()!=this->header()){ /* different containers */
|
||||||
|
this->final_transfer_range_(x,first,last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(hashed_index,Index,void)
|
||||||
|
merge(
|
||||||
|
BOOST_RV_REF(Index) x,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator first,
|
||||||
|
BOOST_DEDUCED_TYPENAME Index::iterator last)
|
||||||
|
{
|
||||||
|
merge(static_cast<Index&>(x),first,last);
|
||||||
|
}
|
||||||
|
|
||||||
/* observers */
|
/* observers */
|
||||||
|
|
||||||
key_from_value key_extractor()const{return key;}
|
key_from_value key_extractor()const{return key;}
|
||||||
|
@ -184,7 +184,7 @@ private:
|
|||||||
|
|
||||||
/* needed to avoid commas in some macros */
|
/* needed to avoid commas in some macros */
|
||||||
|
|
||||||
typedef std::pair<iterator,bool> insertion_return_type;
|
typedef std::pair<iterator,bool> pair_return_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ public:
|
|||||||
/* modifiers */
|
/* modifiers */
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||||
insertion_return_type,emplace_front,emplace_front_impl)
|
pair_return_type,emplace_front,emplace_front_impl)
|
||||||
|
|
||||||
std::pair<iterator,bool> push_front(const value_type& x)
|
std::pair<iterator,bool> push_front(const value_type& x)
|
||||||
{return insert(begin(),x);}
|
{return insert(begin(),x);}
|
||||||
@ -339,7 +339,7 @@ public:
|
|||||||
void pop_front(){erase(begin());}
|
void pop_front(){erase(begin());}
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||||
insertion_return_type,emplace_back,emplace_back_impl)
|
pair_return_type,emplace_back,emplace_back_impl)
|
||||||
|
|
||||||
std::pair<iterator,bool> push_back(const value_type& x)
|
std::pair<iterator,bool> push_back(const value_type& x)
|
||||||
{return insert(end(),x);}
|
{return insert(end(),x);}
|
||||||
@ -348,7 +348,7 @@ public:
|
|||||||
void pop_back(){erase(--end());}
|
void pop_back(){erase(--end());}
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||||
insertion_return_type,emplace,emplace_impl,iterator,position)
|
pair_return_type,emplace,emplace_impl,iterator,position)
|
||||||
|
|
||||||
std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
||||||
{
|
{
|
||||||
@ -557,7 +557,7 @@ public:
|
|||||||
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||||
random_access_index,Index,insertion_return_type)
|
random_access_index,Index,pair_return_type)
|
||||||
splice(
|
splice(
|
||||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
{
|
{
|
||||||
@ -583,7 +583,7 @@ public:
|
|||||||
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||||
random_access_index,Index,insertion_return_type)
|
random_access_index,Index,pair_return_type)
|
||||||
splice(
|
splice(
|
||||||
iterator position,BOOST_RV_REF(Index) x,
|
iterator position,BOOST_RV_REF(Index) x,
|
||||||
BOOST_DEDUCED_TYPENAME Index::iterator i)
|
BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
@ -1121,20 +1121,7 @@ private:
|
|||||||
/* backwards compatibility with old, non-transfer-based splice */
|
/* backwards compatibility with old, non-transfer-based splice */
|
||||||
|
|
||||||
std::pair<iterator,bool> p=insert(position,*i);
|
std::pair<iterator,bool> p=insert(position,*i);
|
||||||
if(p.second){
|
if(p.second)x.erase(i);
|
||||||
|
|
||||||
#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
|
|
||||||
}
|
|
||||||
return std::pair<final_node_type*,bool>(
|
return std::pair<final_node_type*,bool>(
|
||||||
static_cast<final_node_type*>(p.first.get_node()),p.second);
|
static_cast<final_node_type*>(p.first.get_node()),p.second);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ private:
|
|||||||
|
|
||||||
/* needed to avoid commas in some macros */
|
/* needed to avoid commas in some macros */
|
||||||
|
|
||||||
typedef std::pair<iterator,bool> insertion_return_type;
|
typedef std::pair<iterator,bool> pair_return_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -292,7 +292,7 @@ public:
|
|||||||
/* modifiers */
|
/* modifiers */
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||||
insertion_return_type,emplace_front,emplace_front_impl)
|
pair_return_type,emplace_front,emplace_front_impl)
|
||||||
|
|
||||||
std::pair<iterator,bool> push_front(const value_type& x)
|
std::pair<iterator,bool> push_front(const value_type& x)
|
||||||
{return insert(begin(),x);}
|
{return insert(begin(),x);}
|
||||||
@ -301,7 +301,7 @@ public:
|
|||||||
void pop_front(){erase(begin());}
|
void pop_front(){erase(begin());}
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
||||||
insertion_return_type,emplace_back,emplace_back_impl)
|
pair_return_type,emplace_back,emplace_back_impl)
|
||||||
|
|
||||||
std::pair<iterator,bool> push_back(const value_type& x)
|
std::pair<iterator,bool> push_back(const value_type& x)
|
||||||
{return insert(end(),x);}
|
{return insert(end(),x);}
|
||||||
@ -310,7 +310,7 @@ public:
|
|||||||
void pop_back(){erase(--end());}
|
void pop_back(){erase(--end());}
|
||||||
|
|
||||||
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
||||||
insertion_return_type,emplace,emplace_impl,iterator,position)
|
pair_return_type,emplace,emplace_impl,iterator,position)
|
||||||
|
|
||||||
std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
||||||
{
|
{
|
||||||
@ -508,7 +508,7 @@ public:
|
|||||||
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||||
sequenced_index,Index,insertion_return_type)
|
sequenced_index,Index,pair_return_type)
|
||||||
splice(
|
splice(
|
||||||
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
iterator position,Index& x,BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
{
|
{
|
||||||
@ -534,7 +534,7 @@ public:
|
|||||||
|
|
||||||
template<typename Index>
|
template<typename Index>
|
||||||
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
BOOST_MULTI_INDEX_ENABLE_IF_MERGEABLE(
|
||||||
sequenced_index,Index,insertion_return_type)
|
sequenced_index,Index,pair_return_type)
|
||||||
splice(
|
splice(
|
||||||
iterator position,BOOST_RV_REF(Index) x,
|
iterator position,BOOST_RV_REF(Index) x,
|
||||||
BOOST_DEDUCED_TYPENAME Index::iterator i)
|
BOOST_DEDUCED_TYPENAME Index::iterator i)
|
||||||
@ -1034,20 +1034,7 @@ private:
|
|||||||
/* backwards compatibility with old, non-transfer-based splice */
|
/* backwards compatibility with old, non-transfer-based splice */
|
||||||
|
|
||||||
std::pair<iterator,bool> p=insert(position,*i);
|
std::pair<iterator,bool> p=insert(position,*i);
|
||||||
if(p.second){
|
if(p.second)x.erase(i);
|
||||||
|
|
||||||
#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
|
|
||||||
}
|
|
||||||
return std::pair<final_node_type*,bool>(
|
return std::pair<final_node_type*,bool>(
|
||||||
static_cast<final_node_type*>(p.first.get_node()),p.second);
|
static_cast<final_node_type*>(p.first.get_node()),p.second);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <boost/type_traits/integral_constant.hpp>
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <iterator>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "count_allocator.hpp"
|
#include "count_allocator.hpp"
|
||||||
@ -454,6 +455,44 @@ void merge(
|
|||||||
dst.splice(dst.end(),final_forward<Src>(src));
|
dst.splice(dst.end(),final_forward<Src>(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
std::pair<typename Dst::iterator,bool> merge(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator i,
|
||||||
|
typename enable_if_key_based<Dst>::type=0)
|
||||||
|
{
|
||||||
|
return dst.merge(final_forward<Src>(src),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
std::pair<typename Dst::iterator,bool> merge(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator i,
|
||||||
|
typename enable_if_not_key_based<Dst>::type=0)
|
||||||
|
{
|
||||||
|
return dst.splice(dst.end(),final_forward<Src>(src),i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
void merge(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator first,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator last,
|
||||||
|
typename enable_if_key_based<Dst>::type=0)
|
||||||
|
{
|
||||||
|
dst.merge(final_forward<Src>(src),first,last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
void merge(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator first,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator last,
|
||||||
|
typename enable_if_not_key_based<Dst>::type=0)
|
||||||
|
{
|
||||||
|
dst.splice(dst.end(),final_forward<Src>(src),first,last);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Dst,typename Src>
|
template<typename Dst,typename Src>
|
||||||
void test_merge_same(Dst& dst,BOOST_FWD_REF(Src) src)
|
void test_merge_same(Dst& dst,BOOST_FWD_REF(Src) src)
|
||||||
{
|
{
|
||||||
@ -480,27 +519,160 @@ void test_merge_different(Dst& dst,BOOST_FWD_REF(Src) src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
merge(dst,boost::forward<Src>(src));
|
merge(dst,boost::forward<Src>(src));
|
||||||
BOOST_TEST(dst.size()+src.size()==n+m);
|
BOOST_TEST(dst.size()>=n && m>=src.size() && dst.size()-n==m-src.size());
|
||||||
for(std::size_t i=0;i<v.size();++i){
|
for(std::size_t i=0;i<v.size();++i){
|
||||||
BOOST_TEST(&*(v[i].first)==v[i].second);
|
BOOST_TEST(&*(v[i].first)==v[i].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
void test_merge_same(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator i,
|
||||||
|
bool key_based=is_key_based<Dst>::value)
|
||||||
|
{
|
||||||
|
typedef typename Dst::iterator dst_iterator;
|
||||||
|
|
||||||
|
std::size_t n=dst.size();
|
||||||
|
|
||||||
|
std::pair<dst_iterator,bool> p=merge(dst,boost::forward<Src>(src),i);
|
||||||
|
BOOST_TEST(dst.size()==n);
|
||||||
|
BOOST_TEST(src.size()==n);
|
||||||
|
BOOST_TEST(&*(p.first)==&*i && p.second);
|
||||||
|
if(!key_based)BOOST_TEST(boost::next(p.first)==dst.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
void test_merge_different(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator i,
|
||||||
|
bool key_based=is_key_based<Dst>::value)
|
||||||
|
{
|
||||||
|
typedef typename Dst::iterator dst_iterator;
|
||||||
|
|
||||||
|
std::size_t n=dst.size(),m=src.size();
|
||||||
|
const typename Dst::value_type* pi=&*i;
|
||||||
|
|
||||||
|
std::pair<dst_iterator,bool> p=merge(dst,boost::forward<Src>(src),i);
|
||||||
|
BOOST_TEST(dst.size()+src.size()==n+m);
|
||||||
|
BOOST_TEST(p.second?
|
||||||
|
&*(p.first)==pi:
|
||||||
|
&*(p.first)!=pi && *(p.first)==*i);
|
||||||
|
if(!key_based)BOOST_TEST(!p.second || boost::next(p.first)==dst.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
void test_merge_same(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator first,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator last,
|
||||||
|
bool key_based=is_key_based<Dst>::value)
|
||||||
|
{
|
||||||
|
typedef typename Dst::iterator dst_iterator;
|
||||||
|
typedef typename boost::remove_reference<Src>::
|
||||||
|
type::iterator src_iterator;
|
||||||
|
typedef typename boost::remove_reference<Src>::
|
||||||
|
type::value_type src_value_type;
|
||||||
|
|
||||||
|
std::size_t n=dst.size(),d=std::distance(first,last);
|
||||||
|
std::vector<const src_value_type*> v;
|
||||||
|
for(src_iterator it=first;it!=last;++it)v.push_back(&*it);
|
||||||
|
|
||||||
|
merge(dst,boost::forward<Src>(src),first,last);
|
||||||
|
BOOST_TEST(dst.size()==n);
|
||||||
|
BOOST_TEST(src.size()==n);
|
||||||
|
if(!key_based){
|
||||||
|
dst_iterator it=boost::next(dst.begin(),dst.size()-d);
|
||||||
|
for(std::size_t i=0;i<d;++i){
|
||||||
|
BOOST_TEST(&*it++==v[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
src_iterator it=first;
|
||||||
|
for(std::size_t i=0;i<d;++i){
|
||||||
|
BOOST_TEST(&*it++==v[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator,typename Value>
|
||||||
|
bool find_address(Iterator first,Iterator last,const Value* x)
|
||||||
|
{
|
||||||
|
while(first!=last)if(&*first++==x)return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Dst,typename Src>
|
||||||
|
void test_merge_different(
|
||||||
|
Dst& dst,BOOST_FWD_REF(Src) src,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator first,
|
||||||
|
typename boost::remove_reference<Src>::type::iterator last,
|
||||||
|
bool key_based=is_key_based<Dst>::value)
|
||||||
|
{
|
||||||
|
typedef typename Dst::iterator dst_iterator;
|
||||||
|
typedef typename boost::remove_reference<Src>::
|
||||||
|
type::iterator src_iterator;
|
||||||
|
typedef typename boost::remove_reference<Src>::
|
||||||
|
type::value_type src_value_type;
|
||||||
|
|
||||||
|
std::size_t n=dst.size(),
|
||||||
|
m=src.size(),
|
||||||
|
d=std::distance(first,last);
|
||||||
|
std::vector<const src_value_type*> v;
|
||||||
|
for(src_iterator it=first;it!=last;++it)v.push_back(&*it);
|
||||||
|
|
||||||
|
merge(dst,boost::forward<Src>(src),first,last);
|
||||||
|
BOOST_TEST(dst.size()>=n && m>=src.size() && dst.size()-n==m-src.size());
|
||||||
|
if(!key_based){
|
||||||
|
for(dst_iterator it=boost::next(dst.begin(),n);it!=dst.end();++it){
|
||||||
|
BOOST_TEST(std::find(v.begin(),v.end(),&*it)!=v.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(std::size_t i=0;i<v.size();++i){
|
||||||
|
BOOST_TEST(
|
||||||
|
find_address(src.begin(),src.end(),v[i])||
|
||||||
|
find_address(dst.begin(),dst.end(),v[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<int N,int M,typename Dst>
|
template<int N,int M,typename Dst>
|
||||||
void test_merge_same(Dst& dst)
|
void test_merge_same(Dst& dst)
|
||||||
{
|
{
|
||||||
Dst dst1=dst;
|
const Dst dst1=dst;
|
||||||
test_merge_same(
|
{
|
||||||
dst1.template get<N>(),dst1.template get<M>());
|
Dst dst2=dst1;
|
||||||
test_merge_same(
|
test_merge_same(
|
||||||
dst1.template get<N>(),boost::move(dst1.template get<M>()));
|
dst2.template get<N>(),dst2.template get<M>());
|
||||||
|
test_merge_same(
|
||||||
|
dst2.template get<N>(),boost::move(dst2.template get<M>()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Dst dst2=dst1;
|
||||||
|
test_merge_same(
|
||||||
|
dst2.template get<N>(),dst2.template get<M>(),
|
||||||
|
boost::next(dst2.template get<M>().begin(),dst2.size()/2));
|
||||||
|
test_merge_same(
|
||||||
|
dst2.template get<N>(),boost::move(dst2.template get<M>()),
|
||||||
|
boost::next(dst2.template get<M>().begin(),dst2.size()/2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Dst dst2=dst1;
|
||||||
|
test_merge_same(
|
||||||
|
dst2.template get<N>(),dst2.template get<M>(),
|
||||||
|
dst2.template get<M>().begin(),
|
||||||
|
boost::next(dst2.template get<M>().begin(),dst2.size()/2));
|
||||||
|
test_merge_same(
|
||||||
|
dst2.template get<N>(),boost::move(dst2.template get<M>()),
|
||||||
|
dst2.template get<M>().begin(),
|
||||||
|
boost::next(dst2.template get<M>().begin(),dst2.size()/2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int N,int M,typename Dst,typename Src>
|
template<int N,int M,typename Dst,typename Src>
|
||||||
void test_merge_different(Dst& dst,Src& src)
|
void test_merge_different(Dst& dst,Src& src)
|
||||||
{
|
{
|
||||||
Dst dst1=dst;
|
const Dst dst1=dst;
|
||||||
Src src1=src;
|
const Src src1=src;
|
||||||
{
|
{
|
||||||
Dst dst2=dst1;
|
Dst dst2=dst1;
|
||||||
Src src2=src1;
|
Src src2=src1;
|
||||||
@ -513,6 +685,36 @@ void test_merge_different(Dst& dst,Src& src)
|
|||||||
test_merge_different(
|
test_merge_different(
|
||||||
dst2.template get<N>(),boost::move(src2.template get<M>()));
|
dst2.template get<N>(),boost::move(src2.template get<M>()));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
Dst dst2=dst1;
|
||||||
|
Src src2=src1;
|
||||||
|
test_merge_different(
|
||||||
|
dst2.template get<N>(),src2.template get<M>(),
|
||||||
|
boost::next(src2.template get<M>().begin(),src2.size()/2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Dst dst2=dst1;
|
||||||
|
Src src2=src1;
|
||||||
|
test_merge_different(
|
||||||
|
dst2.template get<N>(),boost::move(src2.template get<M>()),
|
||||||
|
boost::next(src2.template get<M>().begin(),src2.size()/2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Dst dst2=dst1;
|
||||||
|
Src src2=src1;
|
||||||
|
test_merge_different(
|
||||||
|
dst2.template get<N>(),src2.template get<M>(),
|
||||||
|
src2.template get<M>().begin(),
|
||||||
|
boost::next(src2.template get<M>().begin(),src2.size()/2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Dst dst2=dst1;
|
||||||
|
Src src2=src1;
|
||||||
|
test_merge_different(
|
||||||
|
dst2.template get<N>(),boost::move(src2.template get<M>()),
|
||||||
|
src2.template get<M>().begin(),
|
||||||
|
boost::next(src2.template get<M>().begin(),src2.size()/2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int N,int M,typename Dst,typename Src>
|
template<int N,int M,typename Dst,typename Src>
|
||||||
@ -528,6 +730,14 @@ void test_merge(Dst& dst,Dst& src)
|
|||||||
else test_merge_different<N,M>(dst,src);
|
else test_merge_different<N,M>(dst,src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct another_int_hash
|
||||||
|
{
|
||||||
|
std::size_t operator()(int x)const
|
||||||
|
{
|
||||||
|
return boost::hash<int>()(x)*2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void test_merge()
|
void test_merge()
|
||||||
{
|
{
|
||||||
typedef multi_index_container<
|
typedef multi_index_container<
|
||||||
@ -544,8 +754,14 @@ void test_merge()
|
|||||||
typedef multi_index_container<
|
typedef multi_index_container<
|
||||||
int,
|
int,
|
||||||
indexed_by<
|
indexed_by<
|
||||||
ordered_unique<identity<int> >,
|
ordered_unique<
|
||||||
hashed_unique<identity<int> >,
|
identity<int>,
|
||||||
|
std::greater<int>
|
||||||
|
>,
|
||||||
|
hashed_unique<
|
||||||
|
identity<int>,
|
||||||
|
another_int_hash
|
||||||
|
>,
|
||||||
random_access<>,
|
random_access<>,
|
||||||
sequenced<>,
|
sequenced<>,
|
||||||
ranked_unique<
|
ranked_unique<
|
||||||
@ -557,7 +773,7 @@ void test_merge()
|
|||||||
|
|
||||||
container1 c1;
|
container1 c1;
|
||||||
container2 c2;
|
container2 c2;
|
||||||
for(int i=0;i<5;++i){
|
for(int i=0;i<10;++i){
|
||||||
c1.insert(i);
|
c1.insert(i);
|
||||||
c2.insert(2*i);
|
c2.insert(2*i);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user