Skip to content

Commit f484b77

Browse files
committed
Fix bug in clone_subtree when updating leftmost and rightmost nodes
1 parent 95863b5 commit f484b77

2 files changed

Lines changed: 36 additions & 4 deletions

File tree

‎include/boost/intrusive/bstree_algorithms.hpp‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,8 +1973,8 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits>
19731973
//Insert left
19741974
NodeTraits::set_parent(insertion_point, temp);
19751975
NodeTraits::set_left (temp, insertion_point);
1976-
//Update leftmost
1977-
if(rightmost == target_sub_root)
1976+
//Update leftmost only if the parent was the current leftmost
1977+
if(leftmost == temp)
19781978
leftmost = insertion_point;
19791979
}
19801980
//Then clone right nodes
@@ -1989,8 +1989,9 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits>
19891989
//Insert right
19901990
NodeTraits::set_parent(insertion_point, temp);
19911991
NodeTraits::set_right (temp, insertion_point);
1992-
//Update rightmost
1993-
rightmost = insertion_point;
1992+
//Update rightmost only if the parent was the current rightmost
1993+
if(rightmost == temp)
1994+
rightmost = insertion_point;
19941995
}
19951996
//If not, go up
19961997
else if(current == source_root){

‎test/generic_assoc_test.hpp‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//
1313
/////////////////////////////////////////////////////////////////////////////
1414
#include <boost/container/vector.hpp> //vector
15+
#include <algorithm> //std::next_permutation
1516
#include <boost/intrusive/detail/config_begin.hpp>
1617
#include "common_functors.hpp"
1718
#include <boost/intrusive/options.hpp>
@@ -428,6 +429,36 @@ void test_generic_assoc<ContainerDefiner>::test_clone(value_cont_type& values)
428429
testset2.clear_and_dispose(test::delete_noexcept_disposer<value_type>());
429430
BOOST_TEST (testset2.empty());
430431
}
432+
{ //In non-balanced trees the shape
433+
//depends on the insertion order, so test all insertion orders
434+
typedef typename ContainerDefiner::template container
435+
<>::type assoc_type;
436+
typedef typename assoc_type::value_type value_type;
437+
438+
const std::size_t NumValues = 5;
439+
value_cont_type vals(NumValues);
440+
std::size_t order[NumValues];
441+
for(std::size_t i = 0; i != NumValues; ++i){
442+
(&vals[i])->value_ = (int)i;
443+
order[i] = i;
444+
}
445+
446+
do{
447+
assoc_type testset1;
448+
for(std::size_t i = 0; i != NumValues; ++i){
449+
testset1.insert(vals[order[i]]);
450+
}
451+
assoc_type testset2;
452+
testset2.clone_from(testset1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
453+
BOOST_TEST (testset2 == testset1);
454+
BOOST_TEST (testset2.size() == NumValues);
455+
BOOST_TEST (*testset2.begin() == *testset1.begin());
456+
BOOST_TEST (*testset2.rbegin() == *testset1.rbegin());
457+
testset2.check();
458+
testset2.clear_and_dispose(test::delete_noexcept_disposer<value_type>());
459+
testset1.clear();
460+
}while(std::next_permutation(order, order + NumValues));
461+
}
431462
}
432463

433464
template<class ContainerDefiner>

0 commit comments

Comments
 (0)