diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index ccd75f4..a6df2e0 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3894,6 +3894,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std * [@https://github.com/boostorg/intrusive/pull/57 GitHub #57: ['UB: comparing unrelated pointers]] * [@https://github.com/boostorg/intrusive/issues/59 GitHub #59: ['Add noexcept support to the library]] * [@https://github.com/boostorg/intrusive/issues/60 GitHub #60: ['Licensing question for math.hpp]] + * [@https://github.com/boostorg/intrusive/issues/63 GitHub #63: ['nop splice removes element]] [endsect] diff --git a/include/boost/intrusive/circular_list_algorithms.hpp b/include/boost/intrusive/circular_list_algorithms.hpp index 1611a20..657f1a7 100644 --- a/include/boost/intrusive/circular_list_algorithms.hpp +++ b/include/boost/intrusive/circular_list_algorithms.hpp @@ -253,7 +253,7 @@ class circular_list_algorithms //! Throws: Nothing. static void transfer(node_ptr p, node_ptr b, node_ptr e) BOOST_NOEXCEPT { - if (b != e) { + if (b != e && p != b && p != e) { node_ptr prev_p(NodeTraits::get_previous(p)); node_ptr prev_b(NodeTraits::get_previous(b)); node_ptr prev_e(NodeTraits::get_previous(e)); diff --git a/test/list_test.cpp b/test/list_test.cpp index 649433e..b5250fe 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -273,7 +273,7 @@ template < class ListType, typename ValueContainer > void test_list< ListType, ValueContainer > ::test_swap(ValueContainer& values) { - { + { //splice between two lists list_type testlist1 (values.begin(), values.begin() + 2); list_type testlist2; testlist2.insert (testlist2.end(), values.begin() + 2, values.begin() + 5); @@ -308,6 +308,41 @@ void test_list< ListType, ValueContainer > BOOST_TEST (testlist1.size() == 1); BOOST_TEST (&testlist1.front() == &values[3]); } + + { //splice in the same list + list_type testlist1 (values.begin(), values.begin() + 5); + + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + //nop 1 + testlist1.splice (testlist1.begin(), testlist1, testlist1.begin(), ++testlist1.begin()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + //nop 2 + testlist1.splice (++testlist1.begin(), testlist1, testlist1.begin(), ++testlist1.begin()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + //nop 3 + testlist1.splice (testlist1.begin(), testlist1, ++testlist1.begin(), ++testlist1.begin()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + testlist1.splice (testlist1.begin(), testlist1, ++testlist1.begin(), ++++testlist1.begin()); + { int init_values [] = { 2, 1, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + testlist1.splice (testlist1.begin(), testlist1, ++testlist1.begin(), ++++++testlist1.begin()); + { int init_values [] = { 1, 3, 2, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + testlist1.splice (++++++++testlist1.begin(), testlist1, testlist1.begin(), ++++testlist1.begin()); + { int init_values [] = { 2, 4, 1, 3, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + } + { list_type testlist1 (values.begin(), values.begin() + 2); list_type testlist2 (values.begin() + 3, values.begin() + 5); diff --git a/test/slist_test.cpp b/test/slist_test.cpp index 0124e1a..a1344af 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -354,6 +354,41 @@ void test_slist< ListType, ValueContainer > { int init_values [] = { 2 }; TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); } } + + { //splice in the same list + list_type testlist1 (values.begin(), values.begin() + 5); + + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + //nop 1 + testlist1.splice_after (testlist1.before_begin(), testlist1, testlist1.before_begin(), ++testlist1.before_begin()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + //nop 2 + testlist1.splice_after (++testlist1.before_begin(), testlist1, testlist1.before_begin(), ++testlist1.before_begin()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + //nop 3 + testlist1.splice_after (testlist1.before_begin(), testlist1, ++testlist1.before_begin(), ++testlist1.before_begin()); + { int init_values [] = { 1, 2, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + testlist1.splice_after (testlist1.before_begin(), testlist1, ++testlist1.before_begin(), ++++testlist1.before_begin()); + { int init_values [] = { 2, 1, 3, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + testlist1.splice_after (testlist1.before_begin(), testlist1, ++testlist1.before_begin(), ++++++testlist1.before_begin()); + { int init_values [] = { 1, 3, 2, 4, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + + testlist1.splice_after (++++++++testlist1.before_begin(), testlist1, testlist1.before_begin(), ++++testlist1.before_begin()); + { int init_values [] = { 2, 4, 1, 3, 5 }; + TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); } + } + { //Now test swap when testlist2 is empty list_type testlist1 (values.begin(), values.begin() + 2); list_type testlist2;