Fix splice for slist

The call of the splice method with iterators leads to an infinite loop inside common_slist_algorithms::get_previous_node

slist<int> lst1 = { 0, 1, 2, 3 };
slist<int> lst2;
lst2.splice(lst2.begin(), lst1, lst1.begin());

expected:
lst1 == { 1, 2, 3 }
lst2 == { 0 }
This commit is contained in:
QUvalda
2017-12-18 16:13:45 +03:00
committed by Ion Gaztañaga
parent 2802a1f50d
commit ed6c8bd87d
2 changed files with 35 additions and 2 deletions

View File

@@ -1471,7 +1471,7 @@ class slist
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, slist& x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(this->previous(p), x, this->previous(i)); }
{ this->splice_after(this->previous(p), x, x.previous(i)); }
//! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x.
@@ -1505,7 +1505,7 @@ class slist
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(this->previous(p), x, this->previous(first), this->previous(last)); }
{ this->splice_after(this->previous(p), x, x.previous(first), x.previous(last)); }
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.

View File

@@ -135,6 +135,33 @@ bool test_support_for_initializer_list()
return true;
}
bool test_for_splice()
{
{
slist<int> list1; list1.push_front(3); list1.push_front(2); list1.push_front(1); list1.push_front(0);
slist<int> list2;
slist<int> expected1; expected1.push_front(3); expected1.push_front(2); expected1.push_front(0);
slist<int> expected2; expected2.push_front(1);
list2.splice(list2.begin(), list1, ++list1.begin());
if (!(expected1 == list1 && expected2 == list2))
return false;
}
{
slist<int> list1; list1.push_front(3); list1.push_front(2); list1.push_front(1); list1.push_front(0);
slist<int> list2;
slist<int> expected1;
slist<int> expected2; expected2.push_front(3); expected2.push_front(2); expected2.push_front(1); expected2.push_front(0);
list2.splice(list2.begin(), list1, list1.begin(), list1.end());
if (!(expected1 == list1 && expected2 == list2))
return false;
}
return true;
}
struct boost_container_slist;
namespace boost {
@@ -207,6 +234,12 @@ int main ()
if(!test_support_for_initializer_list())
return 1;
////////////////////////////////////
// Splice testing
////////////////////////////////////
if(!test_for_splice())
return 1;
////////////////////////////////////
// Iterator testing
////////////////////////////////////