mirror of git://gcc.gnu.org/git/gcc.git
forward_list.h (forward_list::assign): Dispatch to new functions based on assignability of elements.
* include/bits/forward_list.h (forward_list::assign): Dispatch to new functions based on assignability of elements. (forward_list::_M_assign): Add overloaded functions for assigning via assignment or via clearing and insertion. (forward_list::_M_assign_val): Likewise. (forward_list::_M_move_assign(forward_list&&, false_type)): Do not erase elements that are not moved. * include/bits/forward_list.tcc (forward_list::operator=): Call assign() to copy elements. * testsuite/23_containers/forward_list/cons/10.cc: New. * testsuite/23_containers/forward_list/cons/11.cc: New. * testsuite/23_containers/forward_list/cons/12.cc: New. From-SVN: r193057
This commit is contained in:
parent
d81aa38840
commit
362261e71f
|
|
@ -1,3 +1,18 @@
|
||||||
|
2012-11-01 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||||
|
|
||||||
|
* include/bits/forward_list.h (forward_list::assign): Dispatch to new
|
||||||
|
functions based on assignability of elements.
|
||||||
|
(forward_list::_M_assign): Add overloaded functions for assigning
|
||||||
|
via assignment or via clearing and insertion.
|
||||||
|
(forward_list::_M_assign_val): Likewise.
|
||||||
|
(forward_list::_M_move_assign(forward_list&&, false_type)): Do not
|
||||||
|
erase elements that are not moved.
|
||||||
|
* include/bits/forward_list.tcc (forward_list::operator=): Call
|
||||||
|
assign() to copy elements.
|
||||||
|
* testsuite/23_containers/forward_list/cons/10.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/cons/11.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/cons/12.cc: New.
|
||||||
|
|
||||||
2012-10-31 Jonathan Yong <jon_y@users.sourceforge.net>
|
2012-10-31 Jonathan Yong <jon_y@users.sourceforge.net>
|
||||||
|
|
||||||
* config/os/mingw32-w64/os_defines.h: Do not define anymore
|
* config/os/mingw32-w64/os_defines.h: Do not define anymore
|
||||||
|
|
|
||||||
|
|
@ -589,7 +589,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
* in the range [@a __first,@a __last).
|
* in the range [@a __first,@a __last).
|
||||||
*
|
*
|
||||||
* Note that the assignment completely changes the %forward_list and
|
* Note that the assignment completely changes the %forward_list and
|
||||||
* that the number of elements of the resulting %forward_list's is the
|
* that the number of elements of the resulting %forward_list is the
|
||||||
* same as the number of elements assigned. Old data is lost.
|
* same as the number of elements assigned. Old data is lost.
|
||||||
*/
|
*/
|
||||||
template<typename _InputIterator,
|
template<typename _InputIterator,
|
||||||
|
|
@ -597,9 +597,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
void
|
void
|
||||||
assign(_InputIterator __first, _InputIterator __last)
|
assign(_InputIterator __first, _InputIterator __last)
|
||||||
{
|
{
|
||||||
clear();
|
typedef is_assignable<_Tp, decltype(*__first)> __assignable;
|
||||||
insert_after(cbefore_begin(), __first, __last);
|
_M_assign(__first, __last, __assignable());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assigns a given value to a %forward_list.
|
* @brief Assigns a given value to a %forward_list.
|
||||||
|
|
@ -613,10 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
assign(size_type __n, const _Tp& __val)
|
assign(size_type __n, const _Tp& __val)
|
||||||
{
|
{ _M_assign_n(__n, __val, is_copy_assignable<_Tp>()); }
|
||||||
clear();
|
|
||||||
insert_after(cbefore_begin(), __n, __val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Assigns an initializer_list to a %forward_list.
|
* @brief Assigns an initializer_list to a %forward_list.
|
||||||
|
|
@ -628,10 +625,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
assign(std::initializer_list<_Tp> __il)
|
assign(std::initializer_list<_Tp> __il)
|
||||||
{
|
{ assign(__il.begin(), __il.end()); }
|
||||||
clear();
|
|
||||||
insert_after(cbefore_begin(), __il);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a copy of the memory allocation object.
|
/// Get a copy of the memory allocation object.
|
||||||
allocator_type
|
allocator_type
|
||||||
|
|
@ -1255,13 +1249,70 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
|
if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
|
||||||
_M_move_assign(std::move(__list), std::true_type());
|
_M_move_assign(std::move(__list), std::true_type());
|
||||||
else
|
else
|
||||||
{
|
// The rvalue's allocator cannot be moved, or is not equal,
|
||||||
// The rvalue's allocator cannot be moved, or is not equal,
|
// so we need to individually move each element.
|
||||||
// so we need to individually move each element.
|
this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
|
||||||
this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
|
std::__make_move_if_noexcept_iterator(__list.end()));
|
||||||
std::__make_move_if_noexcept_iterator(__list.end()));
|
}
|
||||||
__list.clear();
|
|
||||||
}
|
// Called by assign(_InputIterator, _InputIterator) if _Tp is
|
||||||
|
// CopyAssignable.
|
||||||
|
template<typename _InputIterator>
|
||||||
|
void
|
||||||
|
_M_assign(_InputIterator __first, _InputIterator __last, true_type)
|
||||||
|
{
|
||||||
|
auto __prev = before_begin();
|
||||||
|
auto __curr = begin();
|
||||||
|
auto __end = end();
|
||||||
|
while (__curr != __end && __first != __last)
|
||||||
|
{
|
||||||
|
*__curr = *__first;
|
||||||
|
++__prev;
|
||||||
|
++__curr;
|
||||||
|
++__first;
|
||||||
|
}
|
||||||
|
if (__first != __last)
|
||||||
|
insert_after(__prev, __first, __last);
|
||||||
|
else if (__curr != __end)
|
||||||
|
erase_after(__prev, __end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by assign(_InputIterator, _InputIterator) if _Tp is not
|
||||||
|
// CopyAssignable.
|
||||||
|
template<typename _InputIterator>
|
||||||
|
void
|
||||||
|
_M_assign(_InputIterator __first, _InputIterator __last, false_type)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
insert_after(cbefore_begin(), __first, __last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by assign(size_type, const _Tp&) if Tp is CopyAssignable
|
||||||
|
void
|
||||||
|
_M_assign_n(size_type __n, const _Tp& __val, true_type)
|
||||||
|
{
|
||||||
|
auto __prev = before_begin();
|
||||||
|
auto __curr = begin();
|
||||||
|
auto __end = end();
|
||||||
|
while (__curr != __end && __n > 0)
|
||||||
|
{
|
||||||
|
*__curr = __val;
|
||||||
|
++__prev;
|
||||||
|
++__curr;
|
||||||
|
--__n;
|
||||||
|
}
|
||||||
|
if (__n > 0)
|
||||||
|
insert_after(__prev, __n, __val);
|
||||||
|
else if (__curr != __end)
|
||||||
|
erase_after(__prev, __end);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by assign(size_type, const _Tp&) if Tp is non-CopyAssignable
|
||||||
|
void
|
||||||
|
_M_assign_n(size_type __n, const _Tp& __val, false_type)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
insert_after(cbefore_begin(), __n, __val);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,22 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
}
|
}
|
||||||
std::__alloc_on_copy(__this_alloc, __that_alloc);
|
std::__alloc_on_copy(__this_alloc, __that_alloc);
|
||||||
}
|
}
|
||||||
iterator __prev1 = before_begin();
|
assign(__list.cbegin(), __list.cend());
|
||||||
iterator __curr1 = begin();
|
|
||||||
iterator __last1 = end();
|
|
||||||
const_iterator __first2 = __list.cbegin();
|
|
||||||
const_iterator __last2 = __list.cend();
|
|
||||||
while (__curr1 != __last1 && __first2 != __last2)
|
|
||||||
{
|
|
||||||
*__curr1 = *__first2;
|
|
||||||
++__prev1;
|
|
||||||
++__curr1;
|
|
||||||
++__first2;
|
|
||||||
}
|
|
||||||
if (__first2 == __last2)
|
|
||||||
erase_after(__prev1, __last1);
|
|
||||||
else
|
|
||||||
insert_after(__prev1, __first2, __last2);
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// Copyright (C) 2012 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
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// 23.3.4.2 forward_list construction [forwardlist.cons]
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct Counter
|
||||||
|
{
|
||||||
|
Counter() { ++create; }
|
||||||
|
Counter(const Counter&) { ++create; }
|
||||||
|
~Counter() { ++destroy; }
|
||||||
|
|
||||||
|
static int create;
|
||||||
|
static int destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Counter::create = 0;
|
||||||
|
int Counter::destroy = 0;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
typedef __gnu_test::uneq_allocator<Counter> alloc;
|
||||||
|
typedef std::forward_list<Counter, alloc> list;
|
||||||
|
|
||||||
|
{
|
||||||
|
Counter c;
|
||||||
|
|
||||||
|
list l( list(10, c, alloc(1)), alloc(2) );
|
||||||
|
|
||||||
|
VERIFY( Counter::create == 21 );
|
||||||
|
VERIFY( Counter::destroy == 10 );
|
||||||
|
}
|
||||||
|
VERIFY( Counter::destroy == 21 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// Copyright (C) 2012 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
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// 23.3.4.2 forward_list construction [forwardlist.cons]
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
A() = default;
|
||||||
|
A(const A&) { if (fail) throw fail; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
typedef std::forward_list<A> list;
|
||||||
|
|
||||||
|
list l(2);
|
||||||
|
A from[2];
|
||||||
|
fail = true;
|
||||||
|
// Check existing elements are assigned to, instead of creating new ones.
|
||||||
|
// This is QoI, not required by the standard.
|
||||||
|
l.assign(from, from+2);
|
||||||
|
l.assign(2, from[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// Copyright (C) 2012 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
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// 23.3.4.2 forward_list construction [forwardlist.cons]
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
struct NonCopyAssignable
|
||||||
|
{
|
||||||
|
NonCopyAssignable() = default;
|
||||||
|
NonCopyAssignable(const NonCopyAssignable&) = default;
|
||||||
|
NonCopyAssignable(int) { }
|
||||||
|
|
||||||
|
NonCopyAssignable& operator=(const NonCopyAssignable&) = delete;
|
||||||
|
NonCopyAssignable& operator=(int) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
typedef std::forward_list<NonCopyAssignable> list;
|
||||||
|
|
||||||
|
list l(2);
|
||||||
|
NonCopyAssignable from[2];
|
||||||
|
int from2[2];
|
||||||
|
|
||||||
|
// Assigning non-Assignable elements is QoI, not required by the standard.
|
||||||
|
|
||||||
|
l = l;
|
||||||
|
|
||||||
|
l.assign(from, from+2);
|
||||||
|
l.assign(2, from[0]);
|
||||||
|
|
||||||
|
l.assign(from2, from2+2);
|
||||||
|
l.assign(2, from2[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue