Commit efb7b456 by Paolo Carlini Committed by Paolo Carlini

forward_list.h (forward_list<>::erase_after): Return an iterator.

2010-10-17  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/forward_list.h (forward_list<>::erase_after): Return
	an iterator.
	(_M_erase_after): Return _Fwd_list_node_base*.
	* include/bits/forward_list.tcc: Likewise.
	* include/debug/forward_list: Likewise.
	* testsuite/23_containers/forward_list/modifiers/3.cc: Update
	and extend.
	* testsuite/util/exception/safety.h (erase_base<forward_list<>>):
	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: r165590
parent abd26bfb
2010-10-17 Paolo Carlini <paolo.carlini@oracle.com> 2010-10-17 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/forward_list.h (forward_list<>::erase_after): Return
an iterator.
(_M_erase_after): Return _Fwd_list_node_base*.
* include/bits/forward_list.tcc: Likewise.
* include/debug/forward_list: Likewise.
* testsuite/23_containers/forward_list/modifiers/3.cc: Update
and extend.
* testsuite/util/exception/safety.h (erase_base<forward_list<>>):
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-10-17 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/43554 PR libstdc++/43554
* include/profile/forward_list: New file. * include/profile/forward_list: New file.
* include/std/forward_list: Include <profile/forward_list>. * include/std/forward_list: Include <profile/forward_list>.
......
...@@ -364,10 +364,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -364,10 +364,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_put_node(_Node* __p) _M_put_node(_Node* __p)
{ _M_get_Node_allocator().deallocate(__p, 1); } { _M_get_Node_allocator().deallocate(__p, 1); }
void _Fwd_list_node_base*
_M_erase_after(_Fwd_list_node_base* __pos); _M_erase_after(_Fwd_list_node_base* __pos);
void _Fwd_list_node_base*
_M_erase_after(_Fwd_list_node_base* __pos, _M_erase_after(_Fwd_list_node_base* __pos,
_Fwd_list_node_base* __last); _Fwd_list_node_base* __last);
}; };
...@@ -924,6 +924,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -924,6 +924,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* @brief Removes the element pointed to by the iterator following * @brief Removes the element pointed to by the iterator following
* @c pos. * @c pos.
* @param pos Iterator pointing before element to be erased. * @param pos Iterator pointing before element to be erased.
* @return An iterator pointing to the element following the one
* that was erased, or end() if no such element exists.
* *
* This function will erase the element at the given position and * This function will erase the element at the given position and
* thus shorten the %forward_list by one. * thus shorten the %forward_list by one.
...@@ -935,9 +937,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -935,9 +937,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* is itself a pointer, the pointed-to memory is not touched in * is itself a pointer, the pointed-to memory is not touched in
* any way. Managing the pointer is the user's responsibility. * any way. Managing the pointer is the user's responsibility.
*/ */
void iterator
erase_after(const_iterator __pos) erase_after(const_iterator __pos)
{ this->_M_erase_after(const_cast<_Node_base*>(__pos._M_node)); } { return iterator(this->_M_erase_after(const_cast<_Node_base*>
(__pos._M_node))); }
/** /**
* @brief Remove a range of elements. * @brief Remove a range of elements.
...@@ -945,6 +948,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -945,6 +948,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* erased. * erased.
* @param last Iterator pointing to one past the last element to be * @param last Iterator pointing to one past the last element to be
* erased. * erased.
* @return @last.
* *
* This function will erase the elements in the range @a * This function will erase the elements in the range @a
* (pos,last) and shorten the %forward_list accordingly. * (pos,last) and shorten the %forward_list accordingly.
...@@ -956,10 +960,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -956,10 +960,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* pointed-to memory is not touched in any way. Managing the pointer * pointed-to memory is not touched in any way. Managing the pointer
* is the user's responsibility. * is the user's responsibility.
*/ */
void iterator
erase_after(const_iterator __pos, const_iterator __last) erase_after(const_iterator __pos, const_iterator __last)
{ this->_M_erase_after(const_cast<_Node_base*>(__pos._M_node), { return iterator(this->_M_erase_after(const_cast<_Node_base*>
const_cast<_Node_base*>(__last._M_node)); } (__pos._M_node),
const_cast<_Node_base*>
(__last._M_node))); }
/** /**
* @brief Swaps data with another %forward_list. * @brief Swaps data with another %forward_list.
......
...@@ -63,7 +63,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -63,7 +63,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
} }
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
void _Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>:: _Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos) _M_erase_after(_Fwd_list_node_base* __pos)
{ {
...@@ -71,10 +71,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -71,10 +71,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
__pos->_M_next = __curr->_M_next; __pos->_M_next = __curr->_M_next;
_M_get_Node_allocator().destroy(__curr); _M_get_Node_allocator().destroy(__curr);
_M_put_node(__curr); _M_put_node(__curr);
return __pos->_M_next;
} }
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
void _Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>:: _Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos, _M_erase_after(_Fwd_list_node_base* __pos,
_Fwd_list_node_base* __last) _Fwd_list_node_base* __last)
...@@ -88,8 +89,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) ...@@ -88,8 +89,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_put_node(__temp); _M_put_node(__temp);
} }
__pos->_M_next = __last; __pos->_M_next = __last;
return __last;
} }
// Called by the range constructor to implement [23.1.1]/9 // Called by the range constructor to implement [23.1.1]/9
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
template<typename _InputIterator> template<typename _InputIterator>
......
...@@ -288,26 +288,27 @@ namespace __debug ...@@ -288,26 +288,27 @@ namespace __debug
return iterator(_Base::insert_after(__pos.base(), __il), this); return iterator(_Base::insert_after(__pos.base(), __il), this);
} }
void iterator
erase_after(const_iterator __pos) erase_after(const_iterator __pos)
{ {
__glibcxx_check_erase_after(__pos); __glibcxx_check_erase_after(__pos);
const_iterator __victim = __pos; const_iterator __victim = __pos;
++__victim; ++__victim;
__victim._M_invalidate(); __victim._M_invalidate();
_Base::erase_after(__pos.base()); return iterator(_Base::erase_after(__pos.base()), this);
} }
void iterator
erase_after(const_iterator __pos, const_iterator __last) erase_after(const_iterator __pos, const_iterator __last)
{ {
__glibcxx_check_erase_range_after(__pos, __last); __glibcxx_check_erase_range_after(__pos, __last);
for (const_iterator __victim = std::next(__pos); __victim != __last; ) for (const_iterator __victim = std::next(__pos); __victim != __last; )
{ {
const_iterator __old = __victim++; const_iterator __old = __victim;
++__victim;
__old._M_invalidate(); __old._M_invalidate();
} }
_Base::erase_after(__pos.base(), __last.base()); return iterator(_Base::erase_after(__pos.base(), __last.base()), this);
} }
void void
......
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// Copyright (C) 2008, 2009 Free Software Foundation, Inc. // Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the // software; you can redistribute it and/or modify it under the
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
#include <forward_list> #include <forward_list>
#include <testsuite_hooks.h> #include <testsuite_hooks.h>
bool test __attribute__((unused)) = true;
// This test verifies the following: // This test verifies the following:
// cbegin // cbegin
// erase_after one iterator // erase_after one iterator
...@@ -31,17 +29,20 @@ bool test __attribute__((unused)) = true; ...@@ -31,17 +29,20 @@ bool test __attribute__((unused)) = true;
void void
test01() test01()
{ {
bool test __attribute__((unused)) = true;
std::forward_list<int> fl({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); std::forward_list<int> fl({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
std::forward_list<int>::const_iterator pos = fl.cbegin(); std::forward_list<int>::const_iterator pos = fl.cbegin();
++pos; ++pos;
VERIFY(*pos == 1); VERIFY( *pos == 1 );
fl.erase_after(pos); std::forward_list<int>::iterator pos2 = fl.erase_after(pos);
VERIFY(*pos == 1); VERIFY( *pos == 1 );
++pos; ++pos;
VERIFY(*pos == 3); VERIFY( *pos == 3 );
VERIFY( pos == pos2 );
} }
// This test verifies the following: // This test verifies the following:
...@@ -51,33 +52,40 @@ test01() ...@@ -51,33 +52,40 @@ test01()
void void
test02() test02()
{ {
bool test __attribute__((unused)) = true;
std::forward_list<int> fl({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); std::forward_list<int> fl({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
std::forward_list<int>::const_iterator pos = fl.cbegin(); std::forward_list<int>::const_iterator pos = fl.cbegin();
++pos; ++pos;
VERIFY(*pos == 1); VERIFY( *pos == 1 );
std::forward_list<int>::iterator stop = fl.begin(); std::forward_list<int>::iterator stop = fl.begin();
++stop; ++stop;
++stop; ++stop;
++stop; ++stop;
++stop; ++stop;
VERIFY(*stop == 4); VERIFY( *stop == 4 );
fl.erase_after(pos, stop); std::forward_list<int>::iterator pos2 = fl.erase_after(pos, stop);
VERIFY(*pos == 1); VERIFY( pos2 == stop );
VERIFY( *pos == 1 );
++pos; ++pos;
VERIFY(*pos == 4); VERIFY( *pos == 4 );
VERIFY(std::distance(fl.begin(), fl.end()) == 8); VERIFY( std::distance(fl.begin(), fl.end()) == 8 );
fl.erase_after(pos, fl.end()); std::forward_list<int>::iterator pos3
VERIFY(++pos == fl.end()); = fl.erase_after(pos, fl.end());
VERIFY(std::distance(fl.begin(), fl.end()) == 3); VERIFY( pos3 == fl.end() );
VERIFY( ++pos == fl.end() );
fl.erase_after(fl.before_begin(), pos); VERIFY( std::distance(fl.begin(), fl.end()) == 3 );
VERIFY(std::distance(fl.begin(), fl.end()) == 0);
VERIFY(fl.empty()); std::forward_list<int>::iterator pos4
= fl.erase_after(fl.before_begin(), pos);
VERIFY( pos4 == pos );
VERIFY( std::distance(fl.begin(), fl.end()) == 0 );
VERIFY( fl.empty() );
} }
int int
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" } // { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation // Copyright (C) 2009, 2010 Free Software Foundation
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" } // { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation // Copyright (C) 2009, 2010 Free Software Foundation
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" } // { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation // Copyright (C) 2009, 2010 Free Software Foundation
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" } // { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation // Copyright (C) 2009, 2010 Free Software Foundation
......
...@@ -265,10 +265,11 @@ namespace __gnu_test ...@@ -265,10 +265,11 @@ namespace __gnu_test
{ {
typedef std::forward_list<_Tp1, _Tp2> container_type; typedef std::forward_list<_Tp1, _Tp2> container_type;
typedef typename container_type::iterator iterator; typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator; typedef typename container_type::const_iterator const_iterator;
void (container_type::* _F_erase_point)(const_iterator); iterator (container_type::* _F_erase_point)(const_iterator);
void (container_type::* _F_erase_range)(const_iterator, const_iterator); iterator (container_type::* _F_erase_range)(const_iterator,
const_iterator);
erase_base() erase_base()
: _F_erase_point(&container_type::erase_after), : _F_erase_point(&container_type::erase_after),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment