forward_list: Update to meet allocator-aware requirements.
* include/profile/forward_list: Update to meet allocator-aware requirements. * include/debug/forward_list: Likewise. * include/debug/vector: Verify allocators are swapped or equal. * include/debug/macros.h (__glibcxx_check_equal_allocs): Define. * include/debug/formatter.h: Add new debug message. * src/c++11/debug.cc: Likewise. * testsuite/23_containers/forward_list/allocator/swap.cc: Do not swap containers with non-propagating, non-equal allocators. * testsuite/23_containers/vector/allocator/swap.cc: Likewise. From-SVN: r193186
This commit is contained in:
parent
684592672f
commit
e77c9aedcd
9 changed files with 95 additions and 18 deletions
|
@ -1,3 +1,16 @@
|
|||
2012-11-05 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
* include/profile/forward_list: Update to meet allocator-aware
|
||||
requirements.
|
||||
* include/debug/forward_list: Likewise.
|
||||
* include/debug/vector: Verify allocators are swapped or equal.
|
||||
* include/debug/macros.h (__glibcxx_check_equal_allocs): Define.
|
||||
* include/debug/formatter.h: Add new debug message.
|
||||
* src/c++11/debug.cc: Likewise.
|
||||
* testsuite/23_containers/forward_list/allocator/swap.cc: Do not
|
||||
swap containers with non-propagating, non-equal allocators.
|
||||
* testsuite/23_containers/vector/allocator/swap.cc: Likewise.
|
||||
|
||||
2012-11-05 Benjamin Kosnik <bkoz@redhat.com>
|
||||
Oleg Smolsky <oleg@smolsky.net>
|
||||
|
||||
|
|
|
@ -114,7 +114,8 @@ namespace __gnu_debug
|
|||
__msg_self_move_assign,
|
||||
// unordered container buckets
|
||||
__msg_bucket_index_oob,
|
||||
__msg_valid_load_factor
|
||||
__msg_valid_load_factor,
|
||||
__msg_equal_allocs
|
||||
};
|
||||
|
||||
class _Error_formatter
|
||||
|
|
|
@ -49,6 +49,12 @@ namespace __debug
|
|||
|
||||
typedef typename _Base::iterator _Base_iterator;
|
||||
typedef typename _Base::const_iterator _Base_const_iterator;
|
||||
|
||||
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
|
||||
rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
|
||||
|
||||
typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
|
||||
|
||||
public:
|
||||
typedef typename _Base::reference reference;
|
||||
typedef typename _Base::const_reference const_reference;
|
||||
|
@ -78,12 +84,15 @@ namespace __debug
|
|||
forward_list(forward_list&& __list, const _Alloc& __al)
|
||||
: _Base(std::move(__list._M_base()), __al)
|
||||
{
|
||||
this->_M_swap(__list);
|
||||
if (__list.get_allocator() == __al)
|
||||
this->_M_swap(__list);
|
||||
else
|
||||
__list._M_invalidate_all();
|
||||
}
|
||||
|
||||
explicit
|
||||
forward_list(size_type __n)
|
||||
: _Base(__n)
|
||||
forward_list(size_type __n, const _Alloc& __al = _Alloc())
|
||||
: _Base(__n, __al)
|
||||
{ }
|
||||
|
||||
forward_list(size_type __n, const _Tp& __value,
|
||||
|
@ -128,12 +137,17 @@ namespace __debug
|
|||
|
||||
forward_list&
|
||||
operator=(forward_list&& __list)
|
||||
noexcept(_Node_alloc_traits::_S_nothrow_move())
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
__glibcxx_check_self_move_assign(__list);
|
||||
clear();
|
||||
swap(__list);
|
||||
bool xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign()
|
||||
|| __list.get_allocator() == this->get_allocator();
|
||||
static_cast<_Base&>(*this) = std::move(__list);
|
||||
if (xfer_memory)
|
||||
this->_M_swap(__list);
|
||||
else
|
||||
this->_M_invalidate_all();
|
||||
__list._M_invalidate_all();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -333,7 +347,10 @@ namespace __debug
|
|||
|
||||
void
|
||||
swap(forward_list& __list)
|
||||
noexcept(_Node_alloc_traits::_S_nothrow_swap())
|
||||
{
|
||||
if (!_Node_alloc_traits::_S_propagate_on_swap())
|
||||
__glibcxx_check_equal_allocs(__list);
|
||||
_Base::swap(__list);
|
||||
this->_M_swap(__list);
|
||||
}
|
||||
|
|
|
@ -333,6 +333,11 @@ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \
|
|||
_M_message(__gnu_debug::__msg_valid_load_factor) \
|
||||
._M_sequence(*this, "this"))
|
||||
|
||||
#define __glibcxx_check_equal_allocs(_Other) \
|
||||
_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \
|
||||
_M_message(__gnu_debug::__msg_equal_allocs) \
|
||||
._M_sequence(*this, "this"))
|
||||
|
||||
#ifdef _GLIBCXX_DEBUG_PEDANTIC
|
||||
# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
|
||||
# define __glibcxx_check_string_len(_String,_Len) \
|
||||
|
|
|
@ -550,6 +550,10 @@ namespace __debug
|
|||
noexcept(_Alloc_traits::_S_nothrow_swap())
|
||||
#endif
|
||||
{
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
if (!_Alloc_traits::_S_propagate_on_swap())
|
||||
__glibcxx_check_equal_allocs(__x);
|
||||
#endif
|
||||
_Base::swap(__x);
|
||||
this->_M_swap(__x);
|
||||
std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// <forward_list> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2010-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
|
||||
|
@ -46,10 +46,14 @@ namespace __profile
|
|||
{
|
||||
typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
|
||||
|
||||
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
|
||||
rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
|
||||
|
||||
typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
|
||||
|
||||
public:
|
||||
typedef typename _Base::size_type size_type;
|
||||
|
||||
public:
|
||||
// 23.2.3.1 construct/copy/destroy:
|
||||
explicit
|
||||
forward_list(const _Alloc& __al = _Alloc())
|
||||
|
@ -64,8 +68,8 @@ namespace __profile
|
|||
{ }
|
||||
|
||||
explicit
|
||||
forward_list(size_type __n)
|
||||
: _Base(__n)
|
||||
forward_list(size_type __n, const _Alloc& __al = _Alloc())
|
||||
: _Base(__n, __al)
|
||||
{ }
|
||||
|
||||
forward_list(size_type __n, const _Tp& __value,
|
||||
|
@ -103,11 +107,9 @@ namespace __profile
|
|||
|
||||
forward_list&
|
||||
operator=(forward_list&& __list)
|
||||
noexcept(_Node_alloc_traits::_S_nothrow_move())
|
||||
{
|
||||
// NB: DR 1204.
|
||||
// NB: DR 675.
|
||||
_Base::clear();
|
||||
_Base::swap(__list);
|
||||
static_cast<_Base&>(*this) = std::move(__list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,8 @@ namespace __gnu_debug
|
|||
"attempt to self move assign",
|
||||
"attempt to access container with out-of-bounds bucket index %2;,"
|
||||
" container only holds %3; buckets",
|
||||
"load factor shall be positive"
|
||||
"load factor shall be positive",
|
||||
"allocators must be equal"
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -25,6 +25,23 @@ struct T { int i; };
|
|||
|
||||
using __gnu_test::propagating_allocator;
|
||||
|
||||
// It is undefined behaviour to swap() containers wth unequal allocators
|
||||
// if the allocator doesn't propagate, so ensure the allocators compare
|
||||
// equal, while still being able to test propagation via get_personality().
|
||||
bool
|
||||
operator==(const propagating_allocator<T, false>&,
|
||||
const propagating_allocator<T, false>&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const propagating_allocator<T, false>&,
|
||||
const propagating_allocator<T, false>&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2011 Free Software Foundation
|
||||
// Copyright (C) 2011-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
|
||||
|
@ -25,6 +25,23 @@ struct T { int i; };
|
|||
|
||||
using __gnu_test::propagating_allocator;
|
||||
|
||||
// It is undefined behaviour to swap() containers wth unequal allocators
|
||||
// if the allocator doesn't propagate, so ensure the allocators compare
|
||||
// equal, while still being able to test propagation via get_personality().
|
||||
bool
|
||||
operator==(const propagating_allocator<T, false>&,
|
||||
const propagating_allocator<T, false>&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const propagating_allocator<T, false>&,
|
||||
const propagating_allocator<T, false>&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
|
Loading…
Add table
Reference in a new issue