Commit 16920896 by Paolo Carlini Committed by Paolo Carlini

forward_list.tcc (_Fwd_list_node_base:: _M_transfer_after): Return _Fwd_list_node_base*.

2010-03-15  Paolo Carlini  <paolo.carlini@oracle.com>

	* 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
parent 92ff1083
2010-03-15 Paolo Carlini <paolo.carlini@oracle.com> 2010-03-15 Paolo Carlini <paolo.carlini@oracle.com>
* 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 <paolo.carlini@oracle.com>
* testsuite/23_containers/forward_list/requirements/dr438/ * testsuite/23_containers/forward_list/requirements/dr438/
assign_neg.cc: Adjust dg-error line number. assign_neg.cc: Adjust dg-error line number.
* testsuite/23_containers/forward_list/requirements/dr438/ * testsuite/23_containers/forward_list/requirements/dr438/
......
...@@ -51,28 +51,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -51,28 +51,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
swap(_Fwd_list_node_base& __x, _Fwd_list_node_base& __y) swap(_Fwd_list_node_base& __x, _Fwd_list_node_base& __y)
{ std::swap(__x._M_next, __y._M_next); } { std::swap(__x._M_next, __y._M_next); }
void _Fwd_list_node_base*
_M_transfer_after(_Fwd_list_node_base* __bbegin) _M_transfer_after(_Fwd_list_node_base* __begin)
{ {
_Fwd_list_node_base* __bend = __bbegin; _Fwd_list_node_base* __end = __begin;
while (__bend && __bend->_M_next) while (__end && __end->_M_next)
__bend = __bend->_M_next; __end = __end->_M_next;
_M_transfer_after(__bbegin, __bend); return _M_transfer_after(__begin, __end);
} }
void _Fwd_list_node_base*
_M_transfer_after(_Fwd_list_node_base* __bbegin, _M_transfer_after(_Fwd_list_node_base* __begin,
_Fwd_list_node_base* __bend) _Fwd_list_node_base* __end)
{ {
_Fwd_list_node_base* __keep = __bbegin->_M_next; _Fwd_list_node_base* __keep = __begin->_M_next;
if (__bend) if (__end)
{ {
__bbegin->_M_next = __bend->_M_next; __begin->_M_next = __end->_M_next;
__bend->_M_next = _M_next; __end->_M_next = _M_next;
} }
else else
__bbegin->_M_next = 0; __begin->_M_next = 0;
_M_next = __keep; _M_next = __keep;
return __end;
} }
void void
...@@ -865,7 +866,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -865,7 +866,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* @param pos An iterator into the %forward_list. * @param pos An iterator into the %forward_list.
* @param n Number of elements to be inserted. * @param n Number of elements to be inserted.
* @param val Data 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 * This function will insert a specified number of copies of the
* given data after the location specified by @a pos. * given data after the location specified by @a pos.
...@@ -874,19 +876,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -874,19 +876,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* does not invalidate iterators and references. * does not invalidate iterators and references.
*/ */
iterator iterator
insert_after(const_iterator __pos, size_type __n, const _Tp& __val) 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));
}
/** /**
* @brief Inserts a range into the %forward_list. * @brief Inserts a range into the %forward_list.
* @param position An iterator into the %forward_list. * @param position An iterator into the %forward_list.
* @param first An input iterator. * @param first An input iterator.
* @param last 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 * This function will insert copies of the data in the range [@a
* first,@a last) into the %forward_list after the location specified * first,@a last) into the %forward_list after the location specified
...@@ -898,19 +896,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -898,19 +896,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _InputIterator> template<typename _InputIterator>
iterator iterator
insert_after(const_iterator __pos, insert_after(const_iterator __pos,
_InputIterator __first, _InputIterator __last) _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));
}
/** /**
* @brief Inserts the contents of an initializer_list into * @brief Inserts the contents of an initializer_list into
* %forward_list after the specified iterator. * %forward_list after the specified iterator.
* @param pos An iterator into the %forward_list. * @param pos An iterator into the %forward_list.
* @param il An initializer_list of value_type. * @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 * This function will insert copies of the data in the
* initializer_list @a il into the %forward_list before the location * initializer_list @a il into the %forward_list before the location
...@@ -920,12 +914,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -920,12 +914,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* does not invalidate iterators and references. * does not invalidate iterators and references.
*/ */
iterator iterator
insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) 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));
}
/** /**
* @brief Removes the element pointed to by the iterator following * @brief Removes the element pointed to by the iterator following
...@@ -1037,7 +1026,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -1037,7 +1026,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* Requires this != @a x. * Requires this != @a x.
*/ */
void 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. * @brief Insert element from another %forward_list.
...@@ -1210,6 +1203,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -1210,6 +1203,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// turns out to be the same thing. // turns out to be the same thing.
void void
_M_fill_initialize(size_type __n, const value_type& __value); _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);
}; };
/** /**
......
...@@ -203,22 +203,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -203,22 +203,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
} }
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
void typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>:: 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);
{ iterator __before = __list.before_begin();
_Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node); return iterator(__tmp->_M_transfer_after(__before._M_node));
const_iterator __before = __list.cbefore_begin();
__tmp->_M_transfer_after(const_cast<_Node_base*>(__before._M_node));
}
} }
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
void void
forward_list<_Tp, _Alloc>:: 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) const_iterator __before, const_iterator __last)
{ {
_Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node); _Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node);
...@@ -227,6 +224,48 @@ _GLIBCXX_BEGIN_NAMESPACE(std) ...@@ -227,6 +224,48 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
} }
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
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<typename _Tp, typename _Alloc>
template<typename _InputIterator>
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 _Tp, typename _Alloc>
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<typename _Tp, typename _Alloc>
void void
forward_list<_Tp, _Alloc>:: forward_list<_Tp, _Alloc>::
remove(const _Tp& __val) remove(const _Tp& __val)
......
...@@ -36,8 +36,8 @@ test01() ...@@ -36,8 +36,8 @@ test01()
std::forward_list<int>::iterator ret = fl.insert_after(fl.before_begin(), std::forward_list<int>::iterator ret = fl.insert_after(fl.before_begin(),
42); 42);
VERIFY(ret == fl.begin()); VERIFY( ret == fl.begin() );
VERIFY(fl.front() == 42); VERIFY( fl.front() == 42 );
} }
// This test verifies the following: // This test verifies the following:
...@@ -48,21 +48,24 @@ test02() ...@@ -48,21 +48,24 @@ test02()
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 );
// Note: Calling l.insert_after(pos, 5, 42); without the long five std::forward_list<int>::iterator ret = fl.insert_after(pos, 0, 42);
// gets resolved to the iterator range version and fails to compile! VERIFY( ret == pos );
std::forward_list<int>::iterator ret = fl.insert_after(pos, 5, 42);
VERIFY(ret == pos);
VERIFY(*pos == 1);
ret = fl.insert_after(pos, 5, 42);
VERIFY( *pos == 1 );
++pos;
VERIFY( *pos == 42 );
++pos; ++pos;
VERIFY(*pos == 42);
++pos; ++pos;
++pos; ++pos;
++pos; ++pos;
VERIFY( *pos == 42 );
VERIFY( ret == pos );
++pos; ++pos;
VERIFY(*pos == 42); VERIFY( *pos == 2 );
} }
// This test verifies the following: // This test verifies the following:
...@@ -73,19 +76,22 @@ test03() ...@@ -73,19 +76,22 @@ test03()
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 );
int i[3] = {666, 777, 888}; int i[3] = {666, 777, 888};
std::forward_list<int>::iterator ret = fl.insert_after(pos, i, i + 3); std::forward_list<int>::iterator ret = fl.insert_after(pos, i, i);
VERIFY(ret == pos); VERIFY( ret == pos );
VERIFY(*pos == 1);
ret = fl.insert_after(pos, i, i + 3);
VERIFY( *pos == 1 );
++pos; ++pos;
++pos; ++pos;
++pos; ++pos;
VERIFY(*pos == 888); VERIFY( *pos == 888 );
VERIFY( ret == pos );
++pos; ++pos;
VERIFY(*pos == 2); VERIFY( *pos == 2 );
} }
// This test verifies the following: // This test verifies the following:
...@@ -96,17 +102,23 @@ test04() ...@@ -96,17 +102,23 @@ test04()
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 ret = fl.insert_after(pos, { });
VERIFY( ret == pos);
std::forward_list<int>::iterator ret ret = fl.insert_after(pos, {-1, -2, -3, -4, -5});
= fl.insert_after(pos, {-1, -2, -3, -4, -5}); VERIFY( *pos == 1);
VERIFY(ret == pos);
VERIFY(*pos == 1);
++pos; ++pos;
++pos; ++pos;
++pos; ++pos;
VERIFY(*pos == -3); VERIFY( *pos == -3 );
++pos;
++pos;
VERIFY( ret == pos );
++pos;
VERIFY( *pos == 2 );
} }
// This test verifies the following: // This test verifies the following:
...@@ -117,17 +129,17 @@ test05() ...@@ -117,17 +129,17 @@ test05()
std::forward_list<std::string>::const_iterator pos = fl.cbegin(); std::forward_list<std::string>::const_iterator pos = fl.cbegin();
++pos; ++pos;
VERIFY(*pos == "BBB"); VERIFY( *pos == "BBB" );
std::string x( "XXX" ); std::string x( "XXX" );
std::forward_list<std::string>::iterator ret std::forward_list<std::string>::iterator ret
= fl.insert_after(pos, std::move(x)); = fl.insert_after(pos, std::move(x));
VERIFY(*pos == "BBB"); VERIFY( *pos == "BBB" );
++pos; ++pos;
VERIFY(ret == pos); VERIFY( ret == pos );
VERIFY(*pos == "XXX"); VERIFY( *pos == "XXX" );
++pos; ++pos;
VERIFY(*pos == "CCC"); VERIFY( *pos == "CCC" );
} }
int int
......
// { dg-do compile } // { dg-do compile }
// { dg-options "-std=gnu++0x" } // { dg-options "-std=gnu++0x" }
// { dg-error "no matching" "" { target *-*-* } 1201 } // { dg-error "no matching" "" { target *-*-* } 1194 }
// { 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 *-*-* } 1201 } // { dg-error "no matching" "" { target *-*-* } 1194 }
// { 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 *-*-* } 1201 } // { dg-error "no matching" "" { target *-*-* } 1194 }
// { 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 *-*-* } 1201 } // { dg-error "no matching" "" { target *-*-* } 1194 }
// { dg-excess-errors "" } // { dg-excess-errors "" }
// Copyright (C) 2009, 2010 Free Software Foundation // Copyright (C) 2009, 2010 Free Software Foundation
......
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