mirror of git://gcc.gnu.org/git/gcc.git
forward_list.h: Add C++11 allocator support.
* include/bits/forward_list.h: Add C++11 allocator support. * include/bits/forward_list.tcc: Likewise. * doc/xml/manual/status_cxx2011.xml: Update. * testsuite/23_containers/forward_list/allocator/copy.cc: New. * testsuite/23_containers/forward_list/allocator/copy_assign.cc: New. * testsuite/23_containers/forward_list/allocator/minimal.cc: New. * testsuite/23_containers/forward_list/allocator/move_assign.cc: New. * testsuite/23_containers/forward_list/allocator/noexcept.cc: New. * testsuite/23_containers/forward_list/allocator/swap.cc: New. From-SVN: r192588
This commit is contained in:
parent
14cbb5d84c
commit
7aad1ae2b2
|
|
@ -1,3 +1,15 @@
|
||||||
|
2012-10-18 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||||
|
|
||||||
|
* include/bits/forward_list.h: Add C++11 allocator support.
|
||||||
|
* include/bits/forward_list.tcc: Likewise.
|
||||||
|
* doc/xml/manual/status_cxx2011.xml: Update.
|
||||||
|
* testsuite/23_containers/forward_list/allocator/copy.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/allocator/copy_assign.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/allocator/minimal.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/allocator/move_assign.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/allocator/noexcept.cc: New.
|
||||||
|
* testsuite/23_containers/forward_list/allocator/swap.cc: New.
|
||||||
|
|
||||||
2012-10-18 François Dumont <fdumont@gcc.gnu.org>
|
2012-10-18 François Dumont <fdumont@gcc.gnu.org>
|
||||||
|
|
||||||
* include/debug/formatter.h (_Debug_msg_id): Add
|
* include/debug/formatter.h (_Debug_msg_id): Add
|
||||||
|
|
|
||||||
|
|
@ -1378,7 +1378,8 @@ particular release.
|
||||||
<entry>23.2.1</entry>
|
<entry>23.2.1</entry>
|
||||||
<entry>General container requirements</entry>
|
<entry>General container requirements</entry>
|
||||||
<entry>Partial</entry>
|
<entry>Partial</entry>
|
||||||
<entry>Only <code>vector</code> meets the requirements
|
<entry>Only <code>vector</code> and <code>forward_list</code>
|
||||||
|
meet the requirements
|
||||||
relating to allocator use and propagation.</entry>
|
relating to allocator use and propagation.</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
|
|
|
||||||
|
|
@ -266,11 +266,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
struct _Fwd_list_base
|
struct _Fwd_list_base
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
|
typedef typename __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
|
||||||
|
typedef typename _Alloc_traits::template rebind<_Tp>::other
|
||||||
|
_Tp_alloc_type;
|
||||||
|
|
||||||
typedef typename _Alloc::template
|
typedef typename _Alloc_traits::template
|
||||||
rebind<_Fwd_list_node<_Tp>>::other _Node_alloc_type;
|
rebind<_Fwd_list_node<_Tp>>::other _Node_alloc_type;
|
||||||
|
|
||||||
|
typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
|
||||||
|
|
||||||
struct _Fwd_list_impl
|
struct _Fwd_list_impl
|
||||||
: public _Node_alloc_type
|
: public _Node_alloc_type
|
||||||
{
|
{
|
||||||
|
|
@ -312,12 +316,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
|
|
||||||
_Fwd_list_base(const _Fwd_list_base& __lst, const _Node_alloc_type& __a);
|
_Fwd_list_base(const _Fwd_list_base& __lst, const _Node_alloc_type& __a);
|
||||||
|
|
||||||
_Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
|
_Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a);
|
||||||
: _M_impl(__a)
|
|
||||||
{
|
|
||||||
this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
|
|
||||||
__lst._M_impl._M_head._M_next = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Fwd_list_base(_Fwd_list_base&& __lst)
|
_Fwd_list_base(_Fwd_list_base&& __lst)
|
||||||
: _M_impl(std::move(__lst._M_get_Node_allocator()))
|
: _M_impl(std::move(__lst._M_get_Node_allocator()))
|
||||||
|
|
@ -333,7 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
|
|
||||||
_Node*
|
_Node*
|
||||||
_M_get_node()
|
_M_get_node()
|
||||||
{ return _M_get_Node_allocator().allocate(1); }
|
{ return _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); }
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
_Node*
|
_Node*
|
||||||
|
|
@ -342,8 +341,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
_Node* __node = this->_M_get_node();
|
_Node* __node = this->_M_get_node();
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
_M_get_Node_allocator().construct(__node,
|
_Node_alloc_traits::construct(_M_get_Node_allocator(), __node,
|
||||||
std::forward<_Args>(__args)...);
|
std::forward<_Args>(__args)...);
|
||||||
__node->_M_next = 0;
|
__node->_M_next = 0;
|
||||||
}
|
}
|
||||||
__catch(...)
|
__catch(...)
|
||||||
|
|
@ -360,7 +359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_put_node(_Node* __p)
|
_M_put_node(_Node* __p)
|
||||||
{ _M_get_Node_allocator().deallocate(__p, 1); }
|
{ _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
|
||||||
|
|
||||||
_Fwd_list_node_base*
|
_Fwd_list_node_base*
|
||||||
_M_erase_after(_Fwd_list_node_base* __pos);
|
_M_erase_after(_Fwd_list_node_base* __pos);
|
||||||
|
|
@ -413,14 +412,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
typedef _Fwd_list_node_base _Node_base;
|
typedef _Fwd_list_node_base _Node_base;
|
||||||
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
|
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
|
||||||
typedef typename _Base::_Node_alloc_type _Node_alloc_type;
|
typedef typename _Base::_Node_alloc_type _Node_alloc_type;
|
||||||
|
typedef typename _Base::_Node_alloc_traits _Node_alloc_traits;
|
||||||
|
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// types:
|
// types:
|
||||||
typedef _Tp value_type;
|
typedef _Tp value_type;
|
||||||
typedef typename _Tp_alloc_type::pointer pointer;
|
typedef typename _Alloc_traits::pointer pointer;
|
||||||
typedef typename _Tp_alloc_type::const_pointer const_pointer;
|
typedef typename _Alloc_traits::const_pointer const_pointer;
|
||||||
typedef typename _Tp_alloc_type::reference reference;
|
typedef typename _Alloc_traits::reference reference;
|
||||||
typedef typename _Tp_alloc_type::const_reference const_reference;
|
typedef typename _Alloc_traits::const_reference const_reference;
|
||||||
|
|
||||||
typedef _Fwd_list_iterator<_Tp> iterator;
|
typedef _Fwd_list_iterator<_Tp> iterator;
|
||||||
typedef _Fwd_list_const_iterator<_Tp> const_iterator;
|
typedef _Fwd_list_const_iterator<_Tp> const_iterator;
|
||||||
|
|
@ -504,12 +505,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
* @brief The %forward_list copy constructor.
|
* @brief The %forward_list copy constructor.
|
||||||
* @param __list A %forward_list of identical element and allocator
|
* @param __list A %forward_list of identical element and allocator
|
||||||
* types.
|
* types.
|
||||||
*
|
|
||||||
* The newly-created %forward_list uses a copy of the allocation
|
|
||||||
* object used by @a __list.
|
|
||||||
*/
|
*/
|
||||||
forward_list(const forward_list& __list)
|
forward_list(const forward_list& __list)
|
||||||
: _Base(__list._M_get_Node_allocator())
|
: _Base(_Node_alloc_traits::_S_select_on_copy(
|
||||||
|
__list._M_get_Node_allocator()))
|
||||||
{ _M_range_initialize(__list.begin(), __list.end()); }
|
{ _M_range_initialize(__list.begin(), __list.end()); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -560,16 +559,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
* types.
|
* types.
|
||||||
*
|
*
|
||||||
* The contents of @a __list are moved into this %forward_list
|
* The contents of @a __list are moved into this %forward_list
|
||||||
* (without copying). @a __list is a valid, but unspecified
|
* (without copying, if the allocators permit it).
|
||||||
* %forward_list
|
* @a __list is a valid, but unspecified %forward_list
|
||||||
*/
|
*/
|
||||||
forward_list&
|
forward_list&
|
||||||
operator=(forward_list&& __list)
|
operator=(forward_list&& __list)
|
||||||
|
noexcept(_Node_alloc_traits::_S_nothrow_move())
|
||||||
{
|
{
|
||||||
// NB: DR 1204.
|
constexpr bool __move_storage =
|
||||||
// NB: DR 675.
|
_Node_alloc_traits::_S_propagate_on_move_assign()
|
||||||
this->clear();
|
|| _Node_alloc_traits::_S_always_equal();
|
||||||
this->swap(__list);
|
_M_move_assign(std::move(__list),
|
||||||
|
integral_constant<bool, __move_storage>());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -740,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
*/
|
*/
|
||||||
size_type
|
size_type
|
||||||
max_size() const noexcept
|
max_size() const noexcept
|
||||||
{ return this->_M_get_Node_allocator().max_size(); }
|
{ return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); }
|
||||||
|
|
||||||
// 23.2.3.3 element access:
|
// 23.2.3.3 element access:
|
||||||
|
|
||||||
|
|
@ -981,8 +982,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
swap(forward_list& __list)
|
swap(forward_list& __list)
|
||||||
{ std::swap(this->_M_impl._M_head._M_next,
|
noexcept(_Node_alloc_traits::_S_nothrow_swap())
|
||||||
__list._M_impl._M_head._M_next); }
|
{
|
||||||
|
std::swap(this->_M_impl._M_head._M_next,
|
||||||
|
__list._M_impl._M_head._M_next);
|
||||||
|
_Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(),
|
||||||
|
__list._M_get_Node_allocator());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resizes the %forward_list to the specified number of
|
* @brief Resizes the %forward_list to the specified number of
|
||||||
|
|
@ -1239,6 +1245,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
// Called by resize(sz).
|
// Called by resize(sz).
|
||||||
void
|
void
|
||||||
_M_default_insert_after(const_iterator __pos, size_type __n);
|
_M_default_insert_after(const_iterator __pos, size_type __n);
|
||||||
|
|
||||||
|
// Called by operator=(forward_list&&)
|
||||||
|
void
|
||||||
|
_M_move_assign(forward_list&& __list, std::true_type) noexcept
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
std::swap(this->_M_impl._M_head._M_next,
|
||||||
|
__list._M_impl._M_head._M_next);
|
||||||
|
std::__alloc_on_move(this->_M_get_Node_allocator(),
|
||||||
|
__list._M_get_Node_allocator());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by operator=(forward_list&&)
|
||||||
|
void
|
||||||
|
_M_move_assign(forward_list&& __list, std::false_type)
|
||||||
|
{
|
||||||
|
if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator())
|
||||||
|
_M_move_assign(std::move(__list), std::true_type());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The rvalue's allocator cannot be moved, or is not equal,
|
||||||
|
// so we need to individually move each element.
|
||||||
|
this->assign(std::__make_move_if_noexcept_iterator(__list.begin()),
|
||||||
|
std::__make_move_if_noexcept_iterator(__list.end()));
|
||||||
|
__list.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename _Tp, typename _Alloc>
|
||||||
|
_Fwd_list_base<_Tp, _Alloc>::
|
||||||
|
_Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a)
|
||||||
|
: _M_impl(__a)
|
||||||
|
{
|
||||||
|
if (__lst._M_get_Node_allocator() == __a)
|
||||||
|
this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->_M_impl._M_head._M_next = 0;
|
||||||
|
_Fwd_list_node_base* __to = &this->_M_impl._M_head;
|
||||||
|
_Node* __curr = static_cast<_Node*>(__lst._M_impl._M_head._M_next);
|
||||||
|
|
||||||
|
while (__curr)
|
||||||
|
{
|
||||||
|
__to->_M_next =
|
||||||
|
_M_create_node(std::move_if_noexcept(__curr->_M_value));
|
||||||
|
__to = __to->_M_next;
|
||||||
|
__curr = static_cast<_Node*>(__curr->_M_next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__lst._M_impl._M_head._M_next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename _Tp, typename _Alloc>
|
template<typename _Tp, typename _Alloc>
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
_Fwd_list_node_base*
|
_Fwd_list_node_base*
|
||||||
|
|
@ -72,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
{
|
{
|
||||||
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
|
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
|
||||||
__pos->_M_next = __curr->_M_next;
|
__pos->_M_next = __curr->_M_next;
|
||||||
_M_get_Node_allocator().destroy(__curr);
|
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __curr);
|
||||||
_M_put_node(__curr);
|
_M_put_node(__curr);
|
||||||
return __pos->_M_next;
|
return __pos->_M_next;
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +112,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
{
|
{
|
||||||
_Node* __temp = __curr;
|
_Node* __temp = __curr;
|
||||||
__curr = static_cast<_Node*>(__curr->_M_next);
|
__curr = static_cast<_Node*>(__curr->_M_next);
|
||||||
_M_get_Node_allocator().destroy(__temp);
|
_Node_alloc_traits::destroy(_M_get_Node_allocator(), __temp);
|
||||||
_M_put_node(__temp);
|
_M_put_node(__temp);
|
||||||
}
|
}
|
||||||
__pos->_M_next = __last;
|
__pos->_M_next = __last;
|
||||||
|
|
@ -144,6 +168,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
{
|
{
|
||||||
if (&__list != this)
|
if (&__list != this)
|
||||||
{
|
{
|
||||||
|
if (_Node_alloc_traits::_S_propagate_on_copy_assign())
|
||||||
|
{
|
||||||
|
auto& __this_alloc = this->_M_get_Node_allocator();
|
||||||
|
auto& __that_alloc = __list._M_get_Node_allocator();
|
||||||
|
if (!_Node_alloc_traits::_S_always_equal()
|
||||||
|
&& __this_alloc != __that_alloc)
|
||||||
|
{
|
||||||
|
// replacement allocator cannot free existing storage
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
std::__alloc_on_copy(__this_alloc, __that_alloc);
|
||||||
|
}
|
||||||
iterator __prev1 = before_begin();
|
iterator __prev1 = before_begin();
|
||||||
iterator __curr1 = begin();
|
iterator __curr1 = begin();
|
||||||
iterator __last1 = end();
|
iterator __last1 = end();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright (C) 2012 Free Software Foundation
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct T { int i; };
|
||||||
|
|
||||||
|
using __gnu_test::propagating_allocator;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, false> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(v1);
|
||||||
|
VERIFY(1 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(0 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test02()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, true> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(v1);
|
||||||
|
VERIFY(1 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(1 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
test02();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (C) 2012 Free Software Foundation
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct T { int i; };
|
||||||
|
|
||||||
|
using __gnu_test::propagating_allocator;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, false> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
v2 = v1;
|
||||||
|
VERIFY(1 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(2 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test02()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, true> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
v2 = v1;
|
||||||
|
VERIFY(1 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(1 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
test02();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (C) 2012 Free Software Foundation
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <memory>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct T { int i; };
|
||||||
|
bool operator==(const T& l, const T& r) { return l.i == r.i; }
|
||||||
|
bool operator<(const T& l, const T& r) { return l.i < r.i; }
|
||||||
|
|
||||||
|
using __gnu_test::SimpleAllocator;
|
||||||
|
|
||||||
|
template class std::forward_list<T, SimpleAllocator<T>>;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef SimpleAllocator<T> alloc_type;
|
||||||
|
typedef std::allocator_traits<alloc_type> traits_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v(alloc_type{});
|
||||||
|
VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (C) 2012 Free Software Foundation
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct T { int i; };
|
||||||
|
|
||||||
|
using __gnu_test::propagating_allocator;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, false> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
v2 = std::move(v1);
|
||||||
|
VERIFY(1 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(2 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test02()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, true> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
v2 = std::move(v1);
|
||||||
|
VERIFY(0 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(1 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
test02();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright (C) 2012 Free Software Foundation
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct T { int i; };
|
||||||
|
|
||||||
|
namespace __gnu_test
|
||||||
|
{
|
||||||
|
inline void
|
||||||
|
swap(propagating_allocator<T, true>& l, propagating_allocator<T, true>& r)
|
||||||
|
noexcept(false)
|
||||||
|
{
|
||||||
|
typedef uneq_allocator<T> base_alloc;
|
||||||
|
swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using __gnu_test::propagating_allocator;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
typedef std::allocator<T> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1;
|
||||||
|
test_type v2;
|
||||||
|
// this is a GNU extension for std::allocator
|
||||||
|
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
|
||||||
|
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void test02()
|
||||||
|
{
|
||||||
|
typedef propagating_allocator<T, false> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
|
||||||
|
static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void test03()
|
||||||
|
{
|
||||||
|
typedef propagating_allocator<T, true> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
|
||||||
|
// static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
test02();
|
||||||
|
test03();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (C) 2012 Free Software Foundation
|
||||||
|
//
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// { dg-options "-std=gnu++0x" }
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
struct T { int i; };
|
||||||
|
|
||||||
|
using __gnu_test::propagating_allocator;
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, false> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
std::swap(v1, v2);
|
||||||
|
VERIFY(1 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(2 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test02()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
typedef propagating_allocator<T, true> alloc_type;
|
||||||
|
typedef std::forward_list<T, alloc_type> test_type;
|
||||||
|
test_type v1(alloc_type(1));
|
||||||
|
test_type v2(alloc_type(2));
|
||||||
|
std::swap(v1, v2);
|
||||||
|
VERIFY(2 == v1.get_allocator().get_personality());
|
||||||
|
VERIFY(1 == v2.get_allocator().get_personality());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
test02();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue