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
This commit is contained in:
Paolo Carlini 2010-10-17 17:34:38 +00:00 committed by Paolo Carlini
parent abd26bfbf3
commit efb7b45650
10 changed files with 79 additions and 41 deletions

View File

@ -1,3 +1,23 @@
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

View File

@ -364,10 +364,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_put_node(_Node* __p)
{ _M_get_Node_allocator().deallocate(__p, 1); }
void
_Fwd_list_node_base*
_M_erase_after(_Fwd_list_node_base* __pos);
void
_Fwd_list_node_base*
_M_erase_after(_Fwd_list_node_base* __pos,
_Fwd_list_node_base* __last);
};
@ -924,6 +924,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* @brief Removes the element pointed to by the iterator following
* @c pos.
* @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
* thus shorten the %forward_list by one.
@ -935,9 +937,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* is itself a pointer, the pointed-to memory is not touched in
* any way. Managing the pointer is the user's responsibility.
*/
void
iterator
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.
@ -945,6 +948,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* erased.
* @param last Iterator pointing to one past the last element to be
* erased.
* @return @last.
*
* This function will erase the elements in the range @a
* (pos,last) and shorten the %forward_list accordingly.
@ -956,10 +960,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* pointed-to memory is not touched in any way. Managing the pointer
* is the user's responsibility.
*/
void
iterator
erase_after(const_iterator __pos, const_iterator __last)
{ this->_M_erase_after(const_cast<_Node_base*>(__pos._M_node),
const_cast<_Node_base*>(__last._M_node)); }
{ return iterator(this->_M_erase_after(const_cast<_Node_base*>
(__pos._M_node),
const_cast<_Node_base*>
(__last._M_node))); }
/**
* @brief Swaps data with another %forward_list.

View File

@ -63,7 +63,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
}
template<typename _Tp, typename _Alloc>
void
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos)
{
@ -71,10 +71,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
__pos->_M_next = __curr->_M_next;
_M_get_Node_allocator().destroy(__curr);
_M_put_node(__curr);
return __pos->_M_next;
}
template<typename _Tp, typename _Alloc>
void
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos,
_Fwd_list_node_base* __last)
@ -88,8 +89,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_put_node(__temp);
}
__pos->_M_next = __last;
return __last;
}
// Called by the range constructor to implement [23.1.1]/9
template<typename _Tp, typename _Alloc>
template<typename _InputIterator>

View File

@ -288,26 +288,27 @@ namespace __debug
return iterator(_Base::insert_after(__pos.base(), __il), this);
}
void
iterator
erase_after(const_iterator __pos)
{
__glibcxx_check_erase_after(__pos);
const_iterator __victim = __pos;
++__victim;
__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)
{
__glibcxx_check_erase_range_after(__pos, __last);
for (const_iterator __victim = std::next(__pos); __victim != __last; )
{
const_iterator __old = __victim++;
const_iterator __old = __victim;
++__victim;
__old._M_invalidate();
}
_Base::erase_after(__pos.base(), __last.base());
return iterator(_Base::erase_after(__pos.base(), __last.base()), this);
}
void

View File

@ -1,6 +1,6 @@
// { 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
// software; you can redistribute it and/or modify it under the
@ -22,8 +22,6 @@
#include <forward_list>
#include <testsuite_hooks.h>
bool test __attribute__((unused)) = true;
// This test verifies the following:
// cbegin
// erase_after one iterator
@ -31,17 +29,20 @@ bool test __attribute__((unused)) = true;
void
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>::const_iterator pos = fl.cbegin();
++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;
VERIFY(*pos == 3);
VERIFY( *pos == 3 );
VERIFY( pos == pos2 );
}
// This test verifies the following:
@ -51,33 +52,40 @@ test01()
void
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>::const_iterator pos = fl.cbegin();
++pos;
VERIFY(*pos == 1);
VERIFY( *pos == 1 );
std::forward_list<int>::iterator stop = fl.begin();
++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;
VERIFY(*pos == 4);
VERIFY(std::distance(fl.begin(), fl.end()) == 8);
VERIFY( *pos == 4 );
VERIFY( std::distance(fl.begin(), fl.end()) == 8 );
fl.erase_after(pos, fl.end());
VERIFY(++pos == fl.end());
VERIFY(std::distance(fl.begin(), fl.end()) == 3);
std::forward_list<int>::iterator pos3
= fl.erase_after(pos, fl.end());
VERIFY( pos3 == fl.end() );
VERIFY( ++pos == fl.end() );
VERIFY( std::distance(fl.begin(), fl.end()) == 3 );
fl.erase_after(fl.before_begin(), pos);
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

View File

@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation

View File

@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation

View File

@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation

View File

@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-error "no matching" "" { target *-*-* } 1204 }
// { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation

View File

@ -265,10 +265,11 @@ namespace __gnu_test
{
typedef std::forward_list<_Tp1, _Tp2> container_type;
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);
void (container_type::* _F_erase_range)(const_iterator, const_iterator);
iterator (container_type::* _F_erase_point)(const_iterator);
iterator (container_type::* _F_erase_range)(const_iterator,
const_iterator);
erase_base()
: _F_erase_point(&container_type::erase_after),