From ed6c8bd87d95eb8be54e133c901a50b5bcbbc288 Mon Sep 17 00:00:00 2001 From: QUvalda Date: Mon, 18 Dec 2017 16:13:45 +0300 Subject: [PATCH] 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 lst1 = { 0, 1, 2, 3 }; slist lst2; lst2.splice(lst2.begin(), lst1, lst1.begin()); expected: lst1 == { 1, 2, 3 } lst2 == { 0 } --- include/boost/container/slist.hpp | 4 ++-- test/slist_test.cpp | 33 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index 8159f11..d721e4f 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -1471,7 +1471,7 @@ class slist //! Note: 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)); } //! Requires: 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 //! Note: 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)); } //! Requires: p must point to an element contained //! by this list. first and last must point to elements contained in list x. diff --git a/test/slist_test.cpp b/test/slist_test.cpp index c07af62..9d0c17e 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -135,6 +135,33 @@ bool test_support_for_initializer_list() return true; } +bool test_for_splice() +{ + { + slist list1; list1.push_front(3); list1.push_front(2); list1.push_front(1); list1.push_front(0); + slist list2; + slist expected1; expected1.push_front(3); expected1.push_front(2); expected1.push_front(0); + slist expected2; expected2.push_front(1); + + list2.splice(list2.begin(), list1, ++list1.begin()); + + if (!(expected1 == list1 && expected2 == list2)) + return false; + } + { + slist list1; list1.push_front(3); list1.push_front(2); list1.push_front(1); list1.push_front(0); + slist list2; + slist expected1; + slist 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 ////////////////////////////////////