forward_list.h (forward_list(size_type)): Add missing allocator parameter.
* include/bits/forward_list.h (forward_list(size_type)): Add missing allocator parameter. (_Fwd_list_node_base): Use NSDMI and define constructor as defaulted. (_Fwd_list_node::_M_value): Replace with uninitialized storage. (_Fwd_list_node::_M_valptr()): Define functions to access storage. (_Fwd_list_iterator, _Fwd_list_const_iterator): Use _M_valptr. (_Fwd_list_base::_M_create_node): Only use allocator to construct the element not the node. * include/bits/forward_list.tcc (_Fwd_list_base::_M_erase_after): Only use allocator to destroy the element not the node. * testsuite/23_containers/forward_list/cons/11.cc: Remove unused headers. * testsuite/23_containers/forward_list/cons/12.cc: Likewise. * testsuite/23_containers/forward_list/cons/13.cc: New. * testsuite/23_containers/forward_list/cons/14.cc: New. From-SVN: r193086
This commit is contained in:
parent
7ce3b11540
commit
50799846a5
|
@ -1,3 +1,21 @@
|
|||
2012-11-02 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
* include/bits/forward_list.h (forward_list(size_type)): Add missing
|
||||
allocator parameter.
|
||||
(_Fwd_list_node_base): Use NSDMI and define constructor as defaulted.
|
||||
(_Fwd_list_node::_M_value): Replace with uninitialized storage.
|
||||
(_Fwd_list_node::_M_valptr()): Define functions to access storage.
|
||||
(_Fwd_list_iterator, _Fwd_list_const_iterator): Use _M_valptr.
|
||||
(_Fwd_list_base::_M_create_node): Only use allocator to construct the
|
||||
element not the node.
|
||||
* include/bits/forward_list.tcc (_Fwd_list_base::_M_erase_after): Only
|
||||
use allocator to destroy the element not the node.
|
||||
* testsuite/23_containers/forward_list/cons/11.cc: Remove unused
|
||||
headers.
|
||||
* testsuite/23_containers/forward_list/cons/12.cc: Likewise.
|
||||
* testsuite/23_containers/forward_list/cons/13.cc: New.
|
||||
* testsuite/23_containers/forward_list/cons/14.cc: New.
|
||||
|
||||
2012-11-02 Gerald Pfeifer <gerald@pfeifer.com>
|
||||
|
||||
* doc/xml/manual/codecvt.xml: Fix reference to Austin Common
|
||||
|
|
|
@ -48,9 +48,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
*/
|
||||
struct _Fwd_list_node_base
|
||||
{
|
||||
_Fwd_list_node_base() : _M_next(0) { }
|
||||
_Fwd_list_node_base() = default;
|
||||
|
||||
_Fwd_list_node_base* _M_next;
|
||||
_Fwd_list_node_base* _M_next = nullptr;
|
||||
|
||||
_Fwd_list_node_base*
|
||||
_M_transfer_after(_Fwd_list_node_base* __begin,
|
||||
|
@ -86,19 +86,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
|
||||
/**
|
||||
* @brief A helper node class for %forward_list.
|
||||
* This is just a linked list with a data value in each node.
|
||||
* This is just a linked list with uninitialized storage for a
|
||||
* data value in each node.
|
||||
* There is a sorting utility method.
|
||||
*/
|
||||
template<typename _Tp>
|
||||
struct _Fwd_list_node
|
||||
: public _Fwd_list_node_base
|
||||
{
|
||||
template<typename... _Args>
|
||||
_Fwd_list_node(_Args&&... __args)
|
||||
: _Fwd_list_node_base(),
|
||||
_M_value(std::forward<_Args>(__args)...) { }
|
||||
_Fwd_list_node() = default;
|
||||
|
||||
_Tp _M_value;
|
||||
typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
|
||||
_M_storage;
|
||||
|
||||
_Tp*
|
||||
_M_valptr() noexcept
|
||||
{
|
||||
return static_cast<_Tp*>(static_cast<void*>(&_M_storage));
|
||||
}
|
||||
|
||||
const _Tp*
|
||||
_M_valptr() const noexcept
|
||||
{
|
||||
return static_cast<const _Tp*>(static_cast<const void*>(&_M_storage));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -127,12 +138,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
|
||||
reference
|
||||
operator*() const
|
||||
{ return static_cast<_Node*>(this->_M_node)->_M_value; }
|
||||
{ return *static_cast<_Node*>(this->_M_node)->_M_valptr(); }
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{ return std::__addressof(static_cast<_Node*>
|
||||
(this->_M_node)->_M_value); }
|
||||
{ return static_cast<_Node*>(this->_M_node)->_M_valptr(); }
|
||||
|
||||
_Self&
|
||||
operator++()
|
||||
|
@ -199,12 +209,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
|
||||
reference
|
||||
operator*() const
|
||||
{ return static_cast<_Node*>(this->_M_node)->_M_value; }
|
||||
{ return *static_cast<_Node*>(this->_M_node)->_M_valptr(); }
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{ return std::__addressof(static_cast<_Node*>
|
||||
(this->_M_node)->_M_value); }
|
||||
{ return static_cast<_Node*>(this->_M_node)->_M_valptr(); }
|
||||
|
||||
_Self&
|
||||
operator++()
|
||||
|
@ -339,9 +348,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
_Node* __node = this->_M_get_node();
|
||||
__try
|
||||
{
|
||||
_Node_alloc_traits::construct(_M_get_Node_allocator(), __node,
|
||||
std::forward<_Args>(__args)...);
|
||||
__node->_M_next = 0;
|
||||
_Tp_alloc_type __a(_M_get_Node_allocator());
|
||||
typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
|
||||
::new ((void*)__node) _Node();
|
||||
_Alloc_traits::construct(__a, __node->_M_valptr(),
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
|
@ -457,8 +468,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
* constructed elements.
|
||||
*/
|
||||
explicit
|
||||
forward_list(size_type __n)
|
||||
: _Base()
|
||||
forward_list(size_type __n, const _Alloc& __al = _Alloc())
|
||||
: _Base(_Node_alloc_type(__al))
|
||||
{ _M_default_initialize(__n); }
|
||||
|
||||
/**
|
||||
|
@ -738,7 +749,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
front()
|
||||
{
|
||||
_Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next);
|
||||
return __front->_M_value;
|
||||
return *__front->_M_valptr();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -749,7 +760,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
front() const
|
||||
{
|
||||
_Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next);
|
||||
return __front->_M_value;
|
||||
return *__front->_M_valptr();
|
||||
}
|
||||
|
||||
// 23.3.4.5 modifiers:
|
||||
|
|
|
@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
while (__curr)
|
||||
{
|
||||
__to->_M_next =
|
||||
_M_create_node(std::move_if_noexcept(__curr->_M_value));
|
||||
_M_create_node(std::move_if_noexcept(*__curr->_M_valptr()));
|
||||
__to = __to->_M_next;
|
||||
__curr = static_cast<_Node*>(__curr->_M_next);
|
||||
}
|
||||
|
@ -81,7 +81,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
{
|
||||
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
|
||||
__pos->_M_next = __curr->_M_next;
|
||||
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __curr);
|
||||
_Tp_alloc_type __a(_M_get_Node_allocator());
|
||||
allocator_traits<_Tp_alloc_type>::destroy(__a, __curr->_M_valptr());
|
||||
__curr->~_Node();
|
||||
_M_put_node(__curr);
|
||||
return __pos->_M_next;
|
||||
}
|
||||
|
@ -97,7 +99,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
{
|
||||
_Node* __temp = __curr;
|
||||
__curr = static_cast<_Node*>(__curr->_M_next);
|
||||
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __temp);
|
||||
_Tp_alloc_type __a(_M_get_Node_allocator());
|
||||
allocator_traits<_Tp_alloc_type>::destroy(__a, __temp->_M_valptr());
|
||||
__temp->~_Node();
|
||||
_M_put_node(__temp);
|
||||
}
|
||||
__pos->_M_next = __last;
|
||||
|
@ -300,10 +304,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
|
||||
while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next))
|
||||
{
|
||||
if (__tmp->_M_value == __val)
|
||||
if (*__tmp->_M_valptr() == __val)
|
||||
{
|
||||
if (std::__addressof(__tmp->_M_value)
|
||||
!= std::__addressof(__val))
|
||||
if (__tmp->_M_valptr() != std::__addressof(__val))
|
||||
{
|
||||
this->_M_erase_after(__curr);
|
||||
continue;
|
||||
|
@ -327,7 +330,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
_Node* __curr = static_cast<_Node*>(&this->_M_impl._M_head);
|
||||
while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next))
|
||||
{
|
||||
if (__pred(__tmp->_M_value))
|
||||
if (__pred(*__tmp->_M_valptr()))
|
||||
this->_M_erase_after(__curr);
|
||||
else
|
||||
__curr = static_cast<_Node*>(__curr->_M_next);
|
||||
|
@ -364,10 +367,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
_Node_base* __node = &this->_M_impl._M_head;
|
||||
while (__node->_M_next && __list._M_impl._M_head._M_next)
|
||||
{
|
||||
if (__comp(static_cast<_Node*>
|
||||
(__list._M_impl._M_head._M_next)->_M_value,
|
||||
static_cast<_Node*>
|
||||
(__node->_M_next)->_M_value))
|
||||
if (__comp(*static_cast<_Node*>
|
||||
(__list._M_impl._M_head._M_next)->_M_valptr(),
|
||||
*static_cast<_Node*>
|
||||
(__node->_M_next)->_M_valptr()))
|
||||
__node->_M_transfer_after(&__list._M_impl._M_head,
|
||||
__list._M_impl._M_head._M_next);
|
||||
__node = __node->_M_next;
|
||||
|
@ -460,7 +463,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
|||
__p = static_cast<_Node*>(__p->_M_next);
|
||||
--__psize;
|
||||
}
|
||||
else if (__comp(__p->_M_value, __q->_M_value))
|
||||
else if (__comp(*__p->_M_valptr(), *__q->_M_valptr()))
|
||||
{
|
||||
// First node of p is lower; e must come from p.
|
||||
__e = __p;
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
// 23.3.4.2 forward_list construction [forwardlist.cons]
|
||||
|
||||
#include <forward_list>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
bool fail = false;
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
// 23.3.4.2 forward_list construction [forwardlist.cons]
|
||||
|
||||
#include <forward_list>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
bool fail = false;
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// { 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 even 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 <memory>
|
||||
#include <scoped_allocator>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct A
|
||||
{
|
||||
typedef std::allocator<A> allocator_type;
|
||||
|
||||
A() : ok(false) { }
|
||||
A(const A&) : ok(false) { }
|
||||
A(const allocator_type&) : ok(true) { }
|
||||
A(const A&, const allocator_type&) : ok(true) { }
|
||||
|
||||
bool ok;
|
||||
};
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef std::scoped_allocator_adaptor<A::allocator_type> alloc_type;
|
||||
typedef std::forward_list<A, alloc_type> list;
|
||||
|
||||
list l1(1);
|
||||
VERIFY( l1.begin()->ok );
|
||||
|
||||
A a;
|
||||
list l2(1, a);
|
||||
VERIFY( l2.begin()->ok );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// { 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 even 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 <scoped_allocator>
|
||||
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
using list = forward_list<int>;
|
||||
forward_list<list, scoped_allocator_adaptor<list::allocator_type>> l;
|
||||
|
||||
// Check for forward_list(size_type, const allocator_type&)
|
||||
l.emplace_front(1u);
|
||||
}
|
||||
|
Loading…
Reference in New Issue