From 1692089663b0feffa054f594afe91dc2d5b8416a Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Tue, 16 Mar 2010 01:32:53 +0000 Subject: [PATCH] forward_list.tcc (_Fwd_list_node_base:: _M_transfer_after): Return _Fwd_list_node_base*. 2010-03-15 Paolo Carlini * include/bits/forward_list.tcc (_Fwd_list_node_base:: _M_transfer_after): Return _Fwd_list_node_base*. (forward_list<>::_M_splice_after): Add. (forward_list<>::insert_after(const_iterator, size_type, const _Tp&), insert_after(const_iterator, _InputIterator, _InputIterator), insert_after(const_iterator, initializer_list<>)): Use the above, implement DR 1278 ([Ready] in Pittsburgh). * include/bits/forward_list.h (insert_after(const_iterator, size_type, const _Tp&), insert_after(const_iterator, _InputIterator, _InputIterator), insert_after(const_iterator, initializer_list<>)): Only declare. * testsuite/23_containers/forward_list/modifiers/2.cc: Adjust. * testsuite/23_containers/forward_list/requirements/dr438/ assign_neg.cc: Adjust dg-error line number. * testsuite/23_containers/forward_list/requirements/dr438/ insert_neg.cc: Likewise. * testsuite/23_containers/forward_list/requirements/dr438/ constructor_1_neg.cc: Likewise. * testsuite/23_containers/forward_list/requirements/dr438/ constructor_2_neg.cc: Likewise. From-SVN: r157471 --- libstdc++-v3/ChangeLog | 23 +++++++ libstdc++-v3/include/bits/forward_list.h | 69 +++++++++---------- libstdc++-v3/include/bits/forward_list.tcc | 57 ++++++++++++--- .../23_containers/forward_list/modifiers/2.cc | 66 ++++++++++-------- .../requirements/dr438/assign_neg.cc | 2 +- .../requirements/dr438/constructor_1_neg.cc | 2 +- .../requirements/dr438/constructor_2_neg.cc | 2 +- .../requirements/dr438/insert_neg.cc | 2 +- 8 files changed, 147 insertions(+), 76 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1a4e99a6dc5..24543b02edb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2010-03-15 Paolo Carlini + + * include/bits/forward_list.tcc (_Fwd_list_node_base:: + _M_transfer_after): Return _Fwd_list_node_base*. + (forward_list<>::_M_splice_after): Add. + (forward_list<>::insert_after(const_iterator, size_type, const _Tp&), + insert_after(const_iterator, _InputIterator, _InputIterator), + insert_after(const_iterator, initializer_list<>)): Use the above, + implement DR 1278 ([Ready] in Pittsburgh). + * include/bits/forward_list.h (insert_after(const_iterator, + size_type, const _Tp&), insert_after(const_iterator, _InputIterator, + _InputIterator), insert_after(const_iterator, initializer_list<>)): + Only declare. + * testsuite/23_containers/forward_list/modifiers/2.cc: Adjust. + * testsuite/23_containers/forward_list/requirements/dr438/ + assign_neg.cc: Adjust dg-error line number. + * testsuite/23_containers/forward_list/requirements/dr438/ + insert_neg.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + constructor_2_neg.cc: Likewise. + 2010-03-15 Paolo Carlini * testsuite/23_containers/forward_list/requirements/dr438/ diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 1dcbefd2215..57b7836a324 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -51,28 +51,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std) swap(_Fwd_list_node_base& __x, _Fwd_list_node_base& __y) { std::swap(__x._M_next, __y._M_next); } - void - _M_transfer_after(_Fwd_list_node_base* __bbegin) + _Fwd_list_node_base* + _M_transfer_after(_Fwd_list_node_base* __begin) { - _Fwd_list_node_base* __bend = __bbegin; - while (__bend && __bend->_M_next) - __bend = __bend->_M_next; - _M_transfer_after(__bbegin, __bend); + _Fwd_list_node_base* __end = __begin; + while (__end && __end->_M_next) + __end = __end->_M_next; + return _M_transfer_after(__begin, __end); } - void - _M_transfer_after(_Fwd_list_node_base* __bbegin, - _Fwd_list_node_base* __bend) + _Fwd_list_node_base* + _M_transfer_after(_Fwd_list_node_base* __begin, + _Fwd_list_node_base* __end) { - _Fwd_list_node_base* __keep = __bbegin->_M_next; - if (__bend) + _Fwd_list_node_base* __keep = __begin->_M_next; + if (__end) { - __bbegin->_M_next = __bend->_M_next; - __bend->_M_next = _M_next; + __begin->_M_next = __end->_M_next; + __end->_M_next = _M_next; } else - __bbegin->_M_next = 0; + __begin->_M_next = 0; _M_next = __keep; + return __end; } void @@ -865,7 +866,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @param pos An iterator into the %forward_list. * @param n Number of elements to be inserted. * @param val Data to be inserted. - * @return pos. + * @return An iterator pointing to the last inserted copy of + * @a val or @a pos if @a n == 0. * * This function will insert a specified number of copies of the * given data after the location specified by @a pos. @@ -874,19 +876,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * does not invalidate iterators and references. */ iterator - insert_after(const_iterator __pos, size_type __n, const _Tp& __val) - { - forward_list __tmp(__n, __val, this->_M_get_Node_allocator()); - splice_after(__pos, std::move(__tmp)); - return iterator(const_cast<_Node_base*>(__pos._M_node)); - } + insert_after(const_iterator __pos, size_type __n, const _Tp& __val); /** * @brief Inserts a range into the %forward_list. * @param position An iterator into the %forward_list. * @param first An input iterator. * @param last An input iterator. - * @return pos. + * @return An iterator pointing to the last inserted element or + * @a pos if @a first == @a last. * * This function will insert copies of the data in the range [@a * first,@a last) into the %forward_list after the location specified @@ -898,19 +896,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template iterator insert_after(const_iterator __pos, - _InputIterator __first, _InputIterator __last) - { - forward_list __tmp(__first, __last, this->_M_get_Node_allocator()); - splice_after(__pos, std::move(__tmp)); - return iterator(const_cast<_Node_base*>(__pos._M_node)); - } + _InputIterator __first, _InputIterator __last); /** * @brief Inserts the contents of an initializer_list into * %forward_list after the specified iterator. * @param pos An iterator into the %forward_list. * @param il An initializer_list of value_type. - * @return pos. + * @return An iterator pointing to the last inserted element + * or @a pos if @a il is empty. * * This function will insert copies of the data in the * initializer_list @a il into the %forward_list before the location @@ -920,12 +914,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * does not invalidate iterators and references. */ iterator - insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) - { - forward_list __tmp(__il, this->_M_get_Node_allocator()); - splice_after(__pos, std::move(__tmp)); - return iterator(const_cast<_Node_base*>(__pos._M_node)); - } + insert_after(const_iterator __pos, std::initializer_list<_Tp> __il); /** * @brief Removes the element pointed to by the iterator following @@ -1037,7 +1026,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Requires this != @a x. */ void - splice_after(const_iterator __pos, forward_list&& __list); + splice_after(const_iterator __pos, forward_list&& __list) + { + if (!__list.empty()) + _M_splice_after(__pos, std::move(__list)); + } /** * @brief Insert element from another %forward_list. @@ -1210,6 +1203,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) // turns out to be the same thing. void _M_fill_initialize(size_type __n, const value_type& __value); + + // Called by splice_after and insert_after. + iterator + _M_splice_after(const_iterator __pos, forward_list&& __list); }; /** diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc index e3af42e12dd..7468a90d1af 100644 --- a/libstdc++-v3/include/bits/forward_list.tcc +++ b/libstdc++-v3/include/bits/forward_list.tcc @@ -203,22 +203,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } template - void + typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>:: - splice_after(const_iterator __pos, forward_list&& __list) + _M_splice_after(const_iterator __pos, forward_list&& __list) { - if (!__list.empty() && &__list != this) - { - _Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node); - const_iterator __before = __list.cbefore_begin(); - __tmp->_M_transfer_after(const_cast<_Node_base*>(__before._M_node)); - } + _Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node); + iterator __before = __list.before_begin(); + return iterator(__tmp->_M_transfer_after(__before._M_node)); } template void forward_list<_Tp, _Alloc>:: - splice_after(const_iterator __pos, forward_list&& __list, + splice_after(const_iterator __pos, forward_list&&, const_iterator __before, const_iterator __last) { _Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node); @@ -226,6 +223,48 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const_cast<_Node_base*>(__last._M_node)); } + template + typename forward_list<_Tp, _Alloc>::iterator + forward_list<_Tp, _Alloc>:: + insert_after(const_iterator __pos, size_type __n, const _Tp& __val) + { + if (__n) + { + forward_list __tmp(__n, __val, this->_M_get_Node_allocator()); + return _M_splice_after(__pos, std::move(__tmp)); + } + else + return iterator(const_cast<_Node_base*>(__pos._M_node)); + } + + template + template + typename forward_list<_Tp, _Alloc>::iterator + forward_list<_Tp, _Alloc>:: + insert_after(const_iterator __pos, + _InputIterator __first, _InputIterator __last) + { + forward_list __tmp(__first, __last, this->_M_get_Node_allocator()); + if (!__tmp.empty()) + return _M_splice_after(__pos, std::move(__tmp)); + else + return iterator(const_cast<_Node_base*>(__pos._M_node)); + } + + template + typename forward_list<_Tp, _Alloc>::iterator + forward_list<_Tp, _Alloc>:: + insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) + { + if (__il.size()) + { + forward_list __tmp(__il, this->_M_get_Node_allocator()); + return _M_splice_after(__pos, std::move(__tmp)); + } + else + return iterator(const_cast<_Node_base*>(__pos._M_node)); + } + template void forward_list<_Tp, _Alloc>:: diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc index 92678f39d69..b6ae3f3795c 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/2.cc @@ -36,8 +36,8 @@ test01() std::forward_list::iterator ret = fl.insert_after(fl.before_begin(), 42); - VERIFY(ret == fl.begin()); - VERIFY(fl.front() == 42); + VERIFY( ret == fl.begin() ); + VERIFY( fl.front() == 42 ); } // This test verifies the following: @@ -48,21 +48,24 @@ test02() std::forward_list::const_iterator pos = fl.cbegin(); ++pos; - VERIFY(*pos == 1); + VERIFY( *pos == 1 ); - // Note: Calling l.insert_after(pos, 5, 42); without the long five - // gets resolved to the iterator range version and fails to compile! - std::forward_list::iterator ret = fl.insert_after(pos, 5, 42); - VERIFY(ret == pos); - VERIFY(*pos == 1); + std::forward_list::iterator ret = fl.insert_after(pos, 0, 42); + VERIFY( ret == pos ); + + ret = fl.insert_after(pos, 5, 42); + VERIFY( *pos == 1 ); ++pos; - VERIFY(*pos == 42); + VERIFY( *pos == 42 ); ++pos; ++pos; ++pos; ++pos; - VERIFY(*pos == 42); + VERIFY( *pos == 42 ); + VERIFY( ret == pos ); + ++pos; + VERIFY( *pos == 2 ); } // This test verifies the following: @@ -73,19 +76,22 @@ test03() std::forward_list::const_iterator pos = fl.cbegin(); ++pos; - VERIFY(*pos == 1); + VERIFY( *pos == 1 ); int i[3] = {666, 777, 888}; - std::forward_list::iterator ret = fl.insert_after(pos, i, i + 3); - VERIFY(ret == pos); - VERIFY(*pos == 1); + std::forward_list::iterator ret = fl.insert_after(pos, i, i); + VERIFY( ret == pos ); + + ret = fl.insert_after(pos, i, i + 3); + VERIFY( *pos == 1 ); ++pos; ++pos; ++pos; - VERIFY(*pos == 888); + VERIFY( *pos == 888 ); + VERIFY( ret == pos ); ++pos; - VERIFY(*pos == 2); + VERIFY( *pos == 2 ); } // This test verifies the following: @@ -96,17 +102,23 @@ test04() std::forward_list::const_iterator pos = fl.cbegin(); ++pos; - VERIFY(*pos == 1); + VERIFY( *pos == 1 ); - std::forward_list::iterator ret - = fl.insert_after(pos, {-1, -2, -3, -4, -5}); - VERIFY(ret == pos); - VERIFY(*pos == 1); + std::forward_list::iterator ret = fl.insert_after(pos, { }); + VERIFY( ret == pos); + + ret = fl.insert_after(pos, {-1, -2, -3, -4, -5}); + VERIFY( *pos == 1); ++pos; ++pos; ++pos; - VERIFY(*pos == -3); + VERIFY( *pos == -3 ); + ++pos; + ++pos; + VERIFY( ret == pos ); + ++pos; + VERIFY( *pos == 2 ); } // This test verifies the following: @@ -117,17 +129,17 @@ test05() std::forward_list::const_iterator pos = fl.cbegin(); ++pos; - VERIFY(*pos == "BBB"); + VERIFY( *pos == "BBB" ); std::string x( "XXX" ); std::forward_list::iterator ret = fl.insert_after(pos, std::move(x)); - VERIFY(*pos == "BBB"); + VERIFY( *pos == "BBB" ); ++pos; - VERIFY(ret == pos); - VERIFY(*pos == "XXX"); + VERIFY( ret == pos ); + VERIFY( *pos == "XXX" ); ++pos; - VERIFY(*pos == "CCC"); + VERIFY( *pos == "CCC" ); } int diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc index 5351a5b0788..8d72db59c8b 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1201 } +// { dg-error "no matching" "" { target *-*-* } 1194 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc index b624ab2356f..5f5ac2c7713 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1201 } +// { dg-error "no matching" "" { target *-*-* } 1194 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc index 0a593c83a91..340a6be65e3 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1201 } +// { dg-error "no matching" "" { target *-*-* } 1194 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc index 4739ce77f75..1173dc1b697 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1201 } +// { dg-error "no matching" "" { target *-*-* } 1194 } // { dg-excess-errors "" } // Copyright (C) 2009, 2010 Free Software Foundation