Fix sg_[multi]set not working when merging from a set with a different comparison.

Update testcase to test merging from a different comparison.
This commit is contained in:
Ion Gaztañaga
2016-09-01 18:55:56 +02:00
parent b2498a0da4
commit 36fb49abc9
6 changed files with 46 additions and 11 deletions

View File

@@ -146,7 +146,7 @@ class generic_hook
//value_traits for this hook. //value_traits for this hook.
, public hook_tags_definer , public hook_tags_definer
< generic_hook<Algo, NodeTraits, Tag, LinkMode, BaseHookType> < generic_hook<Algo, NodeTraits, Tag, LinkMode, BaseHookType>
, detail::is_same<Tag, dft_tag>::value*BaseHookType> , detail::is_same<Tag, dft_tag>::value ? BaseHookType : NoBaseHookId>
/// @endcond /// @endcond
{ {
/// @cond /// @cond

View File

@@ -156,6 +156,9 @@ struct alpha_holder
multiply_by_alpha_t get_multiply_by_alpha_t() const multiply_by_alpha_t get_multiply_by_alpha_t() const
{ return multiply_by_alpha_t(alpha_); } { return multiply_by_alpha_t(alpha_); }
SizeType &get_max_tree_size()
{ return max_tree_size_; }
protected: protected:
float alpha_; float alpha_;
float inv_minus_logalpha_; float inv_minus_logalpha_;
@@ -189,6 +192,10 @@ struct alpha_holder<false, SizeType>
multiply_by_alpha_t get_multiply_by_alpha_t() const multiply_by_alpha_t get_multiply_by_alpha_t() const
{ return multiply_by_alpha_t(); } { return multiply_by_alpha_t(); }
SizeType &get_max_tree_size()
{ return max_tree_size_; }
protected:
SizeType max_tree_size_; SizeType max_tree_size_;
}; };
@@ -714,14 +721,14 @@ class sgtree_impl
it = node_algorithms::next_node(it); it = node_algorithms::next_node(it);
std::size_t max_tree1_size = this->max_tree_size_; std::size_t max_tree1_size = this->max_tree_size_;
std::size_t max_tree2_size = source.max_tree_size_; std::size_t max_tree2_size = source.get_max_tree_size();
if( node_algorithms::transfer_unique if( node_algorithms::transfer_unique
( this->header_ptr(), this->key_node_comp(this->key_comp()), this->size(), max_tree1_size ( this->header_ptr(), this->key_node_comp(this->key_comp()), this->size(), max_tree1_size
, source.header_ptr(), p, source.size(), max_tree2_size , source.header_ptr(), p, source.size(), max_tree2_size
, this->get_h_alpha_func(), this->get_alpha_by_max_size_func()) ){ , this->get_h_alpha_func(), this->get_alpha_by_max_size_func()) ){
this->max_tree_size_ = (size_type)max_tree1_size; this->max_tree_size_ = (size_type)max_tree1_size;
this->sz_traits().increment(); this->sz_traits().increment();
source.max_tree_size_ = (size_type)max_tree2_size; source.get_max_tree_size() = (size_type)max_tree2_size;
source.sz_traits().decrement(); source.sz_traits().decrement();
} }
} }
@@ -744,14 +751,14 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
it = node_algorithms::next_node(it); it = node_algorithms::next_node(it);
std::size_t max_tree1_size = this->max_tree_size_; std::size_t max_tree1_size = this->max_tree_size_;
std::size_t max_tree2_size = source.max_tree_size_; std::size_t max_tree2_size = source.get_max_tree_size();
node_algorithms::transfer_equal node_algorithms::transfer_equal
( this->header_ptr(), this->key_node_comp(this->key_comp()), this->size(), max_tree1_size ( this->header_ptr(), this->key_node_comp(this->key_comp()), this->size(), max_tree1_size
, source.header_ptr(), p, source.size(), max_tree2_size , source.header_ptr(), p, source.size(), max_tree2_size
, this->get_h_alpha_func(), this->get_alpha_by_max_size_func()); , this->get_h_alpha_func(), this->get_alpha_by_max_size_func());
this->max_tree_size_ = (size_type)max_tree1_size; this->max_tree_size_ = (size_type)max_tree1_size;
this->sz_traits().increment(); this->sz_traits().increment();
source.max_tree_size_ = (size_type)max_tree2_size; source.get_max_tree_size() = (size_type)max_tree2_size;
source.sz_traits().decrement(); source.sz_traits().decrement();
} }
} }

View File

@@ -85,6 +85,15 @@ struct BPtr_Value
friend bool operator< (const BPtr_Value &other1, int other2) friend bool operator< (const BPtr_Value &other1, int other2)
{ return other1.value_ < other2; } { return other1.value_ < other2; }
friend bool operator> (const BPtr_Value &other1, const BPtr_Value &other2)
{ return other1.value_ > other2.value_; }
friend bool operator> (int other1, const BPtr_Value &other2)
{ return other1 > other2.value_; }
friend bool operator> (const BPtr_Value &other1, int other2)
{ return other1.value_ > other2; }
friend bool operator== (const BPtr_Value &other1, const BPtr_Value &other2) friend bool operator== (const BPtr_Value &other1, const BPtr_Value &other2)
{ return other1.value_ == other2.value_; } { return other1.value_ == other2.value_; }

View File

@@ -181,11 +181,16 @@ void test_generic_multiset<ContainerDefiner>::test_merge(value_cont_type& values
typedef typename ContainerDefiner::template container typedef typename ContainerDefiner::template container
<>::type multiset_type; <>::type multiset_type;
typedef typename multiset_type::key_of_value key_of_value; typedef typename multiset_type::key_of_value key_of_value;
typedef typename multiset_type::key_type key_type;
typedef typename ContainerDefiner::template container
< compare< std::greater<key_type> > >::type multiset_greater_type;
//original vector: 3, 2, 4, 1, 5, 2 //original vector: 3, 2, 4, 1, 5, 2
//2,3 //2,3
multiset_type testset1 (values.begin(), values.begin() + 2); multiset_type testset1 (values.begin(), values.begin() + 2);
//1, 2, 4, 5 //5, 4, 2, 1
multiset_type testset2; multiset_greater_type testset2;
testset2.insert (values.begin() + 2, values.begin() + 6); testset2.insert (values.begin() + 2, values.begin() + 6);
testset2.merge(testset1); testset2.merge(testset1);
@@ -194,7 +199,7 @@ void test_generic_multiset<ContainerDefiner>::test_merge(value_cont_type& values
BOOST_TEST (testset1.empty()); BOOST_TEST (testset1.empty());
BOOST_TEST (testset2.size() == 6); BOOST_TEST (testset2.size() == 6);
{ int init_values [] = { 1, 2, 2, 3, 4, 5 }; { int init_values [] = { 5, 4, 3, 2, 2, 1 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
value_cont_type cmp_val_cont(1); value_cont_type cmp_val_cont(1);

View File

@@ -263,10 +263,15 @@ void test_generic_set<ContainerDefiner>::test_merge(value_cont_type& values)
{ {
typedef typename ContainerDefiner::template container typedef typename ContainerDefiner::template container
<>::type set_type; <>::type set_type;
typedef typename set_type::key_type key_type;
typedef typename ContainerDefiner::template container
< compare< std::greater<key_type> > >::type set_greater_type;
//2,3 //2,3
set_type testset1 (values.begin(), values.begin() + 2); set_type testset1 (values.begin(), values.begin() + 2);
//1, 2, 4, 5 //5, 4, 2, 1
set_type testset2; set_greater_type testset2;
testset2.insert (values.begin() + 2, values.begin() + 6); testset2.insert (values.begin() + 2, values.begin() + 6);
testset2.merge(testset1); testset2.merge(testset1);
@@ -279,7 +284,7 @@ void test_generic_set<ContainerDefiner>::test_merge(value_cont_type& values)
BOOST_TEST (&*testset1.begin() == &values[1]); BOOST_TEST (&*testset1.begin() == &values[1]);
BOOST_TEST (testset2.size() == 5); BOOST_TEST (testset2.size() == 5);
{ int init_values [] = { 1, 2, 3, 4, 5 }; { int init_values [] = { 5, 4, 3, 2, 1 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); } TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
testset1.merge(testset2); testset1.merge(testset2);

View File

@@ -96,6 +96,9 @@ struct testvalue
bool operator< (const testvalue &other) const bool operator< (const testvalue &other) const
{ return value_ < other.value_; } { return value_ < other.value_; }
bool operator> (const testvalue &other) const
{ return value_ > other.value_; }
bool operator==(const testvalue &other) const bool operator==(const testvalue &other) const
{ return value_ == other.value_; } { return value_ == other.value_; }
@@ -105,9 +108,15 @@ struct testvalue
friend bool operator< (int other1, const testvalue &other2) friend bool operator< (int other1, const testvalue &other2)
{ return other1 < other2.value_.int_; } { return other1 < other2.value_.int_; }
friend bool operator> (int other1, const testvalue &other2)
{ return other1 > other2.value_.int_; }
friend bool operator< (const testvalue &other1, int other2) friend bool operator< (const testvalue &other1, int other2)
{ return other1.value_.int_ < other2; } { return other1.value_.int_ < other2; }
friend bool operator> (const testvalue &other1, int other2)
{ return other1.value_.int_ > other2; }
friend bool operator== (int other1, const testvalue &other2) friend bool operator== (int other1, const testvalue &other2)
{ return other1 == other2.value_.int_; } { return other1 == other2.value_.int_; }