Commit 15ee1a77 by François Dumont

macros.h [...]: Add parameter to pass the 2 instances to check allocator equality.

2014-05-06  François Dumont  <fdumont@gcc.gnu.org>

	* include/debug/macros.h [__glibcxx_check_equal_allocs]: Add
	parameter to pass the 2 instances to check allocator equality.
	* include/debug/safe_container.h: New, define _Safe_container<>.
	* include/Makefile.am: Add previous.
	* include/debug/deque (std::__debug::deque<>): Inherit
	_Safe_container<>. Use default implementation for all special
	functions.
	* include/debug/forward_list (std::__debug::forward_list<>):
	Likewise.
	* include/debug/list (std::__debug::list<>): Likewise.
	* include/debug/map.h (std::__debug::map<>): Likewise.
	* include/debug/multimap.h (std::__debug::multimap<>): Likewise.
	* include/debug/set.h (std::__debug::set<>): Likewise.
	* include/debug/multiset.h (std::__debug::multiset<>): Likewise.
	* include/debug/string (std::__debug::basic_string<>): Likewise.
	* include/debug/unordered_map
	(std::__debug::unordered_map<>): Likewise.
	(std::__debug::unordered_multimap<>): Likewise.
	* include/debug/unordered_set
	(std::__debug::unordered_set<>): Likewise.
	(std::__debug::unordered_multiset<>): Likewise.
	* include/debug/vector (std::__debug::vector<>): Likewise.
	* include/debug/safe_base.h (_Safe_sequence_base()): Add
	noexcept.
	(_Safe_sequence_base(_Safe_sequence_base&&): Remove.
	(~_Safe_sequence_base()): Add noexcept.
	* include/debug/safe_sequence.h
	(std::__debug::_Safe_node_sequence<>): New.
	* include/debug/safe_unordered_base.h
	(_Safe_unordered_container_base()): Add noexcept.
	(~_Safe_unordered_container_base()): Likewise.
	(_M_swap(_Safe_unordered_container_base&)): Likewise.
	* include/debug/safe_unordered_container.h:
	(_Safe_unordered_container<>::_M_invalidate_locals()): New.
	(_Safe_unordered_container<>::_M_invalidate_all()): New.
	* src/c++11/debug.cc: Limit includes, adapt methods noexcept
	qualifications.
	* testsuite/util/debug/checks.h (check_construct1): Just implement
	an invalid constructor invocation  and no other operations
	potentially not supported by some types of container.
	(check_construct2): Likewise.
	(check_construct3): Likewise.
	* testsuite/23_containers/forward_list/allocator/move.cc: Add
	check on iterators to make sure they are correctly moved in debug
	mode.
	* testsuite/23_containers/forward_list/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/map/allocator/move.cc: Likewise.
	* testsuite/23_containers/map/allocator/move_assign.cc: Likewise.
	* testsuite/23_containers/multimap/allocator/move.cc: Likewise.
	* testsuite/23_containers/multimap/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/multiset/allocator/move.cc: Likewise.
	* testsuite/23_containers/multiset/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/set/allocator/move.cc: Likewise.
	* testsuite/23_containers/set/allocator/move_assign.cc: Likewise.
	* testsuite/23_containers/unordered_map/allocator/move.cc:
	Likewise.
	* testsuite/23_containers/unordered_map/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/unordered_multimap/allocator/move.cc:
	Likewise.
	* testsuite/23_containers/unordered_multimap/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/unordered_multiset/allocator/move.cc:
	Likewise.
	* testsuite/23_containers/unordered_multiset/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/unordered_set/allocator/move.cc:
	Likewise.
	* testsuite/23_containers/unordered_set/allocator/move_assign.cc:
	Likewise.
	* testsuite/23_containers/forward_list/debug/construct1_neg.cc:
	New.
	* testsuite/23_containers/forward_list/debug/construct2_neg.cc:
	New.
	* testsuite/23_containers/forward_list/debug/construct3_neg.cc:
	New.
	* testsuite/23_containers/forward_list/debug/construct4_neg.cc:
	New.
	* testsuite/23_containers/forward_list/debug/move_assign_neg.cc:
	New.
	* testsuite/23_containers/forward_list/debug/move_neg.cc: New.
	* testsuite/23_containers/map/debug/construct5_neg.cc: New.
	* testsuite/23_containers/map/debug/move_assign_neg.cc: New.
	* testsuite/23_containers/map/debug/move_neg.cc: New.
	* testsuite/23_containers/multimap/debug/construct5_neg.cc: New.
	* testsuite/23_containers/multimap/debug/move_assign_neg.cc: New.
	* testsuite/23_containers/multimap/debug/move_neg.cc: New.
	* testsuite/23_containers/multiset/debug/construct5_neg.cc: New.
	* testsuite/23_containers/multiset/debug/move_assign_neg.cc: New.
	* testsuite/23_containers/multiset/debug/move_neg.cc: New.
	* testsuite/23_containers/set/debug/construct5_neg.cc: New.
	* testsuite/23_containers/set/debug/move_assign_neg.cc: New.
	* testsuite/23_containers/set/debug/move_neg.cc: New.
	* testsuite/23_containers/unordered_map/debug/construct5_neg.cc:
	New.
	* testsuite/23_containers/unordered_map/debug/move_assign_neg.cc:
	New.
	* testsuite/23_containers/unordered_map/debug/move_neg.cc: New.
	* testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc:
	New.
	* testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc:
	New.
	* testsuite/23_containers/unordered_multimap/debug/move_neg.cc:
	New.
	* testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc:
	New.
	* testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc:
	New.
	* testsuite/23_containers/unordered_multiset/debug/move_neg.cc:
	New.
	* testsuite/23_containers/unordered_set/debug/construct5_neg.cc:
	New.
	* testsuite/23_containers/unordered_set/debug/move_assign_neg.cc:
	New.
	* testsuite/23_containers/unordered_set/debug/move_neg.cc: New.
	* testsuite/23_containers/vector/debug/move_neg.cc: New.

From-SVN: r210123
parent 6f7e0b57
2014-05-06 François Dumont <fdumont@gcc.gnu.org>
* include/debug/macros.h [__glibcxx_check_equal_allocs]: Add
parameter to pass the 2 instances to check allocator equality.
* include/debug/safe_container.h: New, define _Safe_container<>.
* include/Makefile.am: Add previous.
* include/debug/deque (std::__debug::deque<>): Inherit
_Safe_container<>. Use default implementation for all special
functions.
* include/debug/forward_list (std::__debug::forward_list<>):
Likewise.
* include/debug/list (std::__debug::list<>): Likewise.
* include/debug/map.h (std::__debug::map<>): Likewise.
* include/debug/multimap.h (std::__debug::multimap<>): Likewise.
* include/debug/set.h (std::__debug::set<>): Likewise.
* include/debug/multiset.h (std::__debug::multiset<>): Likewise.
* include/debug/string (std::__debug::basic_string<>): Likewise.
* include/debug/unordered_map
(std::__debug::unordered_map<>): Likewise.
(std::__debug::unordered_multimap<>): Likewise.
* include/debug/unordered_set
(std::__debug::unordered_set<>): Likewise.
(std::__debug::unordered_multiset<>): Likewise.
* include/debug/vector (std::__debug::vector<>): Likewise.
* include/debug/safe_base.h (_Safe_sequence_base()): Add
noexcept.
(_Safe_sequence_base(_Safe_sequence_base&&): Remove.
(~_Safe_sequence_base()): Add noexcept.
* include/debug/safe_sequence.h
(std::__debug::_Safe_node_sequence<>): New.
* include/debug/safe_unordered_base.h
(_Safe_unordered_container_base()): Add noexcept.
(~_Safe_unordered_container_base()): Likewise.
(_M_swap(_Safe_unordered_container_base&)): Likewise.
* include/debug/safe_unordered_container.h:
(_Safe_unordered_container<>::_M_invalidate_locals()): New.
(_Safe_unordered_container<>::_M_invalidate_all()): New.
* src/c++11/debug.cc: Limit includes, adapt methods noexcept
qualifications.
* testsuite/util/debug/checks.h (check_construct1): Just implement
an invalid constructor invocation and no other operations
potentially not supported by some types of container.
(check_construct2): Likewise.
(check_construct3): Likewise.
* testsuite/23_containers/forward_list/allocator/move.cc: Add
check on iterators to make sure they are correctly moved in debug
mode.
* testsuite/23_containers/forward_list/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/map/allocator/move.cc: Likewise.
* testsuite/23_containers/map/allocator/move_assign.cc: Likewise.
* testsuite/23_containers/multimap/allocator/move.cc: Likewise.
* testsuite/23_containers/multimap/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/multiset/allocator/move.cc: Likewise.
* testsuite/23_containers/multiset/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/set/allocator/move.cc: Likewise.
* testsuite/23_containers/set/allocator/move_assign.cc: Likewise.
* testsuite/23_containers/unordered_map/allocator/move.cc:
Likewise.
* testsuite/23_containers/unordered_map/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/unordered_multimap/allocator/move.cc:
Likewise.
* testsuite/23_containers/unordered_multimap/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/unordered_multiset/allocator/move.cc:
Likewise.
* testsuite/23_containers/unordered_multiset/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/unordered_set/allocator/move.cc:
Likewise.
* testsuite/23_containers/unordered_set/allocator/move_assign.cc:
Likewise.
* testsuite/23_containers/forward_list/debug/construct1_neg.cc:
New.
* testsuite/23_containers/forward_list/debug/construct2_neg.cc:
New.
* testsuite/23_containers/forward_list/debug/construct3_neg.cc:
New.
* testsuite/23_containers/forward_list/debug/construct4_neg.cc:
New.
* testsuite/23_containers/forward_list/debug/move_assign_neg.cc:
New.
* testsuite/23_containers/forward_list/debug/move_neg.cc: New.
* testsuite/23_containers/map/debug/construct5_neg.cc: New.
* testsuite/23_containers/map/debug/move_assign_neg.cc: New.
* testsuite/23_containers/map/debug/move_neg.cc: New.
* testsuite/23_containers/multimap/debug/construct5_neg.cc: New.
* testsuite/23_containers/multimap/debug/move_assign_neg.cc: New.
* testsuite/23_containers/multimap/debug/move_neg.cc: New.
* testsuite/23_containers/multiset/debug/construct5_neg.cc: New.
* testsuite/23_containers/multiset/debug/move_assign_neg.cc: New.
* testsuite/23_containers/multiset/debug/move_neg.cc: New.
* testsuite/23_containers/set/debug/construct5_neg.cc: New.
* testsuite/23_containers/set/debug/move_assign_neg.cc: New.
* testsuite/23_containers/set/debug/move_neg.cc: New.
* testsuite/23_containers/unordered_map/debug/construct5_neg.cc:
New.
* testsuite/23_containers/unordered_map/debug/move_assign_neg.cc:
New.
* testsuite/23_containers/unordered_map/debug/move_neg.cc: New.
* testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc:
New.
* testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc:
New.
* testsuite/23_containers/unordered_multimap/debug/move_neg.cc:
New.
* testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc:
New.
* testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc:
New.
* testsuite/23_containers/unordered_multiset/debug/move_neg.cc:
New.
* testsuite/23_containers/unordered_set/debug/construct5_neg.cc:
New.
* testsuite/23_containers/unordered_set/debug/move_assign_neg.cc:
New.
* testsuite/23_containers/unordered_set/debug/move_neg.cc: New.
* testsuite/23_containers/vector/debug/move_neg.cc: New.
2014-05-05 Andreas Schwab <schwab@linux-m68k.org> 2014-05-05 Andreas Schwab <schwab@linux-m68k.org>
* config/abi/post/ia64-linux-gnu/baseline_symbols.txt * config/abi/post/ia64-linux-gnu/baseline_symbols.txt
......
...@@ -733,6 +733,7 @@ debug_headers = \ ...@@ -733,6 +733,7 @@ debug_headers = \
${debug_srcdir}/multimap.h \ ${debug_srcdir}/multimap.h \
${debug_srcdir}/multiset.h \ ${debug_srcdir}/multiset.h \
${debug_srcdir}/safe_base.h \ ${debug_srcdir}/safe_base.h \
${debug_srcdir}/safe_container.h \
${debug_srcdir}/safe_iterator.h \ ${debug_srcdir}/safe_iterator.h \
${debug_srcdir}/safe_iterator.tcc \ ${debug_srcdir}/safe_iterator.tcc \
${debug_srcdir}/safe_local_iterator.h \ ${debug_srcdir}/safe_local_iterator.h \
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <deque> #include <deque>
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
namespace std _GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
...@@ -40,21 +41,26 @@ namespace __debug ...@@ -40,21 +41,26 @@ namespace __debug
/// Class std::deque with safety/checking/debug instrumentation. /// Class std::deque with safety/checking/debug instrumentation.
template<typename _Tp, typename _Allocator = std::allocator<_Tp> > template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class deque class deque
: public _GLIBCXX_STD_C::deque<_Tp, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> > deque<_Tp, _Allocator>, _Allocator,
__gnu_debug::_Safe_sequence, false>,
public _GLIBCXX_STD_C::deque<_Tp, _Allocator>
{ {
typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base; typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
deque, _Allocator, __gnu_debug::_Safe_sequence, false> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public: public:
typedef typename _Base::reference reference; typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference; typedef typename _Base::const_reference const_reference;
typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque> typedef __gnu_debug::_Safe_iterator<_Base_iterator, deque>
iterator; iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,deque> typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, deque>
const_iterator; const_iterator;
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
...@@ -69,7 +75,25 @@ namespace __debug ...@@ -69,7 +75,25 @@ namespace __debug
// 23.2.1.1 construct/copy/destroy: // 23.2.1.1 construct/copy/destroy:
deque() : _Base() { } #if __cplusplus < 201103L
deque()
: _Base() { }
deque(const deque& __x)
: _Base(__x) { }
~deque() { }
#else
deque() = default;
deque(const deque&) = default;
deque(deque&&) = default;
deque(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
~deque() = default;
#endif
explicit explicit
deque(const _Allocator& __a) deque(const _Allocator& __a)
...@@ -103,48 +127,28 @@ namespace __debug ...@@ -103,48 +127,28 @@ namespace __debug
__gnu_debug::__base(__last), __a) __gnu_debug::__base(__last), __a)
{ } { }
deque(const deque& __x)
: _Base(__x) { }
deque(const _Base& __x) deque(const _Base& __x)
: _Base(__x) { } : _Base(__x) { }
#if __cplusplus >= 201103L #if __cplusplus < 201103L
deque(deque&& __x)
: _Base(std::move(__x))
{ this->_M_swap(__x); }
deque(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
#endif
~deque() _GLIBCXX_NOEXCEPT { }
deque& deque&
operator=(const deque& __x) operator=(const deque& __x)
{ {
*static_cast<_Base*>(this) = __x; this->_M_safe() = __x;
this->_M_invalidate_all(); _M_base() = __x;
return *this; return *this;
} }
#else
deque&
operator=(const deque&) = default;
#if __cplusplus >= 201103L
deque& deque&
operator=(deque&& __x) noexcept operator=(deque&&) = default;
{
// NB: DR 1204.
// NB: DR 675.
__glibcxx_check_self_move_assign(__x);
clear();
swap(__x);
return *this;
}
deque& deque&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
*static_cast<_Base*>(this) = __l; _M_base() = __l;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
...@@ -559,10 +563,13 @@ namespace __debug ...@@ -559,10 +563,13 @@ namespace __debug
} }
void void
swap(deque& __x) _GLIBCXX_NOEXCEPT swap(deque& __x)
#if __cplusplus >= 201103L
noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{ {
_Safe::_M_swap(__x);
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
} }
void void
......
...@@ -33,8 +33,139 @@ ...@@ -33,8 +33,139 @@
#include <forward_list> #include <forward_list>
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
namespace __gnu_debug
{
/// Special iterators swap and invalidation for forward_list because of the
/// before_begin iterator.
template<typename _SafeSequence>
class _Safe_forward_list
: public _Safe_sequence<_SafeSequence>
{
_SafeSequence&
_M_this() noexcept
{ return *static_cast<_SafeSequence*>(this); }
static void
_M_swap_aux(_Safe_sequence_base& __lhs,
_Safe_iterator_base*& __lhs_iterators,
_Safe_sequence_base& __rhs,
_Safe_iterator_base*& __rhs_iterators);
void _M_swap_single(_Safe_sequence_base&) noexcept;
protected:
void
_M_invalidate_all()
{
using _Base_const_iterator = __decltype(_M_this()._M_base().cend());
this->_M_invalidate_if([this](_Base_const_iterator __it)
{
return __it != _M_this()._M_base().cbefore_begin()
&& __it != _M_this()._M_base().cend(); });
}
void _M_swap(_Safe_sequence_base&) noexcept;
};
template<typename _SafeSequence>
void
_Safe_forward_list<_SafeSequence>::
_M_swap_aux(_Safe_sequence_base& __lhs,
_Safe_iterator_base*& __lhs_iterators,
_Safe_sequence_base& __rhs,
_Safe_iterator_base*& __rhs_iterators)
{
using const_iterator = typename _SafeSequence::const_iterator;
_Safe_iterator_base* __bbegin_its = 0;
_Safe_iterator_base* __last_bbegin = 0;
_SafeSequence& __rseq = static_cast<_SafeSequence&>(__rhs);
for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
{
// Even iterator is cast to const_iterator, not a problem.
const_iterator* __victim = static_cast<const_iterator*>(__iter);
__iter = __iter->_M_next;
if (__victim->base() == __rseq._M_base().cbefore_begin())
{
__victim->_M_unlink();
if (__lhs_iterators == __victim)
__lhs_iterators = __victim->_M_next;
if (__bbegin_its)
{
__victim->_M_next = __bbegin_its;
__bbegin_its->_M_prior = __victim;
}
else
__last_bbegin = __victim;
__bbegin_its = __victim;
}
else
__victim->_M_sequence = &__lhs;
}
if (__bbegin_its)
{
if (__rhs_iterators)
{
__rhs_iterators->_M_prior = __last_bbegin;
__last_bbegin->_M_next = __rhs_iterators;
}
__rhs_iterators = __bbegin_its;
}
}
template<typename _SafeSequence>
void
_Safe_forward_list<_SafeSequence>::
_M_swap_single(_Safe_sequence_base& __other) noexcept
{
std::swap(_M_this()._M_iterators, __other._M_iterators);
std::swap(_M_this()._M_const_iterators, __other._M_const_iterators);
// Useless, always 1 on forward_list
//std::swap(_M_this()_M_version, __other._M_version);
_Safe_iterator_base* __this_its = _M_this()._M_iterators;
_M_swap_aux(__other, __other._M_iterators,
_M_this(), _M_this()._M_iterators);
_Safe_iterator_base* __this_const_its = _M_this()._M_const_iterators;
_M_swap_aux(__other, __other._M_const_iterators,
_M_this(), _M_this()._M_const_iterators);
_M_swap_aux(_M_this(), __this_its,
__other, __other._M_iterators);
_M_swap_aux(_M_this(), __this_const_its,
__other, __other._M_const_iterators);
}
/* Special forward_list _M_swap version that does not swap the
* before-begin ownership.*/
template<typename _SafeSequence>
void
_Safe_forward_list<_SafeSequence>::
_M_swap(_Safe_sequence_base& __other) noexcept
{
// We need to lock both sequences to swap
using namespace __gnu_cxx;
__mutex *__this_mutex = &_M_this()._M_get_mutex();
__mutex *__other_mutex =
&static_cast<_SafeSequence&>(__other)._M_get_mutex();
if (__this_mutex == __other_mutex)
{
__scoped_lock __lock(*__this_mutex);
_M_swap_single(__other);
}
else
{
__scoped_lock __l1(__this_mutex < __other_mutex
? *__this_mutex : *__other_mutex);
__scoped_lock __l2(__this_mutex < __other_mutex
? *__other_mutex : *__this_mutex);
_M_swap_single(__other);
}
}
}
namespace std _GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
{ {
namespace __debug namespace __debug
...@@ -42,119 +173,88 @@ namespace __debug ...@@ -42,119 +173,88 @@ namespace __debug
/// Class std::forward_list with safety/checking/debug instrumentation. /// Class std::forward_list with safety/checking/debug instrumentation.
template<typename _Tp, typename _Alloc = std::allocator<_Tp> > template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class forward_list class forward_list
: public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<forward_list<_Tp, _Alloc> > forward_list<_Tp, _Alloc>, _Alloc, __gnu_debug::_Safe_forward_list>,
public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>
{ {
typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base; typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
typedef __gnu_debug::_Safe_container<
forward_list, _Alloc, __gnu_debug::_Safe_forward_list> _Safe;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_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: public:
typedef typename _Base::reference reference; typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference; typedef typename _Base::const_reference const_reference;
typedef __gnu_debug::_Safe_iterator<_Base_iterator, typedef __gnu_debug::_Safe_iterator<
forward_list> iterator; _Base_iterator, forward_list> iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, typedef __gnu_debug::_Safe_iterator<
forward_list> const_iterator; _Base_const_iterator, forward_list> const_iterator;
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type; typedef typename _Base::difference_type difference_type;
typedef _Tp value_type; typedef _Tp value_type;
typedef _Alloc allocator_type; typedef typename _Base::allocator_type allocator_type;
typedef typename _Base::pointer pointer; typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer; typedef typename _Base::const_pointer const_pointer;
// 23.2.3.1 construct/copy/destroy: // 23.2.3.1 construct/copy/destroy:
explicit explicit
forward_list(const _Alloc& __al = _Alloc()) forward_list(const allocator_type& __al = allocator_type())
: _Base(__al) { } : _Base(__al) { }
forward_list(const forward_list& __list, const _Alloc& __al) forward_list(const forward_list& __list, const allocator_type& __al)
: _Base(__list, __al) : _Base(__list, __al)
{ } { }
forward_list(forward_list&& __list, const _Alloc& __al) forward_list(forward_list&& __list, const allocator_type& __al)
: _Base(std::move(__list._M_base()), __al) : _Safe(std::move(__list._M_safe()), __al),
{ _Base(std::move(__list._M_base()), __al)
if (__list.get_allocator() == __al) { }
this->_M_swap(__list);
else
__list._M_invalidate_all();
}
explicit explicit
forward_list(size_type __n, const _Alloc& __al = _Alloc()) forward_list(size_type __n, const allocator_type& __al = allocator_type())
: _Base(__n, __al) : _Base(__n, __al)
{ } { }
forward_list(size_type __n, const _Tp& __value, forward_list(size_type __n, const _Tp& __value,
const _Alloc& __al = _Alloc()) const allocator_type& __al = allocator_type())
: _Base(__n, __value, __al) : _Base(__n, __value, __al)
{ } { }
template<typename _InputIterator, template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>> typename = std::_RequireInputIter<_InputIterator>>
forward_list(_InputIterator __first, _InputIterator __last, forward_list(_InputIterator __first, _InputIterator __last,
const _Alloc& __al = _Alloc()) const allocator_type& __al = allocator_type())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)), __last)),
__gnu_debug::__base(__last), __al) __gnu_debug::__base(__last), __al)
{ } { }
forward_list(const forward_list& __list) forward_list(const forward_list&) = default;
: _Base(__list)
{ }
forward_list(forward_list&& __list) noexcept forward_list(forward_list&&) = default;
: _Base(std::move(__list._M_base()))
{
this->_M_swap(__list);
}
forward_list(std::initializer_list<_Tp> __il, forward_list(std::initializer_list<_Tp> __il,
const _Alloc& __al = _Alloc()) const allocator_type& __al = allocator_type())
: _Base(__il, __al) : _Base(__il, __al)
{ } { }
~forward_list() noexcept ~forward_list() = default;
{ }
forward_list& forward_list&
operator=(const forward_list& __list) operator=(const forward_list&) = default;
{
static_cast<_Base&>(*this) = __list;
this->_M_invalidate_all();
return *this;
}
forward_list& forward_list&
operator=(forward_list&& __list) operator=(forward_list&&) = default;
noexcept(_Node_alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__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;
}
forward_list& forward_list&
operator=(std::initializer_list<_Tp> __il) operator=(std::initializer_list<_Tp> __il)
{ {
static_cast<_Base&>(*this) = __il; _M_base() = __il;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
...@@ -347,12 +447,10 @@ namespace __debug ...@@ -347,12 +447,10 @@ namespace __debug
void void
swap(forward_list& __list) swap(forward_list& __list)
noexcept(_Node_alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__list)) )
{ {
if (!_Node_alloc_traits::_S_propagate_on_swap()) _Safe::_M_swap(__list);
__glibcxx_check_equal_allocs(__list);
_Base::swap(__list); _Base::swap(__list);
this->_M_swap(__list);
} }
void void
...@@ -644,93 +742,9 @@ namespace __debug ...@@ -644,93 +742,9 @@ namespace __debug
const _Base& const _Base&
_M_base() const noexcept { return *this; } _M_base() const noexcept { return *this; }
private:
void
_M_invalidate_all()
{
this->_M_invalidate_if([this](_Base_const_iterator __it)
{
return __it != this->_M_base().cbefore_begin()
&& __it != this->_M_base().cend();
});
}
typedef __gnu_debug::_Safe_iterator_base _Safe_iterator_base;
static void
_M_swap_aux(forward_list& __lhs,
_Safe_iterator_base*& __lhs_iterators,
forward_list& __rhs,
_Safe_iterator_base*& __rhs_iterators);
void _M_swap(forward_list& __list);
}; };
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_swap_aux(forward_list<_Tp, _Alloc>& __lhs,
__gnu_debug::_Safe_iterator_base*& __lhs_iterators,
forward_list<_Tp, _Alloc>& __rhs,
__gnu_debug::_Safe_iterator_base*& __rhs_iterators)
{
using __gnu_debug::_Safe_iterator_base;
_Safe_iterator_base* __bbegin_its = 0;
_Safe_iterator_base* __last_bbegin = 0;
for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
{
// Even iterator are casted to const_iterator, not a problem.
const_iterator* __victim = static_cast<const_iterator*>(__iter);
__iter = __iter->_M_next;
if (__victim->base() == __rhs._M_base().cbefore_begin())
{
__victim->_M_unlink();
if (__lhs_iterators == __victim)
__lhs_iterators = __victim->_M_next;
if (__bbegin_its)
{
__victim->_M_next = __bbegin_its;
__bbegin_its->_M_prior = __victim;
}
else
__last_bbegin = __victim;
__bbegin_its = __victim;
}
else
__victim->_M_sequence = &__lhs;
}
if (__bbegin_its)
{
if (__rhs_iterators)
{
__rhs_iterators->_M_prior = __last_bbegin;
__last_bbegin->_M_next = __rhs_iterators;
}
__rhs_iterators = __bbegin_its;
}
}
/* Special forward_list _M_swap version that do not swap the
* before-begin ownership.*/
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_swap(forward_list<_Tp, _Alloc>& __list)
{
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
std::swap(this->_M_iterators, __list._M_iterators);
std::swap(this->_M_const_iterators, __list._M_const_iterators);
// Useless, always 1 on forward_list
//std::swap(this->_M_version, __list._M_version);
_Safe_iterator_base* __this_its = this->_M_iterators;
_M_swap_aux(__list, __list._M_iterators, *this, this->_M_iterators);
_Safe_iterator_base* __this_const_its = this->_M_const_iterators;
_M_swap_aux(__list, __list._M_const_iterators, *this,
this->_M_const_iterators);
_M_swap_aux(*this, __this_its, __list, __list._M_iterators);
_M_swap_aux(*this, __this_const_its, __list, __list._M_const_iterators);
}
template<typename _Tp, typename _Alloc>
bool bool
operator==(const forward_list<_Tp, _Alloc>& __lx, operator==(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly) const forward_list<_Tp, _Alloc>& __ly)
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <list> #include <list>
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
namespace std _GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
...@@ -40,15 +41,20 @@ namespace __debug ...@@ -40,15 +41,20 @@ namespace __debug
/// Class std::list with safety/checking/debug instrumentation. /// Class std::list with safety/checking/debug instrumentation.
template<typename _Tp, typename _Allocator = std::allocator<_Tp> > template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class list class list
: public _GLIBCXX_STD_C::list<_Tp, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> > list<_Tp, _Allocator>, _Allocator,
__gnu_debug::_Safe_node_sequence, false>,
public _GLIBCXX_STD_C::list<_Tp, _Allocator>
{ {
typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base; typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
list, _Allocator, __gnu_debug::_Safe_node_sequence, false> _Safe;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
public: public:
typedef typename _Base::reference reference; typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference; typedef typename _Base::const_reference const_reference;
...@@ -70,9 +76,26 @@ namespace __debug ...@@ -70,9 +76,26 @@ namespace __debug
// 23.2.2.1 construct/copy/destroy: // 23.2.2.1 construct/copy/destroy:
list() _GLIBCXX_NOEXCEPT #if __cplusplus < 201103L
list()
: _Base() { } : _Base() { }
list(const list& __x)
: _Base(__x) { }
~list() { }
#else
list() = default;
list(const list&) = default;
list(list&&) = default;
list(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
~list() = default;
#endif
explicit explicit
list(const _Allocator& __a) _GLIBCXX_NOEXCEPT list(const _Allocator& __a) _GLIBCXX_NOEXCEPT
: _Base(__a) { } : _Base(__a) { }
...@@ -105,49 +128,29 @@ namespace __debug ...@@ -105,49 +128,29 @@ namespace __debug
__gnu_debug::__base(__last), __a) __gnu_debug::__base(__last), __a)
{ } { }
list(const list& __x)
: _Base(__x) { }
list(const _Base& __x) list(const _Base& __x)
: _Base(__x) { } : _Base(__x) { }
#if __cplusplus >= 201103L #if __cplusplus < 201103L
list(list&& __x) noexcept
: _Base(std::move(__x))
{ this->_M_swap(__x); }
list(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
: _Base(__l, __a) { }
#endif
~list() _GLIBCXX_NOEXCEPT { }
list& list&
operator=(const list& __x) operator=(const list& __x)
{ {
static_cast<_Base&>(*this) = __x; this->_M_safe() = __x;
this->_M_invalidate_all(); _M_base() = __x;
return *this; return *this;
} }
#else
list&
operator=(const list&) = default;
#if __cplusplus >= 201103L
list& list&
operator=(list&& __x) operator=(list&&) = default;
{
// NB: DR 1204.
// NB: DR 675.
__glibcxx_check_self_move_assign(__x);
clear();
swap(__x);
return *this;
}
list& list&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
static_cast<_Base&>(*this) = __l;
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_base() = __l;
return *this; return *this;
} }
...@@ -245,16 +248,14 @@ namespace __debug ...@@ -245,16 +248,14 @@ namespace __debug
{ {
this->_M_detach_singular(); this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end()) // if __sz < size(), invalidate all iterators in [begin + __sz, end())
_Base_iterator __victim = _Base::begin(); _Base_iterator __victim = _Base::begin();
_Base_iterator __end = _Base::end(); _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i) for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim; ++__victim;
for (; __victim != __end; ++__victim) for (; __victim != __end; ++__victim)
{
this->_M_invalidate_if(_Equal(__victim)); this->_M_invalidate_if(_Equal(__victim));
}
__try __try
{ {
...@@ -272,16 +273,14 @@ namespace __debug ...@@ -272,16 +273,14 @@ namespace __debug
{ {
this->_M_detach_singular(); this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end()) // if __sz < size(), invalidate all iterators in [begin + __sz, end())
_Base_iterator __victim = _Base::begin(); _Base_iterator __victim = _Base::begin();
_Base_iterator __end = _Base::end(); _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i) for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim; ++__victim;
for (; __victim != __end; ++__victim) for (; __victim != __end; ++__victim)
{
this->_M_invalidate_if(_Equal(__victim)); this->_M_invalidate_if(_Equal(__victim));
}
__try __try
{ {
...@@ -299,16 +298,14 @@ namespace __debug ...@@ -299,16 +298,14 @@ namespace __debug
{ {
this->_M_detach_singular(); this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end()) // if __sz < size(), invalidate all iterators in [begin + __sz, end())
_Base_iterator __victim = _Base::begin(); _Base_iterator __victim = _Base::begin();
_Base_iterator __end = _Base::end(); _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i) for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim; ++__victim;
for (; __victim != __end; ++__victim) for (; __victim != __end; ++__victim)
{
this->_M_invalidate_if(_Equal(__victim)); this->_M_invalidate_if(_Equal(__victim));
}
__try __try
{ {
...@@ -504,9 +501,12 @@ namespace __debug ...@@ -504,9 +501,12 @@ namespace __debug
void void
swap(list& __x) swap(list& __x)
#if __cplusplus >= 201103L
noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{ {
_Safe::_M_swap(__x);
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
} }
void void
...@@ -742,13 +742,6 @@ namespace __debug ...@@ -742,13 +742,6 @@ namespace __debug
const _Base& const _Base&
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
private:
void
_M_invalidate_all()
{
this->_M_invalidate_if(_Not_equal(_Base::end()));
}
}; };
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
......
...@@ -347,10 +347,10 @@ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \ ...@@ -347,10 +347,10 @@ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \
_M_message(__gnu_debug::__msg_valid_load_factor) \ _M_message(__gnu_debug::__msg_valid_load_factor) \
._M_sequence(*this, "this")) ._M_sequence(*this, "this"))
#define __glibcxx_check_equal_allocs(_Other) \ #define __glibcxx_check_equal_allocs(_This, _Other) \
_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \ _GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(), \
_M_message(__gnu_debug::__msg_equal_allocs) \ _M_message(__gnu_debug::__msg_equal_allocs) \
._M_sequence(*this, "this")) ._M_sequence(_This, "this"))
#ifdef _GLIBCXX_DEBUG_PEDANTIC #ifdef _GLIBCXX_DEBUG_PEDANTIC
# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) # define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_MAP_H 1 #define _GLIBCXX_DEBUG_MAP_H 1
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <utility> #include <utility>
...@@ -41,19 +42,20 @@ namespace __debug ...@@ -41,19 +42,20 @@ namespace __debug
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class map class map
: public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> > map<_Key, _Tp, _Compare, _Allocator>, _Allocator,
__gnu_debug::_Safe_node_sequence>,
public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>
{ {
typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base; typedef _GLIBCXX_STD_C::map<
_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
map, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
#if __cplusplus >= 201103L
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
#endif
public: public:
// types: // types:
typedef _Key key_type; typedef _Key key_type;
...@@ -78,32 +80,17 @@ namespace __debug ...@@ -78,32 +80,17 @@ namespace __debug
// 23.3.1.1 construct/copy/destroy: // 23.3.1.1 construct/copy/destroy:
#if __cplusplus < 201103L
map() : _Base() { } map() : _Base() { }
explicit map(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
map(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
map(const map& __x) map(const map& __x)
: _Base(__x) { } : _Base(__x) { }
map(const _Base& __x) ~map() { }
: _Base(__x) { } #else
map() = default;
#if __cplusplus >= 201103L map(const map&) = default;
map(map&& __x) map(map&&) = default;
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _Base(std::move(__x))
{ this->_M_swap(__x); }
map(initializer_list<value_type> __l, map(initializer_list<value_type> __l,
const _Compare& __c = _Compare(), const _Compare& __c = _Compare(),
...@@ -118,7 +105,8 @@ namespace __debug ...@@ -118,7 +105,8 @@ namespace __debug
: _Base(__m, __a) { } : _Base(__m, __a) { }
map(map&& __m, const allocator_type& __a) map(map&& __m, const allocator_type& __a)
: _Base(std::move(__m._M_base()), __a) { } : _Safe(std::move(__m._M_safe()), __a),
_Base(std::move(__m._M_base()), __a) { }
map(initializer_list<value_type> __l, const allocator_type& __a) map(initializer_list<value_type> __l, const allocator_type& __a)
: _Base(__l, __a) { } : _Base(__l, __a) { }
...@@ -130,34 +118,40 @@ namespace __debug ...@@ -130,34 +118,40 @@ namespace __debug
__last)), __last)),
__gnu_debug::__base(__last), __a) __gnu_debug::__base(__last), __a)
{ } { }
~map() = default;
#endif #endif
~map() _GLIBCXX_NOEXCEPT { } map(const _Base& __x)
: _Base(__x) { }
explicit map(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
map(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
#if __cplusplus < 201103L
map& map&
operator=(const map& __x) operator=(const map& __x)
{ {
this->_M_safe() = __x;
_M_base() = __x; _M_base() = __x;
this->_M_invalidate_all();
return *this; return *this;
} }
#else
map&
operator=(const map&) = default;
#if __cplusplus >= 201103L
map& map&
operator=(map&& __x) operator=(map&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
map& map&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
...@@ -395,15 +389,11 @@ namespace __debug ...@@ -395,15 +389,11 @@ namespace __debug
void void
swap(map& __x) swap(map& __x)
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif #endif
{ {
#if __cplusplus >= 201103L _Safe::_M_swap(__x);
if (!_Alloc_traits::_S_propagate_on_swap())
__glibcxx_check_equal_allocs(__x);
#endif
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
} }
void void
...@@ -467,14 +457,6 @@ namespace __debug ...@@ -467,14 +457,6 @@ namespace __debug
const _Base& const _Base&
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
private:
void
_M_invalidate_all()
{
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
this->_M_invalidate_if(_Not_equal(_M_base().end()));
}
}; };
template<typename _Key, typename _Tp, template<typename _Key, typename _Tp,
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_MULTIMAP_H 1 #define _GLIBCXX_DEBUG_MULTIMAP_H 1
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <utility> #include <utility>
...@@ -41,20 +42,20 @@ namespace __debug ...@@ -41,20 +42,20 @@ namespace __debug
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class multimap class multimap
: public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp, multimap<_Key, _Tp, _Compare, _Allocator>, _Allocator,
_Compare, _Allocator> > __gnu_debug::_Safe_node_sequence>,
public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>
{ {
typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base; typedef _GLIBCXX_STD_C::multimap<
_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
multimap, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
#if __cplusplus >= 201103L
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
#endif
public: public:
// types: // types:
typedef _Key key_type; typedef _Key key_type;
...@@ -79,32 +80,17 @@ namespace __debug ...@@ -79,32 +80,17 @@ namespace __debug
// 23.3.1.1 construct/copy/destroy: // 23.3.1.1 construct/copy/destroy:
#if __cplusplus < 201103L
multimap() : _Base() { } multimap() : _Base() { }
explicit multimap(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
multimap(const multimap& __x) multimap(const multimap& __x)
: _Base(__x) { } : _Base(__x) { }
multimap(const _Base& __x) ~multimap() { }
: _Base(__x) { } #else
multimap() = default;
#if __cplusplus >= 201103L multimap(const multimap&) = default;
multimap(multimap&& __x) multimap(multimap&&) = default;
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _Base(std::move(__x))
{ this->_M_swap(__x); }
multimap(initializer_list<value_type> __l, multimap(initializer_list<value_type> __l,
const _Compare& __c = _Compare(), const _Compare& __c = _Compare(),
...@@ -119,47 +105,52 @@ namespace __debug ...@@ -119,47 +105,52 @@ namespace __debug
: _Base(__m, __a) { } : _Base(__m, __a) { }
multimap(multimap&& __m, const allocator_type& __a) multimap(multimap&& __m, const allocator_type& __a)
: _Base(std::move(__m._M_base()), __a) { } : _Safe(std::move(__m._M_safe()), __a),
_Base(std::move(__m._M_base()), __a) { }
multimap(initializer_list<value_type> __l, const allocator_type& __a) multimap(initializer_list<value_type> __l, const allocator_type& __a)
: _Base(__l, __a) : _Base(__l, __a) { }
{ }
template<typename _InputIterator> template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last, multimap(_InputIterator __first, _InputIterator __last,
const allocator_type& __a) const allocator_type& __a)
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)), __last)),
__gnu_debug::__base(__last), __a) __gnu_debug::__base(__last), __a) { }
{ }
~multimap() = default;
#endif #endif
~multimap() _GLIBCXX_NOEXCEPT { } explicit multimap(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
multimap(const _Base& __x)
: _Base(__x) { }
#if __cplusplus < 201103L
multimap& multimap&
operator=(const multimap& __x) operator=(const multimap& __x)
{ {
this->_M_safe() = __x;
_M_base() = __x; _M_base() = __x;
this->_M_invalidate_all();
return *this; return *this;
} }
#else
multimap&
operator=(const multimap&) = default;
#if __cplusplus >= 201103L
multimap& multimap&
operator=(multimap&& __x) operator=(multimap&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
multimap& multimap&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
...@@ -379,15 +370,11 @@ namespace __debug ...@@ -379,15 +370,11 @@ namespace __debug
void void
swap(multimap& __x) swap(multimap& __x)
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif #endif
{ {
#if __cplusplus >= 201103L _Safe::_M_swap(__x);
if (!_Alloc_traits::_S_propagate_on_swap())
__glibcxx_check_equal_allocs(__x);
#endif
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
} }
void void
...@@ -451,14 +438,6 @@ namespace __debug ...@@ -451,14 +438,6 @@ namespace __debug
const _Base& const _Base&
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
private:
void
_M_invalidate_all()
{
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
this->_M_invalidate_if(_Not_equal(_Base::end()));
}
}; };
template<typename _Key, typename _Tp, template<typename _Key, typename _Tp,
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_MULTISET_H 1 #define _GLIBCXX_DEBUG_MULTISET_H 1
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <utility> #include <utility>
...@@ -41,19 +42,19 @@ namespace __debug ...@@ -41,19 +42,19 @@ namespace __debug
template<typename _Key, typename _Compare = std::less<_Key>, template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> > typename _Allocator = std::allocator<_Key> >
class multiset class multiset
: public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> > multiset<_Key, _Compare, _Allocator>, _Allocator,
__gnu_debug::_Safe_node_sequence>,
public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>
{ {
typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base; typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
multiset, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
#if __cplusplus >= 201103L
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
#endif
public: public:
// types: // types:
typedef _Key key_type; typedef _Key key_type;
...@@ -78,32 +79,17 @@ namespace __debug ...@@ -78,32 +79,17 @@ namespace __debug
// 23.3.3.1 construct/copy/destroy: // 23.3.3.1 construct/copy/destroy:
#if __cplusplus < 201103L
multiset() : _Base() { } multiset() : _Base() { }
explicit multiset(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
multiset(const multiset& __x) multiset(const multiset& __x)
: _Base(__x) { } : _Base(__x) { }
multiset(const _Base& __x) ~multiset() { }
: _Base(__x) { } #else
multiset() = default;
#if __cplusplus >= 201103L multiset(const multiset&) = default;
multiset(multiset&& __x) multiset(multiset&&) = default;
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _Base(std::move(__x))
{ this->_M_swap(__x); }
multiset(initializer_list<value_type> __l, multiset(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(), const _Compare& __comp = _Compare(),
...@@ -118,7 +104,8 @@ namespace __debug ...@@ -118,7 +104,8 @@ namespace __debug
: _Base(__m, __a) { } : _Base(__m, __a) { }
multiset(multiset&& __m, const allocator_type& __a) multiset(multiset&& __m, const allocator_type& __a)
: _Base(std::move(__m._M_base()), __a) { } : _Safe(std::move(__m._M_safe()), __a),
_Base(std::move(__m._M_base()), __a) { }
multiset(initializer_list<value_type> __l, const allocator_type& __a) multiset(initializer_list<value_type> __l, const allocator_type& __a)
: _Base(__l, __a) : _Base(__l, __a)
...@@ -129,36 +116,41 @@ namespace __debug ...@@ -129,36 +116,41 @@ namespace __debug
const allocator_type& __a) const allocator_type& __a)
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)), __last)),
__gnu_debug::__base(__last), __a) __gnu_debug::__base(__last), __a) { }
{ }
~multiset() = default;
#endif #endif
~multiset() _GLIBCXX_NOEXCEPT { } explicit multiset(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
multiset(const _Base& __x)
: _Base(__x) { }
#if __cplusplus < 201103L
multiset& multiset&
operator=(const multiset& __x) operator=(const multiset& __x)
{ {
this->_M_safe() = __x;
_M_base() = __x; _M_base() = __x;
this->_M_invalidate_all();
return *this; return *this;
} }
#else
multiset&
operator=(const multiset&) = default;
#if __cplusplus >= 201103L
multiset& multiset&
operator=(multiset&& __x) operator=(multiset&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
multiset& multiset&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
...@@ -233,7 +225,8 @@ namespace __debug ...@@ -233,7 +225,8 @@ namespace __debug
iterator iterator
emplace(_Args&&... __args) emplace(_Args&&... __args)
{ {
return iterator(_Base::emplace(std::forward<_Args>(__args)...), this); return iterator(_Base::emplace(std::forward<_Args>(__args)...),
this);
} }
template<typename... _Args> template<typename... _Args>
...@@ -364,15 +357,11 @@ namespace __debug ...@@ -364,15 +357,11 @@ namespace __debug
void void
swap(multiset& __x) swap(multiset& __x)
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif #endif
{ {
#if __cplusplus >= 201103L _Safe::_M_swap(__x);
if (!_Alloc_traits::_S_propagate_on_swap())
__glibcxx_check_equal_allocs(__x);
#endif
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
} }
void void
...@@ -444,14 +433,6 @@ namespace __debug ...@@ -444,14 +433,6 @@ namespace __debug
const _Base& const _Base&
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
private:
void
_M_invalidate_all()
{
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
this->_M_invalidate_if(_Not_equal(_Base::end()));
}
}; };
template<typename _Key, typename _Compare, typename _Allocator> template<typename _Key, typename _Compare, typename _Allocator>
......
...@@ -104,7 +104,8 @@ namespace __gnu_debug ...@@ -104,7 +104,8 @@ namespace __gnu_debug
~_Safe_iterator_base() { this->_M_detach(); } ~_Safe_iterator_base() { this->_M_detach(); }
/** For use in _Safe_iterator. */ /** For use in _Safe_iterator. */
__gnu_cxx::__mutex& _M_get_mutex() throw (); __gnu_cxx::__mutex&
_M_get_mutex() throw ();
public: public:
/** Attaches this iterator to the given sequence, detaching it /** Attaches this iterator to the given sequence, detaching it
...@@ -112,30 +113,37 @@ namespace __gnu_debug ...@@ -112,30 +113,37 @@ namespace __gnu_debug
* new sequence is the NULL pointer, the iterator is left * new sequence is the NULL pointer, the iterator is left
* unattached. * unattached.
*/ */
void _M_attach(_Safe_sequence_base* __seq, bool __constant); void
_M_attach(_Safe_sequence_base* __seq, bool __constant);
/** Likewise, but not thread-safe. */ /** Likewise, but not thread-safe. */
void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw (); void
_M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
/** Detach the iterator for whatever sequence it is attached to, /** Detach the iterator for whatever sequence it is attached to,
* if any. * if any.
*/ */
void _M_detach(); void
_M_detach();
/** Likewise, but not thread-safe. */ /** Likewise, but not thread-safe. */
void _M_detach_single() throw (); void
_M_detach_single() throw ();
/** Determines if we are attached to the given sequence. */ /** Determines if we are attached to the given sequence. */
bool _M_attached_to(const _Safe_sequence_base* __seq) const bool
_M_attached_to(const _Safe_sequence_base* __seq) const
{ return _M_sequence == __seq; } { return _M_sequence == __seq; }
/** Is this iterator singular? */ /** Is this iterator singular? */
_GLIBCXX_PURE bool _M_singular() const throw (); _GLIBCXX_PURE bool
_M_singular() const throw ();
/** Can we compare this iterator to the given iterator @p __x? /** Can we compare this iterator to the given iterator @p __x?
Returns true if both iterators are nonsingular and reference Returns true if both iterators are nonsingular and reference
the same sequence. */ the same sequence. */
_GLIBCXX_PURE bool _M_can_compare(const _Safe_iterator_base& __x) const throw (); _GLIBCXX_PURE bool
_M_can_compare(const _Safe_iterator_base& __x) const throw ();
/** Invalidate the iterator, making it singular. */ /** Invalidate the iterator, making it singular. */
void void
...@@ -188,17 +196,13 @@ namespace __gnu_debug ...@@ -188,17 +196,13 @@ namespace __gnu_debug
protected: protected:
// Initialize with a version number of 1 and no iterators // Initialize with a version number of 1 and no iterators
_Safe_sequence_base() _Safe_sequence_base() _GLIBCXX_NOEXCEPT
: _M_iterators(0), _M_const_iterators(0), _M_version(1) : _M_iterators(0), _M_const_iterators(0), _M_version(1)
{ } { }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
_Safe_sequence_base(const _Safe_sequence_base&) noexcept _Safe_sequence_base(const _Safe_sequence_base&) noexcept
: _Safe_sequence_base() { } : _Safe_sequence_base() { }
_Safe_sequence_base(_Safe_sequence_base&& __x) noexcept
: _Safe_sequence_base()
{ _M_swap(__x); }
#endif #endif
/** Notify all iterators that reference this sequence that the /** Notify all iterators that reference this sequence that the
...@@ -231,10 +235,11 @@ namespace __gnu_debug ...@@ -231,10 +235,11 @@ namespace __gnu_debug
* one container now reference the other container. * one container now reference the other container.
*/ */
void void
_M_swap(_Safe_sequence_base& __x); _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT;
/** For use in _Safe_sequence. */ /** For use in _Safe_sequence. */
__gnu_cxx::__mutex& _M_get_mutex() throw (); __gnu_cxx::__mutex&
_M_get_mutex() throw ();
public: public:
/** Invalidates all iterators. */ /** Invalidates all iterators. */
......
// Safe container implementation -*- C++ -*-
// Copyright (C) 2014 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.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file debug/safe_container.h
* This file is a GNU debug extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_DEBUG_SAFE_CONTAINER_H
#define _GLIBCXX_DEBUG_SAFE_CONTAINER_H 1
#include <ext/alloc_traits.h>
namespace __gnu_debug
{
/// Safe class dealing with some allocator dependent operations.
template<typename _SafeContainer,
typename _Alloc,
template<typename> class _SafeBase,
bool _IsCxx11AllocatorAware = true>
class _Safe_container
: public _SafeBase<_SafeContainer>
{
typedef _SafeBase<_SafeContainer> _Base;
_SafeContainer&
_M_cont() _GLIBCXX_NOEXCEPT
{ return *static_cast<_SafeContainer*>(this); }
protected:
_Safe_container&
_M_safe() _GLIBCXX_NOEXCEPT
{ return *this; }
#if __cplusplus >= 201103L
_Safe_container() = default;
_Safe_container(const _Safe_container&) = default;
_Safe_container(_Safe_container&& __x) noexcept
: _Safe_container()
{ _Base::_M_swap(__x); }
_Safe_container(_Safe_container&& __x,
const _Alloc& __a)
: _Safe_container()
{
if (__x._M_cont().get_allocator() == __a)
_Base::_M_swap(__x);
else
__x._M_invalidate_all();
}
#endif
public:
// Copy assignment invalidate all iterators.
_Safe_container&
operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT
{
this->_M_invalidate_all();
return *this;
}
#if __cplusplus >= 201103L
_Safe_container&
operator=(_Safe_container&& __x) noexcept
{
__glibcxx_check_self_move_assign(__x);
if (_IsCxx11AllocatorAware)
{
typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| _M_cont().get_allocator() == __x._M_cont().get_allocator();
if (__xfer_memory)
_Base::_M_swap(__x);
else
this->_M_invalidate_all();
}
else
_Base::_M_swap(__x);
__x._M_invalidate_all();
return *this;
}
void
_M_swap(_Safe_container& __x) noexcept
{
if (_IsCxx11AllocatorAware)
{
typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits;
if (!_Alloc_traits::_S_propagate_on_swap())
__glibcxx_check_equal_allocs(this->_M_cont()._M_base(),
__x._M_cont()._M_base());
}
_Base::_M_swap(__x);
}
#endif
};
} // namespace __gnu_debug
#endif
...@@ -127,6 +127,25 @@ namespace __gnu_debug ...@@ -127,6 +127,25 @@ namespace __gnu_debug
void void
_M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred); _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred);
}; };
/// Like _Safe_sequence but with a special _M_invalidate_all implementation
/// not invalidating past-the-end iterators. Used by node based sequence.
template<typename _Sequence>
class _Safe_node_sequence
: public _Safe_sequence<_Sequence>
{
protected:
void
_M_invalidate_all()
{
typedef typename _Sequence::const_iterator _Const_iterator;
typedef typename _Const_iterator::iterator_type _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
const _Sequence& __seq = *static_cast<_Sequence*>(this);
this->_M_invalidate_if(_Not_equal(__seq._M_base().end()));
}
};
} // namespace __gnu_debug } // namespace __gnu_debug
#include <debug/safe_sequence.tcc> #include <debug/safe_sequence.tcc>
......
...@@ -80,7 +80,7 @@ namespace __gnu_debug ...@@ -80,7 +80,7 @@ namespace __gnu_debug
~_Safe_local_iterator_base() { this->_M_detach(); } ~_Safe_local_iterator_base() { this->_M_detach(); }
_Safe_unordered_container_base* _Safe_unordered_container_base*
_M_get_container() const _GLIBCXX_NOEXCEPT; _M_get_container() const noexcept;
public: public:
/** Attaches this iterator to the given container, detaching it /** Attaches this iterator to the given container, detaching it
...@@ -132,15 +132,16 @@ namespace __gnu_debug ...@@ -132,15 +132,16 @@ namespace __gnu_debug
protected: protected:
// Initialize with a version number of 1 and no iterators // Initialize with a version number of 1 and no iterators
_Safe_unordered_container_base() _Safe_unordered_container_base() noexcept
: _M_local_iterators(nullptr), _M_const_local_iterators(nullptr) : _M_local_iterators(nullptr), _M_const_local_iterators(nullptr)
{ } { }
// Initialize with a version number of 1 and no iterators // Copy constructor does not copy iterators.
_Safe_unordered_container_base(const _Safe_unordered_container_base&) _Safe_unordered_container_base(const _Safe_unordered_container_base&)
noexcept noexcept
: _Safe_unordered_container_base() { } : _Safe_unordered_container_base() { }
// When moved unordered containers iterators are swapped.
_Safe_unordered_container_base(_Safe_unordered_container_base&& __x) _Safe_unordered_container_base(_Safe_unordered_container_base&& __x)
noexcept noexcept
: _Safe_unordered_container_base() : _Safe_unordered_container_base()
...@@ -148,7 +149,7 @@ namespace __gnu_debug ...@@ -148,7 +149,7 @@ namespace __gnu_debug
/** Notify all iterators that reference this container that the /** Notify all iterators that reference this container that the
container is being destroyed. */ container is being destroyed. */
~_Safe_unordered_container_base() ~_Safe_unordered_container_base() noexcept
{ this->_M_detach_all(); } { this->_M_detach_all(); }
/** Detach all iterators, leaving them singular. */ /** Detach all iterators, leaving them singular. */
...@@ -161,7 +162,7 @@ namespace __gnu_debug ...@@ -161,7 +162,7 @@ namespace __gnu_debug
* one container now reference the other container. * one container now reference the other container.
*/ */
void void
_M_swap(_Safe_unordered_container_base& __x); _M_swap(_Safe_unordered_container_base& __x) noexcept;
public: public:
/** Attach an iterator to this container. */ /** Attach an iterator to this container. */
......
...@@ -57,7 +57,31 @@ namespace __gnu_debug ...@@ -57,7 +57,31 @@ namespace __gnu_debug
template<typename _Container> template<typename _Container>
class _Safe_unordered_container : public _Safe_unordered_container_base class _Safe_unordered_container : public _Safe_unordered_container_base
{ {
public: private:
_Container&
_M_cont() noexcept
{ return *static_cast<_Container*>(this); }
protected:
void
_M_invalidate_locals()
{
auto __local_end = _M_cont()._M_base().end(0);
this->_M_invalidate_local_if(
[__local_end](__decltype(_M_cont()._M_base().cend(0)) __it)
{ return __it != __local_end; });
}
void
_M_invalidate_all()
{
auto __end = _M_cont()._M_base().end();
this->_M_invalidate_if(
[__end](__decltype(_M_cont()._M_base().cend()) __it)
{ return __it != __end; });
_M_invalidate_locals();
}
/** Invalidates all iterators @c x that reference this container, /** Invalidates all iterators @c x that reference this container,
are not singular, and for which @c __pred(x) returns @c are not singular, and for which @c __pred(x) returns @c
true. @c __pred will be invoked with the normal iterators nested true. @c __pred will be invoked with the normal iterators nested
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_SET_H 1 #define _GLIBCXX_DEBUG_SET_H 1
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <utility> #include <utility>
...@@ -41,18 +42,19 @@ namespace __debug ...@@ -41,18 +42,19 @@ namespace __debug
template<typename _Key, typename _Compare = std::less<_Key>, template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> > typename _Allocator = std::allocator<_Key> >
class set class set
: public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> > set<_Key, _Compare, _Allocator>, _Allocator,
__gnu_debug::_Safe_node_sequence>,
public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>
{ {
typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base; typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
set, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
#if __cplusplus >= 201103L
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
#endif
public: public:
// types: // types:
typedef _Key key_type; typedef _Key key_type;
...@@ -77,32 +79,17 @@ namespace __debug ...@@ -77,32 +79,17 @@ namespace __debug
// 23.3.3.1 construct/copy/destroy: // 23.3.3.1 construct/copy/destroy:
#if __cplusplus < 201103L
set() : _Base() { } set() : _Base() { }
explicit set(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
set(const set& __x) set(const set& __x)
: _Base(__x) { } : _Base(__x) { }
set(const _Base& __x) ~set() { }
: _Base(__x) { } #else
set() = default;
#if __cplusplus >= 201103L set(const set&) = default;
set(set&& __x) set(set&&) = default;
noexcept(is_nothrow_copy_constructible<_Compare>::value)
: _Base(std::move(__x))
{ this->_M_swap(__x); }
set(initializer_list<value_type> __l, set(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(), const _Compare& __comp = _Compare(),
...@@ -117,47 +104,52 @@ namespace __debug ...@@ -117,47 +104,52 @@ namespace __debug
: _Base(__x, __a) { } : _Base(__x, __a) { }
set(set&& __x, const allocator_type& __a) set(set&& __x, const allocator_type& __a)
: _Base(std::move(__x._M_base()), __a) { } : _Safe(std::move(__x._M_safe()), __a),
_Base(std::move(__x._M_base()), __a) { }
set(initializer_list<value_type> __l, const allocator_type& __a) set(initializer_list<value_type> __l, const allocator_type& __a)
: _Base(__l, __a) : _Base(__l, __a) { }
{ }
template<typename _InputIterator> template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last, set(_InputIterator __first, _InputIterator __last,
const allocator_type& __a) const allocator_type& __a)
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)), __last)),
__gnu_debug::__base(__last), __a) __gnu_debug::__base(__last), __a) { }
{ }
~set() = default;
#endif #endif
~set() _GLIBCXX_NOEXCEPT { } explicit set(const _Compare& __comp,
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
__gnu_debug::__base(__last),
__comp, __a) { }
set(const _Base& __x)
: _Base(__x) { }
#if __cplusplus < 201103L
set& set&
operator=(const set& __x) operator=(const set& __x)
{ {
this->_M_safe() = __x;
_M_base() = __x; _M_base() = __x;
this->_M_invalidate_all();
return *this; return *this;
} }
#else
set&
operator=(const set&) = default;
#if __cplusplus >= 201103L
set& set&
operator=(set&& __x) operator=(set&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
set& set&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
...@@ -372,15 +364,11 @@ namespace __debug ...@@ -372,15 +364,11 @@ namespace __debug
void void
swap(set& __x) swap(set& __x)
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif #endif
{ {
#if __cplusplus >= 201103L _Safe::_M_swap(__x);
if (!_Alloc_traits::_S_propagate_on_swap())
__glibcxx_check_equal_allocs(__x);
#endif
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
} }
void void
...@@ -452,14 +440,6 @@ namespace __debug ...@@ -452,14 +440,6 @@ namespace __debug
const _Base& const _Base&
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
private:
void
_M_invalidate_all()
{
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
this->_M_invalidate_if(_Not_equal(_M_base().end()));
}
}; };
template<typename _Key, typename _Compare, typename _Allocator> template<typename _Key, typename _Compare, typename _Allocator>
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <string> #include <string>
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
namespace __gnu_debug namespace __gnu_debug
...@@ -39,12 +40,14 @@ namespace __gnu_debug ...@@ -39,12 +40,14 @@ namespace __gnu_debug
template<typename _CharT, typename _Traits = std::char_traits<_CharT>, template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
typename _Allocator = std::allocator<_CharT> > typename _Allocator = std::allocator<_CharT> >
class basic_string class basic_string
: public std::basic_string<_CharT, _Traits, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits, basic_string<_CharT, _Traits, _Allocator>,
_Allocator> > _Allocator, _Safe_sequence, false>,
public std::basic_string<_CharT, _Traits, _Allocator>
{ {
typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<basic_string> _Safe_base; typedef __gnu_debug::_Safe_container<
basic_string, _Allocator, _Safe_sequence, false> _Safe;
public: public:
// types: // types:
...@@ -58,10 +61,10 @@ namespace __gnu_debug ...@@ -58,10 +61,10 @@ namespace __gnu_debug
typedef typename _Base::pointer pointer; typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer; typedef typename _Base::const_pointer const_pointer;
typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string> typedef __gnu_debug::_Safe_iterator<
iterator; typename _Base::iterator, basic_string> iterator;
typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, typedef __gnu_debug::_Safe_iterator<
basic_string> const_iterator; typename _Base::const_iterator, basic_string> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
...@@ -71,30 +74,39 @@ namespace __gnu_debug ...@@ -71,30 +74,39 @@ namespace __gnu_debug
// 21.3.1 construct/copy/destroy: // 21.3.1 construct/copy/destroy:
explicit basic_string(const _Allocator& __a = _Allocator()) explicit basic_string(const _Allocator& __a = _Allocator())
// _GLIBCXX_NOEXCEPT // _GLIBCXX_NOEXCEPT
: _Base(__a) : _Base(__a) { }
{ }
// Provides conversion from a release-mode string to a debug-mode string
basic_string(const _Base& __base) : _Base(__base) { }
// _GLIBCXX_RESOLVE_LIB_DEFECTS #if __cplusplus < 201103L
// 42. string ctors specify wrong default allocator
basic_string(const basic_string& __str) basic_string(const basic_string& __str)
: _Base(__str, 0, _Base::npos, __str.get_allocator()) : _Base(__str) { }
~basic_string() { }
#else
basic_string(const basic_string&) = default;
basic_string(basic_string&&) = default;
basic_string(std::initializer_list<_CharT> __l,
const _Allocator& __a = _Allocator())
: _Base(__l, __a)
{ } { }
~basic_string() = default;
#endif // C++11
// Provides conversion from a normal-mode string to a debug-mode string
basic_string(const _Base& __base)
: _Base(__base) { }
// _GLIBCXX_RESOLVE_LIB_DEFECTS // _GLIBCXX_RESOLVE_LIB_DEFECTS
// 42. string ctors specify wrong default allocator // 42. string ctors specify wrong default allocator
basic_string(const basic_string& __str, size_type __pos, basic_string(const basic_string& __str, size_type __pos,
size_type __n = _Base::npos, size_type __n = _Base::npos,
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__str, __pos, __n, __a) : _Base(__str, __pos, __n, __a) { }
{ }
basic_string(const _CharT* __s, size_type __n, basic_string(const _CharT* __s, size_type __n,
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__check_string(__s, __n), __n, __a) : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) { }
{ }
basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__check_string(__s), __a) : _Base(__gnu_debug::__check_string(__s), __a)
...@@ -102,43 +114,36 @@ namespace __gnu_debug ...@@ -102,43 +114,36 @@ namespace __gnu_debug
basic_string(size_type __n, _CharT __c, basic_string(size_type __n, _CharT __c,
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__n, __c, __a) : _Base(__n, __c, __a) { }
{ }
template<typename _InputIterator> template<typename _InputIterator>
basic_string(_InputIterator __begin, _InputIterator __end, basic_string(_InputIterator __begin, _InputIterator __end,
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin, : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin,
__end)), __end)),
__gnu_debug::__base(__end), __a) __gnu_debug::__base(__end), __a) { }
{ }
#if __cplusplus >= 201103L
basic_string(basic_string&& __str) // noexcept
: _Base(std::move(__str))
{ }
basic_string(std::initializer_list<_CharT> __l,
const _Allocator& __a = _Allocator())
: _Base(__l, __a)
{ }
#endif // C++11
~basic_string() _GLIBCXX_NOEXCEPT { }
#if __cplusplus < 201103L
basic_string& basic_string&
operator=(const basic_string& __str) operator=(const basic_string& __str)
{ {
*static_cast<_Base*>(this) = __str; this->_M_safe() = __str;
this->_M_invalidate_all(); _M_base() = __str;
return *this; return *this;
} }
#else
basic_string&
operator=(const basic_string&) = default;
basic_string&
operator=(basic_string&&) = default;
#endif
basic_string& basic_string&
operator=(const _CharT* __s) operator=(const _CharT* __s)
{ {
__glibcxx_check_string(__s); __glibcxx_check_string(__s);
*static_cast<_Base*>(this) = __s; _M_base() = __s;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
...@@ -146,25 +151,16 @@ namespace __gnu_debug ...@@ -146,25 +151,16 @@ namespace __gnu_debug
basic_string& basic_string&
operator=(_CharT __c) operator=(_CharT __c)
{ {
*static_cast<_Base*>(this) = __c; _M_base() = __c;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
basic_string& basic_string&
operator=(basic_string&& __str)
{
__glibcxx_check_self_move_assign(__str);
*static_cast<_Base*>(this) = std::move(__str);
this->_M_invalidate_all();
return *this;
}
basic_string&
operator=(std::initializer_list<_CharT> __l) operator=(std::initializer_list<_CharT> __l)
{ {
*static_cast<_Base*>(this) = __l; _M_base() = __l;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
...@@ -704,12 +700,10 @@ namespace __gnu_debug ...@@ -704,12 +700,10 @@ namespace __gnu_debug
} }
void void
swap(basic_string<_CharT,_Traits,_Allocator>& __x) swap(basic_string& __x)
{ {
_Safe::_M_swap(__x);
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x);
this->_M_invalidate_all();
__x._M_invalidate_all();
} }
// 21.3.6 string operations: // 21.3.6 string operations:
...@@ -922,7 +916,7 @@ namespace __gnu_debug ...@@ -922,7 +916,7 @@ namespace __gnu_debug
const _Base& const _Base&
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
using _Safe_base::_M_invalidate_all; using _Safe::_M_invalidate_all;
}; };
template<typename _CharT, typename _Traits, typename _Allocator> template<typename _CharT, typename _Traits, typename _Allocator>
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
# include <unordered_map> # include <unordered_map>
#include <debug/safe_unordered_container.h> #include <debug/safe_unordered_container.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h> #include <debug/safe_local_iterator.h>
...@@ -48,21 +49,21 @@ namespace __debug ...@@ -48,21 +49,21 @@ namespace __debug
typename _Pred = std::equal_to<_Key>, typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_map class unordered_map
: public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp, unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
_Hash, _Pred, _Alloc> > __gnu_debug::_Safe_unordered_container>,
public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
{ {
typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, typedef _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash,
_Pred, _Alloc> _Base; _Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_unordered_container<unordered_map> _Safe_base; typedef __gnu_debug::_Safe_container<unordered_map,
_Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_local_iterator _Base_const_local_iterator; typedef typename _Base::const_local_iterator
_Base_const_local_iterator;
typedef typename _Base::local_iterator _Base_local_iterator; typedef typename _Base::local_iterator _Base_local_iterator;
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
public: public:
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher; typedef typename _Base::hasher hasher;
...@@ -72,14 +73,14 @@ namespace __debug ...@@ -72,14 +73,14 @@ namespace __debug
typedef typename _Base::key_type key_type; typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type; typedef typename _Base::value_type value_type;
typedef __gnu_debug::_Safe_iterator<_Base_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_map> iterator; _Base_iterator, unordered_map> iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_map> const_iterator; _Base_const_iterator, unordered_map> const_iterator;
typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator, typedef __gnu_debug::_Safe_local_iterator<
unordered_map> local_iterator; _Base_local_iterator, unordered_map> local_iterator;
typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator, typedef __gnu_debug::_Safe_local_iterator<
unordered_map> const_local_iterator; _Base_const_local_iterator, unordered_map> const_local_iterator;
explicit explicit
unordered_map(size_type __n = 10, unordered_map(size_type __n = 10,
...@@ -108,18 +109,16 @@ namespace __debug ...@@ -108,18 +109,16 @@ namespace __debug
explicit explicit
unordered_map(const allocator_type& __a) unordered_map(const allocator_type& __a)
: _Base(__a) : _Base(__a) { }
{ }
unordered_map(const unordered_map& __umap, unordered_map(const unordered_map& __umap,
const allocator_type& __a) const allocator_type& __a)
: _Base(__umap._M_base(), __a) : _Base(__umap, __a) { }
{ }
unordered_map(unordered_map&& __umap, unordered_map(unordered_map&& __umap,
const allocator_type& __a) const allocator_type& __a)
: _Base(std::move(__umap._M_base()), __a) : _Safe(std::move(__umap._M_safe()), __a),
{ } _Base(std::move(__umap._M_base()), __a) { }
unordered_map(initializer_list<value_type> __l, unordered_map(initializer_list<value_type> __l,
size_type __n = 0, size_type __n = 0,
...@@ -128,31 +127,13 @@ namespace __debug ...@@ -128,31 +127,13 @@ namespace __debug
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { } : _Base(__l, __n, __hf, __eql, __a) { }
~unordered_map() noexcept { } ~unordered_map() = default;
unordered_map& unordered_map&
operator=(const unordered_map& __x) operator=(const unordered_map&) = default;
{
_M_base() = __x._M_base();
this->_M_invalidate_all();
return *this;
}
unordered_map& unordered_map&
operator=(unordered_map&& __x) operator=(unordered_map&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
unordered_map& unordered_map&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
...@@ -164,12 +145,10 @@ namespace __debug ...@@ -164,12 +145,10 @@ namespace __debug
void void
swap(unordered_map& __x) swap(unordered_map& __x)
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
{ {
if (!_Alloc_traits::_S_propagate_on_swap()) _Safe::_M_swap(__x);
__glibcxx_check_equal_allocs(__x);
_Base::swap(__x); _Base::swap(__x);
_Safe_base::_M_swap(__x);
} }
void void
...@@ -449,28 +428,10 @@ namespace __debug ...@@ -449,28 +428,10 @@ namespace __debug
private: private:
void void
_M_invalidate_locals()
{
_Base_local_iterator __local_end = _Base::end(0);
this->_M_invalidate_local_if(
[__local_end](_Base_const_local_iterator __it)
{ return __it != __local_end; });
}
void
_M_invalidate_all()
{
_Base_iterator __end = _Base::end();
this->_M_invalidate_if([__end](_Base_const_iterator __it)
{ return __it != __end; });
_M_invalidate_locals();
}
void
_M_check_rehashed(size_type __prev_count) _M_check_rehashed(size_type __prev_count)
{ {
if (__prev_count != this->bucket_count()) if (__prev_count != this->bucket_count())
_M_invalidate_locals(); this->_M_invalidate_locals();
} }
}; };
...@@ -502,23 +463,20 @@ namespace __debug ...@@ -502,23 +463,20 @@ namespace __debug
typename _Pred = std::equal_to<_Key>, typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_multimap class unordered_multimap
: public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, : public __gnu_debug::_Safe_container<
_Pred, _Alloc>, unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key, __gnu_debug::_Safe_unordered_container>,
_Tp, _Hash, _Pred, _Alloc> > public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
{ {
typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
_Pred, _Alloc> _Base; _Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_unordered_container<unordered_multimap> typedef __gnu_debug::_Safe_container<unordered_multimap,
_Safe_base; _Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_local_iterator _Base_const_local_iterator; typedef typename _Base::const_local_iterator _Base_const_local_iterator;
typedef typename _Base::local_iterator _Base_local_iterator; typedef typename _Base::local_iterator _Base_local_iterator;
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
public: public:
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher; typedef typename _Base::hasher hasher;
...@@ -528,10 +486,10 @@ namespace __debug ...@@ -528,10 +486,10 @@ namespace __debug
typedef typename _Base::key_type key_type; typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type; typedef typename _Base::value_type value_type;
typedef __gnu_debug::_Safe_iterator<_Base_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_multimap> iterator; _Base_iterator, unordered_multimap> iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_multimap> const_iterator; _Base_const_iterator, unordered_multimap> const_iterator;
typedef __gnu_debug::_Safe_local_iterator< typedef __gnu_debug::_Safe_local_iterator<
_Base_local_iterator, unordered_multimap> local_iterator; _Base_local_iterator, unordered_multimap> local_iterator;
typedef __gnu_debug::_Safe_local_iterator< typedef __gnu_debug::_Safe_local_iterator<
...@@ -564,18 +522,16 @@ namespace __debug ...@@ -564,18 +522,16 @@ namespace __debug
explicit explicit
unordered_multimap(const allocator_type& __a) unordered_multimap(const allocator_type& __a)
: _Base(__a) : _Base(__a) { }
{ }
unordered_multimap(const unordered_multimap& __umap, unordered_multimap(const unordered_multimap& __umap,
const allocator_type& __a) const allocator_type& __a)
: _Base(__umap._M_base(), __a) : _Base(__umap, __a) { }
{ }
unordered_multimap(unordered_multimap&& __umap, unordered_multimap(unordered_multimap&& __umap,
const allocator_type& __a) const allocator_type& __a)
: _Base(std::move(__umap._M_base()), __a) : _Safe(std::move(__umap._M_safe()), __a),
{ } _Base(std::move(__umap._M_base()), __a) { }
unordered_multimap(initializer_list<value_type> __l, unordered_multimap(initializer_list<value_type> __l,
size_type __n = 0, size_type __n = 0,
...@@ -584,48 +540,28 @@ namespace __debug ...@@ -584,48 +540,28 @@ namespace __debug
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { } : _Base(__l, __n, __hf, __eql, __a) { }
~unordered_multimap() noexcept { } ~unordered_multimap() = default;
unordered_multimap& unordered_multimap&
operator=(const unordered_multimap& __x) operator=(const unordered_multimap&) = default;
{
_M_base() = __x._M_base();
this->_M_invalidate_all();
return *this;
}
unordered_multimap& unordered_multimap&
operator=(unordered_multimap&& __x) operator=(unordered_multimap&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
unordered_multimap& unordered_multimap&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
_M_base() = __l; this->_M_base() = __l;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
void void
swap(unordered_multimap& __x) swap(unordered_multimap& __x)
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
{ {
if (!_Alloc_traits::_S_propagate_on_swap()) _Safe::_M_swap(__x);
__glibcxx_check_equal_allocs(__x);
_Base::swap(__x); _Base::swap(__x);
_Safe_base::_M_swap(__x);
} }
void void
...@@ -901,28 +837,10 @@ namespace __debug ...@@ -901,28 +837,10 @@ namespace __debug
private: private:
void void
_M_invalidate_locals()
{
_Base_local_iterator __local_end = _Base::end(0);
this->_M_invalidate_local_if(
[__local_end](_Base_const_local_iterator __it)
{ return __it != __local_end; });
}
void
_M_invalidate_all()
{
_Base_iterator __end = _Base::end();
this->_M_invalidate_if([__end](_Base_const_iterator __it)
{ return __it != __end; });
_M_invalidate_locals();
}
void
_M_check_rehashed(size_type __prev_count) _M_check_rehashed(size_type __prev_count)
{ {
if (__prev_count != this->bucket_count()) if (__prev_count != this->bucket_count())
_M_invalidate_locals(); this->_M_invalidate_locals();
} }
}; };
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
# include <unordered_set> # include <unordered_set>
#include <debug/safe_unordered_container.h> #include <debug/safe_unordered_container.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h> #include <debug/safe_local_iterator.h>
...@@ -48,20 +49,21 @@ namespace __debug ...@@ -48,20 +49,21 @@ namespace __debug
typename _Pred = std::equal_to<_Value>, typename _Pred = std::equal_to<_Value>,
typename _Alloc = std::allocator<_Value> > typename _Alloc = std::allocator<_Value> >
class unordered_set class unordered_set
: public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash, unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
_Pred, _Alloc> > __gnu_debug::_Safe_unordered_container>,
public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
{ {
typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash, typedef _GLIBCXX_STD_C::unordered_set<
_Pred, _Alloc> _Base; _Value, _Hash, _Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base; typedef __gnu_debug::_Safe_container<
unordered_set, _Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_local_iterator _Base_const_local_iterator; typedef typename _Base::const_local_iterator _Base_const_local_iterator;
typedef typename _Base::local_iterator _Base_local_iterator; typedef typename _Base::local_iterator _Base_local_iterator;
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
public: public:
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher; typedef typename _Base::hasher hasher;
...@@ -71,14 +73,14 @@ namespace __debug ...@@ -71,14 +73,14 @@ namespace __debug
typedef typename _Base::key_type key_type; typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type; typedef typename _Base::value_type value_type;
typedef __gnu_debug::_Safe_iterator<_Base_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_set> iterator; _Base_iterator, unordered_set> iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_set> const_iterator; _Base_const_iterator, unordered_set> const_iterator;
typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator, typedef __gnu_debug::_Safe_local_iterator<
unordered_set> local_iterator; _Base_local_iterator, unordered_set> local_iterator;
typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator, typedef __gnu_debug::_Safe_local_iterator<
unordered_set> const_local_iterator; _Base_const_local_iterator, unordered_set> const_local_iterator;
explicit explicit
unordered_set(size_type __n = 10, unordered_set(size_type __n = 10,
...@@ -107,18 +109,16 @@ namespace __debug ...@@ -107,18 +109,16 @@ namespace __debug
explicit explicit
unordered_set(const allocator_type& __a) unordered_set(const allocator_type& __a)
: _Base(__a) : _Base(__a) { }
{ }
unordered_set(const unordered_set& __uset, unordered_set(const unordered_set& __uset,
const allocator_type& __a) const allocator_type& __a)
: _Base(__uset._M_base(), __a) : _Base(__uset, __a) { }
{ }
unordered_set(unordered_set&& __uset, unordered_set(unordered_set&& __uset,
const allocator_type& __a) const allocator_type& __a)
: _Base(std::move(__uset._M_base()), __a) : _Safe(std::move(__uset._M_safe()), __a),
{ } _Base(std::move(__uset._M_base()), __a) { }
unordered_set(initializer_list<value_type> __l, unordered_set(initializer_list<value_type> __l,
size_type __n = 0, size_type __n = 0,
...@@ -127,31 +127,13 @@ namespace __debug ...@@ -127,31 +127,13 @@ namespace __debug
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { } : _Base(__l, __n, __hf, __eql, __a) { }
~unordered_set() noexcept { } ~unordered_set() = default;
unordered_set& unordered_set&
operator=(const unordered_set& __x) operator=(const unordered_set&) = default;
{
_M_base() = __x._M_base();
this->_M_invalidate_all();
return *this;
}
unordered_set& unordered_set&
operator=(unordered_set&& __x) operator=(unordered_set&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
unordered_set& unordered_set&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
...@@ -163,12 +145,10 @@ namespace __debug ...@@ -163,12 +145,10 @@ namespace __debug
void void
swap(unordered_set& __x) swap(unordered_set& __x)
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
{ {
if (!_Alloc_traits::_S_propagate_on_swap()) _Safe::_M_swap(__x);
__glibcxx_check_equal_allocs(__x);
_Base::swap(__x); _Base::swap(__x);
_Safe_base::_M_swap(__x);
} }
void void
...@@ -290,8 +270,8 @@ namespace __debug ...@@ -290,8 +270,8 @@ namespace __debug
insert(const value_type& __obj) insert(const value_type& __obj)
{ {
size_type __bucket_count = this->bucket_count(); size_type __bucket_count = this->bucket_count();
typedef std::pair<_Base_iterator, bool> __pair_type; std::pair<_Base_iterator, bool> __res
__pair_type __res = _Base::insert(__obj); = _Base::insert(__obj);
_M_check_rehashed(__bucket_count); _M_check_rehashed(__bucket_count);
return std::make_pair(iterator(__res.first, this), __res.second); return std::make_pair(iterator(__res.first, this), __res.second);
} }
...@@ -310,8 +290,8 @@ namespace __debug ...@@ -310,8 +290,8 @@ namespace __debug
insert(value_type&& __obj) insert(value_type&& __obj)
{ {
size_type __bucket_count = this->bucket_count(); size_type __bucket_count = this->bucket_count();
typedef std::pair<typename _Base::iterator, bool> __pair_type; std::pair<_Base_iterator, bool> __res
__pair_type __res = _Base::insert(std::move(__obj)); = _Base::insert(std::move(__obj));
_M_check_rehashed(__bucket_count); _M_check_rehashed(__bucket_count);
return std::make_pair(iterator(__res.first, this), __res.second); return std::make_pair(iterator(__res.first, this), __res.second);
} }
...@@ -356,8 +336,8 @@ namespace __debug ...@@ -356,8 +336,8 @@ namespace __debug
std::pair<iterator, iterator> std::pair<iterator, iterator>
equal_range(const key_type& __key) equal_range(const key_type& __key)
{ {
typedef std::pair<_Base_iterator, _Base_iterator> __pair_type; std::pair<_Base_iterator, _Base_iterator> __res
__pair_type __res = _Base::equal_range(__key); = _Base::equal_range(__key);
return std::make_pair(iterator(__res.first, this), return std::make_pair(iterator(__res.first, this),
iterator(__res.second, this)); iterator(__res.second, this));
} }
...@@ -446,29 +426,10 @@ namespace __debug ...@@ -446,29 +426,10 @@ namespace __debug
private: private:
void void
_M_invalidate_locals()
{
_Base_local_iterator __local_end = _Base::end(0);
this->_M_invalidate_local_if(
[__local_end](_Base_const_local_iterator __it)
{ return __it != __local_end; });
}
void
_M_invalidate_all()
{
_Base_iterator __end = _Base::end();
this->_M_invalidate_if(
[__end](_Base_const_iterator __it)
{ return __it != __end; });
_M_invalidate_locals();
}
void
_M_check_rehashed(size_type __prev_count) _M_check_rehashed(size_type __prev_count)
{ {
if (__prev_count != this->bucket_count()) if (__prev_count != this->bucket_count())
_M_invalidate_locals(); this->_M_invalidate_locals();
} }
}; };
...@@ -497,22 +458,21 @@ namespace __debug ...@@ -497,22 +458,21 @@ namespace __debug
typename _Pred = std::equal_to<_Value>, typename _Pred = std::equal_to<_Value>,
typename _Alloc = std::allocator<_Value> > typename _Alloc = std::allocator<_Value> >
class unordered_multiset class unordered_multiset
: public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_unordered_container< unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _Alloc,
unordered_multiset<_Value, _Hash, _Pred, _Alloc> > __gnu_debug::_Safe_unordered_container>,
{ public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>
typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, {
_Pred, _Alloc> _Base; typedef _GLIBCXX_STD_C::unordered_multiset<
typedef __gnu_debug::_Safe_unordered_container<unordered_multiset> _Value, _Hash, _Pred, _Alloc> _Base;
_Safe_base; typedef __gnu_debug::_Safe_container<unordered_multiset,
_Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_local_iterator _Base_const_local_iterator; typedef typename _Base::const_local_iterator
_Base_const_local_iterator;
typedef typename _Base::local_iterator _Base_local_iterator; typedef typename _Base::local_iterator _Base_local_iterator;
typedef __gnu_cxx::__alloc_traits<typename
_Base::allocator_type> _Alloc_traits;
public: public:
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher; typedef typename _Base::hasher hasher;
...@@ -522,10 +482,10 @@ namespace __debug ...@@ -522,10 +482,10 @@ namespace __debug
typedef typename _Base::key_type key_type; typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type; typedef typename _Base::value_type value_type;
typedef __gnu_debug::_Safe_iterator<_Base_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_multiset> iterator; _Base_iterator, unordered_multiset> iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, typedef __gnu_debug::_Safe_iterator<
unordered_multiset> const_iterator; _Base_const_iterator, unordered_multiset> const_iterator;
typedef __gnu_debug::_Safe_local_iterator< typedef __gnu_debug::_Safe_local_iterator<
_Base_local_iterator, unordered_multiset> local_iterator; _Base_local_iterator, unordered_multiset> local_iterator;
typedef __gnu_debug::_Safe_local_iterator< typedef __gnu_debug::_Safe_local_iterator<
...@@ -558,18 +518,16 @@ namespace __debug ...@@ -558,18 +518,16 @@ namespace __debug
explicit explicit
unordered_multiset(const allocator_type& __a) unordered_multiset(const allocator_type& __a)
: _Base(__a) : _Base(__a) { }
{ }
unordered_multiset(const unordered_multiset& __uset, unordered_multiset(const unordered_multiset& __uset,
const allocator_type& __a) const allocator_type& __a)
: _Base(__uset._M_base(), __a) : _Base(__uset, __a) { }
{ }
unordered_multiset(unordered_multiset&& __uset, unordered_multiset(unordered_multiset&& __uset,
const allocator_type& __a) const allocator_type& __a)
: _Base(std::move(__uset._M_base()), __a) : _Safe(std::move(__uset._M_safe()), __a),
{ } _Base(std::move(__uset._M_base()), __a) { }
unordered_multiset(initializer_list<value_type> __l, unordered_multiset(initializer_list<value_type> __l,
size_type __n = 0, size_type __n = 0,
...@@ -578,48 +536,28 @@ namespace __debug ...@@ -578,48 +536,28 @@ namespace __debug
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { } : _Base(__l, __n, __hf, __eql, __a) { }
~unordered_multiset() noexcept { } ~unordered_multiset() = default;
unordered_multiset& unordered_multiset&
operator=(const unordered_multiset& __x) operator=(const unordered_multiset&) = default;
{
_M_base() = __x._M_base();
this->_M_invalidate_all();
return *this;
}
unordered_multiset& unordered_multiset&
operator=(unordered_multiset&& __x) operator=(unordered_multiset&&) = default;
noexcept(_Alloc_traits::_S_nothrow_move())
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
__x._M_invalidate_all();
return *this;
}
unordered_multiset& unordered_multiset&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
_M_base() = __l; this->_M_base() = __l;
this->_M_invalidate_all(); this->_M_invalidate_all();
return *this; return *this;
} }
void void
swap(unordered_multiset& __x) swap(unordered_multiset& __x)
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
{ {
if (!_Alloc_traits::_S_propagate_on_swap()) _Safe::_M_swap(__x);
__glibcxx_check_equal_allocs(__x);
_Base::swap(__x); _Base::swap(__x);
_Safe_base::_M_swap(__x);
} }
void void
...@@ -805,8 +743,8 @@ namespace __debug ...@@ -805,8 +743,8 @@ namespace __debug
std::pair<iterator, iterator> std::pair<iterator, iterator>
equal_range(const key_type& __key) equal_range(const key_type& __key)
{ {
typedef std::pair<_Base_iterator, _Base_iterator> __pair_type; std::pair<_Base_iterator, _Base_iterator> __res
__pair_type __res = _Base::equal_range(__key); = _Base::equal_range(__key);
return std::make_pair(iterator(__res.first, this), return std::make_pair(iterator(__res.first, this),
iterator(__res.second, this)); iterator(__res.second, this));
} }
...@@ -885,28 +823,10 @@ namespace __debug ...@@ -885,28 +823,10 @@ namespace __debug
private: private:
void void
_M_invalidate_locals()
{
_Base_local_iterator __local_end = _Base::end(0);
this->_M_invalidate_local_if(
[__local_end](_Base_const_local_iterator __it)
{ return __it != __local_end; });
}
void
_M_invalidate_all()
{
_Base_iterator __end = _Base::end();
this->_M_invalidate_if([__end](_Base_const_iterator __it)
{ return __it != __end; });
_M_invalidate_locals();
}
void
_M_check_rehashed(size_type __prev_count) _M_check_rehashed(size_type __prev_count)
{ {
if (__prev_count != this->bucket_count()) if (__prev_count != this->bucket_count())
_M_invalidate_locals(); this->_M_invalidate_locals();
} }
}; };
......
...@@ -32,8 +32,68 @@ ...@@ -32,8 +32,68 @@
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <debug/safe_sequence.h> #include <debug/safe_sequence.h>
#include <debug/safe_container.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
namespace __gnu_debug
{
/// Special vector safe base class to add a guaranteed capacity information
/// useful to detect code relying on the libstdc++ reallocation management
/// implementation detail.
template<typename _SafeSequence,
typename _BaseSequence>
class _Safe_vector
{
typedef typename _BaseSequence::size_type size_type;
const _SafeSequence&
_M_seq() const { return *static_cast<const _SafeSequence*>(this); }
protected:
_Safe_vector() _GLIBCXX_NOEXCEPT
: _M_guaranteed_capacity(0)
{ _M_update_guaranteed_capacity(); }
_Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
: _M_guaranteed_capacity(0)
{ _M_update_guaranteed_capacity(); }
_Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
: _M_guaranteed_capacity(__n)
{ }
#if __cplusplus >= 201103L
_Safe_vector(_Safe_vector&& __x) noexcept
: _Safe_vector()
{ __x._M_guaranteed_capacity = 0; }
_Safe_vector&
operator=(const _Safe_vector&) noexcept
{ _M_update_guaranteed_capacity(); }
_Safe_vector&
operator=(_Safe_vector&& __x) noexcept
{
_M_update_guaranteed_capacity();
__x._M_guaranteed_capacity = 0;
}
#endif
size_type _M_guaranteed_capacity;
bool
_M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
{ return __elements > _M_seq().capacity(); }
void
_M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
{
if (_M_seq().size() > _M_guaranteed_capacity)
_M_guaranteed_capacity = _M_seq().size();
}
};
}
namespace std _GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
{ {
namespace __debug namespace __debug
...@@ -42,28 +102,30 @@ namespace __debug ...@@ -42,28 +102,30 @@ namespace __debug
template<typename _Tp, template<typename _Tp,
typename _Allocator = std::allocator<_Tp> > typename _Allocator = std::allocator<_Tp> >
class vector class vector
: public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, : public __gnu_debug::_Safe_container<
public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
public __gnu_debug::_Safe_vector<
vector<_Tp, _Allocator>,
_GLIBCXX_STD_C::vector<_Tp, _Allocator> >
{ {
typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_container<
vector, _Allocator, __gnu_debug::_Safe_sequence> _Safe;
typedef __gnu_debug::_Safe_vector<vector, _Base> _Safe_vector;
typedef typename _Base::iterator _Base_iterator; typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_iterator; typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
#if __cplusplus >= 201103L
typedef __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> > _Safe_base;
typedef __gnu_cxx::__alloc_traits<_Allocator> _Alloc_traits;
#endif
public: public:
typedef typename _Base::reference reference; typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference; typedef typename _Base::const_reference const_reference;
typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector> typedef __gnu_debug::_Safe_iterator<
iterator; _Base_iterator, vector> iterator;
typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector> typedef __gnu_debug::_Safe_iterator<
const_iterator; _Base_const_iterator, vector> const_iterator;
typedef typename _Base::size_type size_type; typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type; typedef typename _Base::difference_type difference_type;
...@@ -77,26 +139,30 @@ namespace __debug ...@@ -77,26 +139,30 @@ namespace __debug
// 23.2.4.1 construct/copy/destroy: // 23.2.4.1 construct/copy/destroy:
#if __cplusplus < 201103L
vector() _GLIBCXX_NOEXCEPT vector() _GLIBCXX_NOEXCEPT
: _Base(), _M_guaranteed_capacity(0) { } : _Base() { }
#else
vector() = default;
#endif
explicit explicit
vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
: _Base(__a), _M_guaranteed_capacity(0) { } : _Base(__a) { }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
explicit explicit
vector(size_type __n, const _Allocator& __a = _Allocator()) vector(size_type __n, const _Allocator& __a = _Allocator())
: _Base(__n, __a), _M_guaranteed_capacity(__n) { } : _Base(__n, __a), _Safe_vector(__n) { }
vector(size_type __n, const _Tp& __value, vector(size_type __n, const _Tp& __value,
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } : _Base(__n, __value, __a) { }
#else #else
explicit explicit
vector(size_type __n, const _Tp& __value = _Tp(), vector(size_type __n, const _Tp& __value = _Tp(),
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { } : _Base(__n, __value, __a) { }
#endif #endif
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
...@@ -109,79 +175,58 @@ namespace __debug ...@@ -109,79 +175,58 @@ namespace __debug
const _Allocator& __a = _Allocator()) const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)), __last)),
__gnu_debug::__base(__last), __a), __gnu_debug::__base(__last), __a) { }
_M_guaranteed_capacity(0)
{ _M_update_guaranteed_capacity(); }
#if __cplusplus < 201103L
vector(const vector& __x) vector(const vector& __x)
: _Base(__x), _M_guaranteed_capacity(__x.size()) { } : _Base(__x) { }
/// Construction from a normal-mode vector ~vector() _GLIBCXX_NOEXCEPT { }
vector(const _Base& __x) #else
: _Base(__x), _M_guaranteed_capacity(__x.size()) { } vector(const vector&) = default;
vector(vector&&) = default;
#if __cplusplus >= 201103L
vector(vector&& __x) noexcept
: _Base(std::move(__x)),
_Safe_base(std::move(__x)),
_M_guaranteed_capacity(this->size())
{ __x._M_guaranteed_capacity = 0; }
vector(const vector& __x, const allocator_type& __a) vector(const vector& __x, const allocator_type& __a)
: _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { } : _Base(__x, __a) { }
vector(vector&& __x, const allocator_type& __a) vector(vector&& __x, const allocator_type& __a)
: _Base(std::move(__x), __a), : _Safe(std::move(__x._M_safe()), __a),
_M_guaranteed_capacity(this->size()) _Base(std::move(__x._M_base()), __a),
{ _Safe_vector(std::move(__x)) { }
if (__x.get_allocator() == __a)
this->_M_swap(__x);
else
__x._M_invalidate_all();
__x._M_guaranteed_capacity = 0;
}
vector(initializer_list<value_type> __l, vector(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__l, __a), : _Base(__l, __a) { }
_M_guaranteed_capacity(__l.size()) { }
~vector() = default;
#endif #endif
~vector() _GLIBCXX_NOEXCEPT { } /// Construction from a normal-mode vector
vector(const _Base& __x)
: _Base(__x) { }
#if __cplusplus < 201103L
vector& vector&
operator=(const vector& __x) operator=(const vector& __x)
{ {
this->_M_safe() = __x;
_M_base() = __x; _M_base() = __x;
this->_M_invalidate_all(); this->_M_update_guaranteed_capacity();
_M_update_guaranteed_capacity();
return *this; return *this;
} }
#else
vector&
operator=(const vector&) = default;
#if __cplusplus >= 201103L
vector& vector&
operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) operator=(vector&&) = default;
{
__glibcxx_check_self_move_assign(__x);
bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign()
|| __x.get_allocator() == this->get_allocator();
_M_base() = std::move(__x._M_base());
if (__xfer_memory)
this->_M_swap(__x);
else
this->_M_invalidate_all();
_M_update_guaranteed_capacity();
__x._M_invalidate_all();
__x._M_guaranteed_capacity = 0;
return *this;
}
vector& vector&
operator=(initializer_list<value_type> __l) operator=(initializer_list<value_type> __l)
{ {
_M_base() = __l; _M_base() = __l;
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
return *this; return *this;
} }
#endif #endif
...@@ -199,7 +244,7 @@ namespace __debug ...@@ -199,7 +244,7 @@ namespace __debug
_Base::assign(__gnu_debug::__base(__first), _Base::assign(__gnu_debug::__base(__first),
__gnu_debug::__base(__last)); __gnu_debug::__base(__last));
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
void void
...@@ -207,7 +252,7 @@ namespace __debug ...@@ -207,7 +252,7 @@ namespace __debug
{ {
_Base::assign(__n, __u); _Base::assign(__n, __u);
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
...@@ -216,7 +261,7 @@ namespace __debug ...@@ -216,7 +261,7 @@ namespace __debug
{ {
_Base::assign(__l); _Base::assign(__l);
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#endif #endif
...@@ -281,37 +326,37 @@ namespace __debug ...@@ -281,37 +326,37 @@ namespace __debug
void void
resize(size_type __sz) resize(size_type __sz)
{ {
bool __realloc = _M_requires_reallocation(__sz); bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size()) if (__sz < this->size())
this->_M_invalidate_after_nth(__sz); this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz); _Base::resize(__sz);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
void void
resize(size_type __sz, const _Tp& __c) resize(size_type __sz, const _Tp& __c)
{ {
bool __realloc = _M_requires_reallocation(__sz); bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size()) if (__sz < this->size())
this->_M_invalidate_after_nth(__sz); this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c); _Base::resize(__sz, __c);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#else #else
void void
resize(size_type __sz, _Tp __c = _Tp()) resize(size_type __sz, _Tp __c = _Tp())
{ {
bool __realloc = _M_requires_reallocation(__sz); bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size()) if (__sz < this->size())
this->_M_invalidate_after_nth(__sz); this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c); _Base::resize(__sz, __c);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#endif #endif
...@@ -321,7 +366,7 @@ namespace __debug ...@@ -321,7 +366,7 @@ namespace __debug
{ {
if (_Base::_M_shrink_to_fit()) if (_Base::_M_shrink_to_fit())
{ {
_M_guaranteed_capacity = _Base::capacity(); this->_M_guaranteed_capacity = _Base::capacity();
this->_M_invalidate_all(); this->_M_invalidate_all();
} }
} }
...@@ -331,7 +376,7 @@ namespace __debug ...@@ -331,7 +376,7 @@ namespace __debug
capacity() const _GLIBCXX_NOEXCEPT capacity() const _GLIBCXX_NOEXCEPT
{ {
#ifdef _GLIBCXX_DEBUG_PEDANTIC #ifdef _GLIBCXX_DEBUG_PEDANTIC
return _M_guaranteed_capacity; return this->_M_guaranteed_capacity;
#else #else
return _Base::capacity(); return _Base::capacity();
#endif #endif
...@@ -342,10 +387,10 @@ namespace __debug ...@@ -342,10 +387,10 @@ namespace __debug
void void
reserve(size_type __n) reserve(size_type __n)
{ {
bool __realloc = _M_requires_reallocation(__n); bool __realloc = this->_M_requires_reallocation(__n);
_Base::reserve(__n); _Base::reserve(__n);
if (__n > _M_guaranteed_capacity) if (__n > this->_M_guaranteed_capacity)
_M_guaranteed_capacity = __n; this->_M_guaranteed_capacity = __n;
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
} }
...@@ -403,11 +448,11 @@ namespace __debug ...@@ -403,11 +448,11 @@ namespace __debug
void void
push_back(const _Tp& __x) push_back(const _Tp& __x)
{ {
bool __realloc = _M_requires_reallocation(this->size() + 1); bool __realloc = this->_M_requires_reallocation(this->size() + 1);
_Base::push_back(__x); _Base::push_back(__x);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
...@@ -421,11 +466,11 @@ namespace __debug ...@@ -421,11 +466,11 @@ namespace __debug
void void
emplace_back(_Args&&... __args) emplace_back(_Args&&... __args)
{ {
bool __realloc = _M_requires_reallocation(this->size() + 1); bool __realloc = this->_M_requires_reallocation(this->size() + 1);
_Base::emplace_back(std::forward<_Args>(__args)...); _Base::emplace_back(std::forward<_Args>(__args)...);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#endif #endif
...@@ -443,7 +488,7 @@ namespace __debug ...@@ -443,7 +488,7 @@ namespace __debug
emplace(const_iterator __position, _Args&&... __args) emplace(const_iterator __position, _Args&&... __args)
{ {
__glibcxx_check_insert(__position); __glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + 1); bool __realloc = this->_M_requires_reallocation(this->size() + 1);
difference_type __offset = __position.base() - _Base::begin(); difference_type __offset = __position.base() - _Base::begin();
_Base_iterator __res = _Base::emplace(__position.base(), _Base_iterator __res = _Base::emplace(__position.base(),
std::forward<_Args>(__args)...); std::forward<_Args>(__args)...);
...@@ -451,7 +496,7 @@ namespace __debug ...@@ -451,7 +496,7 @@ namespace __debug
this->_M_invalidate_all(); this->_M_invalidate_all();
else else
this->_M_invalidate_after_nth(__offset); this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
return iterator(__res, this); return iterator(__res, this);
} }
#endif #endif
...@@ -464,14 +509,14 @@ namespace __debug ...@@ -464,14 +509,14 @@ namespace __debug
#endif #endif
{ {
__glibcxx_check_insert(__position); __glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + 1); bool __realloc = this->_M_requires_reallocation(this->size() + 1);
difference_type __offset = __position.base() - _Base::begin(); difference_type __offset = __position.base() - _Base::begin();
_Base_iterator __res = _Base::insert(__position.base(), __x); _Base_iterator __res = _Base::insert(__position.base(), __x);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
else else
this->_M_invalidate_after_nth(__offset); this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
return iterator(__res, this); return iterator(__res, this);
} }
...@@ -492,14 +537,14 @@ namespace __debug ...@@ -492,14 +537,14 @@ namespace __debug
insert(const_iterator __position, size_type __n, const _Tp& __x) insert(const_iterator __position, size_type __n, const _Tp& __x)
{ {
__glibcxx_check_insert(__position); __glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + __n); bool __realloc = this->_M_requires_reallocation(this->size() + __n);
difference_type __offset = __position.base() - _Base::cbegin(); difference_type __offset = __position.base() - _Base::cbegin();
_Base_iterator __res = _Base::insert(__position.base(), __n, __x); _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
else else
this->_M_invalidate_after_nth(__offset); this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
return iterator(__res, this); return iterator(__res, this);
} }
#else #else
...@@ -507,14 +552,14 @@ namespace __debug ...@@ -507,14 +552,14 @@ namespace __debug
insert(iterator __position, size_type __n, const _Tp& __x) insert(iterator __position, size_type __n, const _Tp& __x)
{ {
__glibcxx_check_insert(__position); __glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + __n); bool __realloc = this->_M_requires_reallocation(this->size() + __n);
difference_type __offset = __position.base() - _Base::begin(); difference_type __offset = __position.base() - _Base::begin();
_Base::insert(__position.base(), __n, __x); _Base::insert(__position.base(), __n, __x);
if (__realloc) if (__realloc)
this->_M_invalidate_all(); this->_M_invalidate_all();
else else
this->_M_invalidate_after_nth(__offset); this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#endif #endif
...@@ -540,7 +585,7 @@ namespace __debug ...@@ -540,7 +585,7 @@ namespace __debug
this->_M_invalidate_all(); this->_M_invalidate_all();
else else
this->_M_invalidate_after_nth(__offset); this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
return iterator(__res, this); return iterator(__res, this);
} }
#else #else
...@@ -563,7 +608,7 @@ namespace __debug ...@@ -563,7 +608,7 @@ namespace __debug
this->_M_invalidate_all(); this->_M_invalidate_all();
else else
this->_M_invalidate_after_nth(__offset); this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity(); this->_M_update_guaranteed_capacity();
} }
#endif #endif
...@@ -611,16 +656,12 @@ namespace __debug ...@@ -611,16 +656,12 @@ namespace __debug
void void
swap(vector& __x) swap(vector& __x)
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
noexcept(_Alloc_traits::_S_nothrow_swap()) noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif #endif
{ {
#if __cplusplus >= 201103L _Safe::_M_swap(__x);
if (!_Alloc_traits::_S_propagate_on_swap())
__glibcxx_check_equal_allocs(__x);
#endif
_Base::swap(__x); _Base::swap(__x);
this->_M_swap(__x); std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
} }
void void
...@@ -628,7 +669,7 @@ namespace __debug ...@@ -628,7 +669,7 @@ namespace __debug
{ {
_Base::clear(); _Base::clear();
this->_M_invalidate_all(); this->_M_invalidate_all();
_M_guaranteed_capacity = 0; this->_M_guaranteed_capacity = 0;
} }
_Base& _Base&
...@@ -638,19 +679,6 @@ namespace __debug ...@@ -638,19 +679,6 @@ namespace __debug
_M_base() const _GLIBCXX_NOEXCEPT { return *this; } _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
private: private:
size_type _M_guaranteed_capacity;
bool
_M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT
{ return __elements > this->capacity(); }
void
_M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
{
if (this->size() > _M_guaranteed_capacity)
_M_guaranteed_capacity = this->size();
}
void void
_M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
{ {
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
#include <debug/debug.h> #include <debug/debug.h>
#include <debug/safe_sequence.h> #include <debug/safe_base.h>
#include <debug/safe_unordered_container.h> #include <debug/safe_unordered_base.h>
#include <debug/safe_iterator.h> #include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h> #include <debug/safe_local_iterator.h>
#include <algorithm> #include <algorithm>
...@@ -235,7 +235,7 @@ namespace __gnu_debug ...@@ -235,7 +235,7 @@ namespace __gnu_debug
void void
_Safe_sequence_base:: _Safe_sequence_base::
_M_swap(_Safe_sequence_base& __x) _M_swap(_Safe_sequence_base& __x) noexcept
{ {
// We need to lock both sequences to swap // We need to lock both sequences to swap
using namespace __gnu_cxx; using namespace __gnu_cxx;
...@@ -382,7 +382,7 @@ namespace __gnu_debug ...@@ -382,7 +382,7 @@ namespace __gnu_debug
_Safe_unordered_container_base* _Safe_unordered_container_base*
_Safe_local_iterator_base:: _Safe_local_iterator_base::
_M_get_container() const _GLIBCXX_NOEXCEPT _M_get_container() const noexcept
{ return static_cast<_Safe_unordered_container_base*>(_M_sequence); } { return static_cast<_Safe_unordered_container_base*>(_M_sequence); }
void void
...@@ -455,7 +455,7 @@ namespace __gnu_debug ...@@ -455,7 +455,7 @@ namespace __gnu_debug
void void
_Safe_unordered_container_base:: _Safe_unordered_container_base::
_M_swap(_Safe_unordered_container_base& __x) _M_swap(_Safe_unordered_container_base& __x) noexcept
{ {
// We need to lock both containers to swap // We need to lock both containers to swap
using namespace __gnu_cxx; using namespace __gnu_cxx;
......
...@@ -32,9 +32,11 @@ void test01() ...@@ -32,9 +32,11 @@ void test01()
typedef std::forward_list<T, alloc_type> test_type; typedef std::forward_list<T, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { T() }; v1 = { T() };
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -46,11 +46,13 @@ void test02() ...@@ -46,11 +46,13 @@ void test02()
typedef std::forward_list<T, alloc_type> test_type; typedef std::forward_list<T, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.push_front(T()); v1.push_front(T());
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2.push_front(T()); v2.push_front(T());
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality()); VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <forward_list>
#include <debug/checks.h>
void test01()
{
__gnu_test::check_construct1<std::forward_list<int> >();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <forward_list>
#include <debug/checks.h>
void test01()
{
__gnu_test::check_construct2<std::forward_list<int> >();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2010-2014 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/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <forward_list>
#include <debug/checks.h>
void test01()
{
__gnu_test::check_construct3<std::forward_list<int> >();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/forward_list>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::forward_list<int, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_front(0);
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it == v2.begin() ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/forward_list>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::forward_list<int, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_front(0);
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.push_front(1);
v2 = std::move(v1);
VERIFY( *it == 0 ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/forward_list>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<int> alloc_type;
typedef __gnu_debug::forward_list<int, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { 0 };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -38,9 +38,13 @@ void test01() ...@@ -38,9 +38,13 @@ void test01()
typedef std::map<T, U, Cmp, alloc_type> test_type; typedef std::map<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -38,9 +38,11 @@ void test01() ...@@ -38,9 +38,11 @@ void test01()
typedef std::map<T, U, Cmp, alloc_type> test_type; typedef std::map<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality()); VERIFY(2 == v2.get_allocator().get_personality());
} }
...@@ -52,11 +54,15 @@ void test02() ...@@ -52,11 +54,15 @@ void test02()
typedef std::map<T, U, Cmp, alloc_type> test_type; typedef std::map<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality()); VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it->first == 0 ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.insert(std::make_pair(1, 1));
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::map<int, int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { { 0, 0 } };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it->first == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -38,9 +38,13 @@ void test01() ...@@ -38,9 +38,13 @@ void test01()
typedef std::multimap<T, U, Cmp, alloc_type> test_type; typedef std::multimap<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -52,11 +52,13 @@ void test02() ...@@ -52,11 +52,13 @@ void test02()
typedef std::multimap<T, U, Cmp, alloc_type> test_type; typedef std::multimap<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality()); VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it->first == 0 ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.insert(std::make_pair(1, 1));
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::multimap<int, int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { { 0, 0 } };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it->first == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -36,9 +36,13 @@ void test01() ...@@ -36,9 +36,13 @@ void test01()
typedef std::multiset<T, Cmp, alloc_type> test_type; typedef std::multiset<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -50,11 +50,13 @@ void test02() ...@@ -50,11 +50,13 @@ void test02()
typedef std::multiset<T, Cmp, alloc_type> test_type; typedef std::multiset<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality()); VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(0);
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(0);
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.insert(1);
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/set>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<int> alloc_type;
typedef __gnu_debug::multiset<int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { 0 };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -38,9 +38,13 @@ void test01() ...@@ -38,9 +38,13 @@ void test01()
typedef std::set<T, Cmp, alloc_type> test_type; typedef std::set<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -50,11 +50,13 @@ void test02() ...@@ -50,11 +50,13 @@ void test02()
typedef std::set<T, Cmp, alloc_type> test_type; typedef std::set<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1 = { test_type::value_type{} }; v1 = { test_type::value_type{} };
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2 = { test_type::value_type{} }; v2 = { test_type::value_type{} };
v2 = std::move(v1); v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality()); VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(0);
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(0);
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.insert(1);
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/set>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<int> alloc_type;
typedef __gnu_debug::set<int, std::less<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { 0 };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -45,9 +45,11 @@ void test01() ...@@ -45,9 +45,11 @@ void test01()
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.emplace(std::piecewise_construct, v1.emplace(std::piecewise_construct,
std::make_tuple(T()), std::make_tuple(T())); std::make_tuple(T()), std::make_tuple(T()));
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -66,6 +66,8 @@ void test02() ...@@ -66,6 +66,8 @@ void test02()
v1.emplace(std::piecewise_construct, v1.emplace(std::piecewise_construct,
std::make_tuple(1), std::make_tuple(1)); std::make_tuple(1), std::make_tuple(1));
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2.emplace(std::piecewise_construct, v2.emplace(std::piecewise_construct,
std::make_tuple(2), std::make_tuple(2)); std::make_tuple(2), std::make_tuple(2));
...@@ -79,6 +81,8 @@ void test02() ...@@ -79,6 +81,8 @@ void test02()
VERIFY( counter_type::move_assign_count == 0 ); VERIFY( counter_type::move_assign_count == 0 );
VERIFY( counter_type::destructor_count == 2 ); VERIFY( counter_type::destructor_count == 2 );
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type;
typedef __gnu_debug::unordered_map<int, int, std::hash<int>,
std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::unordered_map<int, int,
std::hash<int>, std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(alloc_type(2));
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::unordered_map<
int, int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { { 0, 0 } };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it->first == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -45,9 +45,11 @@ void test01() ...@@ -45,9 +45,11 @@ void test01()
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.emplace(std::piecewise_construct, v1.emplace(std::piecewise_construct,
std::make_tuple(T()), std::make_tuple(T())); std::make_tuple(T()), std::make_tuple(T()));
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -66,6 +66,8 @@ void test02() ...@@ -66,6 +66,8 @@ void test02()
v1.emplace(std::piecewise_construct, v1.emplace(std::piecewise_construct,
std::make_tuple(1), std::make_tuple(1)); std::make_tuple(1), std::make_tuple(1));
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2.emplace(std::piecewise_construct, v2.emplace(std::piecewise_construct,
std::make_tuple(2), std::make_tuple(2)); std::make_tuple(2), std::make_tuple(2));
...@@ -79,6 +81,8 @@ void test02() ...@@ -79,6 +81,8 @@ void test02()
VERIFY( counter_type::move_assign_count == 0 ); VERIFY( counter_type::move_assign_count == 0 );
VERIFY( counter_type::destructor_count == 2 ); VERIFY( counter_type::destructor_count == 2 );
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type;
typedef __gnu_debug::unordered_multimap<int, int,
std::hash<int>, std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_map>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<std::pair<const int, int>> alloc_type;
typedef __gnu_debug::unordered_multimap<int, int, std::hash<int>,
std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(std::make_pair(0, 0));
auto it = v1.begin();
test_type v2(alloc_type(2));
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_map>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<std::pair<const int, int> > alloc_type;
typedef __gnu_debug::unordered_multimap<
int, int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { { 0, 0 } };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it->first == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -44,9 +44,11 @@ void test01() ...@@ -44,9 +44,11 @@ void test01()
typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type; typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.insert(T()); v1.insert(T());
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -63,6 +63,8 @@ void test02() ...@@ -63,6 +63,8 @@ void test02()
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.emplace(0); v1.emplace(0);
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2.emplace(0); v2.emplace(0);
...@@ -76,6 +78,8 @@ void test02() ...@@ -76,6 +78,8 @@ void test02()
VERIFY( counter_type::move_count == 0 ); VERIFY( counter_type::move_count == 0 );
VERIFY( counter_type::copy_count == 0 ); VERIFY( counter_type::copy_count == 0 );
VERIFY( counter_type::destructor_count == 1 ); VERIFY( counter_type::destructor_count == 1 );
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::unordered_multiset<int, std::hash<int>,
std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(0);
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it == v2.begin() ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::unordered_multiset<int, std::hash<int>,
std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.emplace(0);
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.emplace(1);
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_set>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<int> alloc_type;
typedef __gnu_debug::unordered_multiset<
int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { 0 };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -44,9 +44,11 @@ void test01() ...@@ -44,9 +44,11 @@ void test01()
typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type; typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.insert(T()); v1.insert(T());
auto it = v1.begin();
test_type v2(std::move(v1)); test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality()); VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality()); VERIFY(1 == v2.get_allocator().get_personality());
VERIFY( it == v2.begin() );
} }
void test02() void test02()
......
...@@ -63,6 +63,8 @@ void test02() ...@@ -63,6 +63,8 @@ void test02()
test_type v1(alloc_type(1)); test_type v1(alloc_type(1));
v1.emplace(0); v1.emplace(0);
auto it = v1.begin();
test_type v2(alloc_type(2)); test_type v2(alloc_type(2));
v2.emplace(0); v2.emplace(0);
...@@ -76,6 +78,8 @@ void test02() ...@@ -76,6 +78,8 @@ void test02()
VERIFY( counter_type::move_count == 0 ); VERIFY( counter_type::move_count == 0 );
VERIFY( counter_type::copy_count == 0 ); VERIFY( counter_type::copy_count == 0 );
VERIFY( counter_type::destructor_count == 1 ); VERIFY( counter_type::destructor_count == 1 );
VERIFY( it == v2.begin() );
} }
int main() int main()
......
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::unordered_set<int, std::hash<int>,
std::equal_to<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(0);
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( it == v2.begin() ); // Error, it is singular
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
//
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_set>
#include <testsuite_allocator.h>
void test01()
{
bool test __attribute__((unused)) = true;
typedef __gnu_test::uneq_allocator<int> alloc_type;
typedef __gnu_debug::unordered_set<int, std::hash<int>,
std::equal_to<int>,
alloc_type> test_type;
test_type v1(alloc_type(1));
v1.emplace(0);
auto it = v1.begin();
test_type v2(alloc_type(2));
v2.emplace(1);
v2 = std::move(v1);
VERIFY( it == v2.begin() ); // Error, it is singular.
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/unordered_set>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<int> alloc_type;
typedef __gnu_debug::unordered_set<
int, std::hash<int>, std::equal_to<int>, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { 0 };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 );
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2014 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/>.
// { dg-options "-std=gnu++11" }
// { dg-do run { xfail *-*-* } }
#include <debug/vector>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
using __gnu_test::uneq_allocator;
void test01()
{
bool test __attribute__((unused)) = true;
typedef uneq_allocator<int> alloc_type;
typedef __gnu_debug::vector<int, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { 0 };
auto it = v1.begin();
test_type v2(std::move(v1), alloc_type(2));
VERIFY( *it == 0 );
}
int main()
{
test01();
return 0;
}
...@@ -179,10 +179,8 @@ namespace __gnu_test ...@@ -179,10 +179,8 @@ namespace __gnu_test
val_type *first = &v.front() + 1; val_type *first = &v.front() + 1;
val_type *last = first + 2; val_type *last = first + 2;
cont_type c1(first, last);
VERIFY(c1.size() == 2);
cont_type c2(last, first); // Expected failure cont_type c(last, first); // Expected failure
} }
// Check that invalid range of debug random iterators is detected // Check that invalid range of debug random iterators is detected
...@@ -206,10 +204,8 @@ namespace __gnu_test ...@@ -206,10 +204,8 @@ namespace __gnu_test
typename vector_type::iterator first = v.begin() + 1; typename vector_type::iterator first = v.begin() + 1;
typename vector_type::iterator last = first + 2; typename vector_type::iterator last = first + 2;
cont_type c1(first, last);
VERIFY(c1.size() == 2);
cont_type c2(last, first); // Expected failure cont_type c(last, first); // Expected failure
} }
// Check that invalid range of debug not random iterators is detected // Check that invalid range of debug not random iterators is detected
...@@ -233,10 +229,8 @@ namespace __gnu_test ...@@ -233,10 +229,8 @@ namespace __gnu_test
typename list_type::iterator first = l.begin(); ++first; typename list_type::iterator first = l.begin(); ++first;
typename list_type::iterator last = first; ++last; ++last; typename list_type::iterator last = first; ++last; ++last;
cont_type c1(first, last);
VERIFY(c1.size() == 2);
cont_type c2(last, first); // Expected failure cont_type c(last, first); // Expected failure
} }
template <typename _Cont> template <typename _Cont>
......
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