===================================================================
@@ -733,6 +733,7 @@
${debug_srcdir}/multimap.h \
${debug_srcdir}/multiset.h \
${debug_srcdir}/safe_base.h \
+ ${debug_srcdir}/safe_container.h \
${debug_srcdir}/safe_iterator.h \
${debug_srcdir}/safe_iterator.tcc \
${debug_srcdir}/safe_local_iterator.h \
===================================================================
@@ -31,6 +31,7 @@
#include <deque>
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
namespace std _GLIBCXX_VISIBILITY(default)
@@ -40,21 +41,26 @@
/// Class std::deque with safety/checking/debug instrumentation.
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class deque
- : public _GLIBCXX_STD_C::deque<_Tp, _Allocator>,
- public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ 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 __gnu_debug::_Safe_container<
+ deque, _Allocator, __gnu_debug::_Safe_sequence, false> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
+
public:
typedef typename _Base::reference 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;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,deque>
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, deque>
const_iterator;
typedef typename _Base::size_type size_type;
@@ -69,8 +75,26 @@
// 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
deque(const _Allocator& __a)
: _Base(__a) { }
@@ -103,48 +127,28 @@
__gnu_debug::__base(__last), __a)
{ }
- deque(const deque& __x)
- : _Base(__x) { }
-
deque(const _Base& __x)
: _Base(__x) { }
-#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 { }
-
+#if __cplusplus < 201103L
deque&
operator=(const deque& __x)
{
- *static_cast<_Base*>(this) = __x;
- this->_M_invalidate_all();
+ this->_M_safe() = __x;
+ _M_base() = __x;
return *this;
}
+#else
+ deque&
+ operator=(const deque&) = default;
-#if __cplusplus >= 201103L
deque&
- operator=(deque&& __x) noexcept
- {
- // NB: DR 1204.
- // NB: DR 675.
- __glibcxx_check_self_move_assign(__x);
- clear();
- swap(__x);
- return *this;
- }
+ operator=(deque&&) = default;
deque&
operator=(initializer_list<value_type> __l)
{
- *static_cast<_Base*>(this) = __l;
+ _M_base() = __l;
this->_M_invalidate_all();
return *this;
}
@@ -241,7 +245,7 @@
typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
}
-
+
public:
// 23.2.1.2 capacity:
using _Base::size;
@@ -559,10 +563,13 @@
}
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);
- this->_M_swap(__x);
}
void
===================================================================
@@ -33,8 +33,138 @@
#include <forward_list>
#include <debug/safe_sequence.h>
+#include <debug/safe_container.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 = &__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 __debug
@@ -42,119 +172,88 @@
/// Class std::forward_list with safety/checking/debug instrumentation.
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class forward_list
- : public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>,
- public __gnu_debug::_Safe_sequence<forward_list<_Tp, _Alloc> >
+ : public __gnu_debug::_Safe_container<
+ 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 __gnu_debug::_Safe_container<
+ forward_list, _Alloc, __gnu_debug::_Safe_forward_list> _Safe;
typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_iterator;
- typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
- rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
-
- typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
-
public:
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<_Base_iterator,
- forward_list> iterator;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
- forward_list> const_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_iterator, forward_list> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_const_iterator, forward_list> const_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
typedef _Tp value_type;
- typedef _Alloc allocator_type;
+ typedef typename _Base::allocator_type allocator_type;
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
// 23.2.3.1 construct/copy/destroy:
explicit
- forward_list(const _Alloc& __al = _Alloc())
+ forward_list(const allocator_type& __al = allocator_type())
: _Base(__al) { }
- forward_list(const forward_list& __list, const _Alloc& __al)
+ forward_list(const forward_list& __list, const allocator_type& __al)
: _Base(__list, __al)
{ }
- forward_list(forward_list&& __list, const _Alloc& __al)
- : _Base(std::move(__list._M_base()), __al)
- {
- if (__list.get_allocator() == __al)
- this->_M_swap(__list);
- else
- __list._M_invalidate_all();
- }
+ forward_list(forward_list&& __list, const allocator_type& __al)
+ : _Safe(std::move(__list._M_safe()), __al),
+ _Base(std::move(__list._M_base()), __al)
+ { }
explicit
- forward_list(size_type __n, const _Alloc& __al = _Alloc())
+ forward_list(size_type __n, const allocator_type& __al = allocator_type())
: _Base(__n, __al)
{ }
forward_list(size_type __n, const _Tp& __value,
- const _Alloc& __al = _Alloc())
+ const allocator_type& __al = allocator_type())
: _Base(__n, __value, __al)
{ }
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
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,
__last)),
__gnu_debug::__base(__last), __al)
{ }
- forward_list(const forward_list& __list)
- : _Base(__list)
- { }
+ forward_list(const forward_list&) = default;
- forward_list(forward_list&& __list) noexcept
- : _Base(std::move(__list._M_base()))
- {
- this->_M_swap(__list);
- }
+ forward_list(forward_list&&) = default;
forward_list(std::initializer_list<_Tp> __il,
- const _Alloc& __al = _Alloc())
+ const allocator_type& __al = allocator_type())
: _Base(__il, __al)
{ }
- ~forward_list() noexcept
- { }
+ ~forward_list() = default;
forward_list&
- operator=(const forward_list& __list)
- {
- static_cast<_Base&>(*this) = __list;
- this->_M_invalidate_all();
- return *this;
- }
+ operator=(const forward_list&) = default;
forward_list&
- operator=(forward_list&& __list)
- 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;
- }
+ operator=(forward_list&&) = default;
forward_list&
operator=(std::initializer_list<_Tp> __il)
{
- static_cast<_Base&>(*this) = __il;
+ _M_base() = __il;
this->_M_invalidate_all();
return *this;
}
@@ -347,12 +446,10 @@
void
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())
- __glibcxx_check_equal_allocs(__list);
+ _Safe::_M_swap(__list);
_Base::swap(__list);
- this->_M_swap(__list);
}
void
@@ -644,93 +741,9 @@
const _Base&
_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>
- 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
operator==(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly)
===================================================================
@@ -31,6 +31,7 @@
#include <list>
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
namespace std _GLIBCXX_VISIBILITY(default)
@@ -40,15 +41,20 @@
/// Class std::list with safety/checking/debug instrumentation.
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class list
- : public _GLIBCXX_STD_C::list<_Tp, _Allocator>,
- public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ 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 __gnu_debug::_Safe_container<
+ list, _Allocator, __gnu_debug::_Safe_node_sequence, false> _Safe;
typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
+
public:
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
@@ -70,9 +76,26 @@
// 23.2.2.1 construct/copy/destroy:
- list() _GLIBCXX_NOEXCEPT
+#if __cplusplus < 201103L
+ list()
: _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
list(const _Allocator& __a) _GLIBCXX_NOEXCEPT
: _Base(__a) { }
@@ -105,49 +128,29 @@
__gnu_debug::__base(__last), __a)
{ }
- list(const list& __x)
- : _Base(__x) { }
-
list(const _Base& __x)
: _Base(__x) { }
-#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 { }
-
+#if __cplusplus < 201103L
list&
operator=(const list& __x)
{
- static_cast<_Base&>(*this) = __x;
- this->_M_invalidate_all();
+ this->_M_safe() = __x;
+ _M_base() = __x;
return *this;
}
+#else
+ list&
+ operator=(const list&) = default;
-#if __cplusplus >= 201103L
list&
- operator=(list&& __x)
- {
- // NB: DR 1204.
- // NB: DR 675.
- __glibcxx_check_self_move_assign(__x);
- clear();
- swap(__x);
- return *this;
- }
+ operator=(list&&) = default;
list&
operator=(initializer_list<value_type> __l)
{
- static_cast<_Base&>(*this) = __l;
this->_M_invalidate_all();
+ _M_base() = __l;
return *this;
}
@@ -245,16 +248,14 @@
{
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 __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
for (; __victim != __end; ++__victim)
- {
this->_M_invalidate_if(_Equal(__victim));
- }
__try
{
@@ -272,16 +273,14 @@
{
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 __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
for (; __victim != __end; ++__victim)
- {
this->_M_invalidate_if(_Equal(__victim));
- }
__try
{
@@ -299,16 +298,14 @@
{
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 __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
for (; __victim != __end; ++__victim)
- {
this->_M_invalidate_if(_Equal(__victim));
- }
__try
{
@@ -504,9 +501,12 @@
void
swap(list& __x)
+#if __cplusplus >= 201103L
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
+#endif
{
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
}
void
@@ -742,13 +742,6 @@
const _Base&
_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>
===================================================================
@@ -347,10 +347,10 @@
_M_message(__gnu_debug::__msg_valid_load_factor) \
._M_sequence(*this, "this"))
-#define __glibcxx_check_equal_allocs(_Other) \
-_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \
+#define __glibcxx_check_equal_allocs(_This, _Other) \
+_GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(), \
_M_message(__gnu_debug::__msg_equal_allocs) \
- ._M_sequence(*this, "this"))
+ ._M_sequence(_This, "this"))
#ifdef _GLIBCXX_DEBUG_PEDANTIC
# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
===================================================================
@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_MAP_H 1
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <utility>
@@ -41,19 +42,20 @@
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class map
- : public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>,
- public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ 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::iterator _Base_iterator;
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:
// types:
typedef _Key key_type;
@@ -78,33 +80,18 @@
// 23.3.1.1 construct/copy/destroy:
+#if __cplusplus < 201103L
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)
: _Base(__x) { }
- map(const _Base& __x)
- : _Base(__x) { }
+ ~map() { }
+#else
+ map() = default;
+ map(const map&) = default;
+ map(map&&) = default;
-#if __cplusplus >= 201103L
- map(map&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _Base(std::move(__x))
- { this->_M_swap(__x); }
-
map(initializer_list<value_type> __l,
const _Compare& __c = _Compare(),
const allocator_type& __a = allocator_type())
@@ -118,7 +105,8 @@
: _Base(__m, __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)
: _Base(__l, __a) { }
@@ -130,34 +118,40 @@
__last)),
__gnu_debug::__base(__last), __a)
{ }
+
+ ~map() = default;
#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&
operator=(const map& __x)
{
+ this->_M_safe() = __x;
_M_base() = __x;
- this->_M_invalidate_all();
return *this;
}
+#else
+ map&
+ operator=(const map&) = default;
-#if __cplusplus >= 201103L
map&
- operator=(map&& __x)
- 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;
- }
+ operator=(map&&) = default;
map&
operator=(initializer_list<value_type> __l)
@@ -173,7 +167,7 @@
using _Base::get_allocator;
// iterators:
- iterator
+ iterator
begin() _GLIBCXX_NOEXCEPT
{ return iterator(_Base::begin(), this); }
@@ -395,15 +389,11 @@
void
swap(map& __x)
#if __cplusplus >= 201103L
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{
-#if __cplusplus >= 201103L
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
-#endif
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
}
void
@@ -467,14 +457,6 @@
const _Base&
_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,
===================================================================
@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_MULTIMAP_H 1
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <utility>
@@ -41,20 +42,20 @@
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class multimap
- : public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>,
- public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp,
- _Compare, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ multimap<_Key, _Tp, _Compare, _Allocator>, _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::iterator _Base_iterator;
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:
// types:
typedef _Key key_type;
@@ -79,33 +80,18 @@
// 23.3.1.1 construct/copy/destroy:
+#if __cplusplus < 201103L
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)
: _Base(__x) { }
- multimap(const _Base& __x)
- : _Base(__x) { }
+ ~multimap() { }
+#else
+ multimap() = default;
+ multimap(const multimap&) = default;
+ multimap(multimap&&) = default;
-#if __cplusplus >= 201103L
- multimap(multimap&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _Base(std::move(__x))
- { this->_M_swap(__x); }
-
multimap(initializer_list<value_type> __l,
const _Compare& __c = _Compare(),
const allocator_type& __a = allocator_type())
@@ -119,47 +105,52 @@
: _Base(__m, __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)
- : _Base(__l, __a)
- { }
+ : _Base(__l, __a) { }
template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
- __gnu_debug::__base(__last), __a)
- { }
+ __gnu_debug::__base(__last), __a) { }
+
+ ~multimap() = default;
#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&
operator=(const multimap& __x)
{
+ this->_M_safe() = __x;
_M_base() = __x;
- this->_M_invalidate_all();
return *this;
}
+#else
+ multimap&
+ operator=(const multimap&) = default;
-#if __cplusplus >= 201103L
multimap&
- operator=(multimap&& __x)
- 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;
- }
+ operator=(multimap&&) = default;
multimap&
operator=(initializer_list<value_type> __l)
@@ -247,7 +238,7 @@
this);
}
#endif
-
+
iterator
insert(const value_type& __x)
{ return iterator(_Base::insert(__x), this); }
@@ -379,15 +370,11 @@
void
swap(multimap& __x)
#if __cplusplus >= 201103L
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{
-#if __cplusplus >= 201103L
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
-#endif
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
}
void
@@ -451,14 +438,6 @@
const _Base&
_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,
===================================================================
@@ -30,6 +30,7 @@
#define _GLIBCXX_DEBUG_MULTISET_H 1
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <utility>
@@ -41,19 +42,19 @@
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> >
class multiset
- : public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>,
- public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ 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 __gnu_debug::_Safe_container<
+ multiset, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator;
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:
// types:
typedef _Key key_type;
@@ -78,33 +79,18 @@
// 23.3.3.1 construct/copy/destroy:
+#if __cplusplus < 201103L
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)
: _Base(__x) { }
- multiset(const _Base& __x)
- : _Base(__x) { }
+ ~multiset() { }
+#else
+ multiset() = default;
+ multiset(const multiset&) = default;
+ multiset(multiset&&) = default;
-#if __cplusplus >= 201103L
- multiset(multiset&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _Base(std::move(__x))
- { this->_M_swap(__x); }
-
multiset(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
@@ -118,7 +104,8 @@
: _Base(__m, __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)
: _Base(__l, __a)
@@ -129,36 +116,41 @@
const allocator_type& __a)
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
- __gnu_debug::__base(__last), __a)
- { }
+ __gnu_debug::__base(__last), __a) { }
+
+ ~multiset() = default;
#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&
operator=(const multiset& __x)
{
+ this->_M_safe() = __x;
_M_base() = __x;
- this->_M_invalidate_all();
return *this;
}
+#else
+ multiset&
+ operator=(const multiset&) = default;
-#if __cplusplus >= 201103L
multiset&
- operator=(multiset&& __x)
- 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;
- }
+ operator=(multiset&&) = default;
multiset&
operator=(initializer_list<value_type> __l)
@@ -233,7 +225,8 @@
iterator
emplace(_Args&&... __args)
{
- return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
+ return iterator(_Base::emplace(std::forward<_Args>(__args)...),
+ this);
}
template<typename... _Args>
@@ -364,15 +357,11 @@
void
swap(multiset& __x)
#if __cplusplus >= 201103L
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{
-#if __cplusplus >= 201103L
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
-#endif
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
}
void
@@ -444,14 +433,6 @@
const _Base&
_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>
===================================================================
@@ -104,7 +104,8 @@
~_Safe_iterator_base() { this->_M_detach(); }
/** For use in _Safe_iterator. */
- __gnu_cxx::__mutex& _M_get_mutex() throw ();
+ __gnu_cxx::__mutex&
+ _M_get_mutex() throw ();
public:
/** Attaches this iterator to the given sequence, detaching it
@@ -112,30 +113,37 @@
* new sequence is the NULL pointer, the iterator is left
* unattached.
*/
- void _M_attach(_Safe_sequence_base* __seq, bool __constant);
+ void
+ _M_attach(_Safe_sequence_base* __seq, bool __constant);
/** 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,
* if any.
*/
- void _M_detach();
+ void
+ _M_detach();
/** Likewise, but not thread-safe. */
- void _M_detach_single() throw ();
+ void
+ _M_detach_single() throw ();
/** 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; }
/** 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?
Returns true if both iterators are nonsingular and reference
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. */
void
@@ -188,17 +196,13 @@
protected:
// 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)
{ }
#if __cplusplus >= 201103L
_Safe_sequence_base(const _Safe_sequence_base&) noexcept
: _Safe_sequence_base() { }
-
- _Safe_sequence_base(_Safe_sequence_base&& __x) noexcept
- : _Safe_sequence_base()
- { _M_swap(__x); }
#endif
/** Notify all iterators that reference this sequence that the
@@ -231,10 +235,11 @@
* one container now reference the other container.
*/
void
- _M_swap(_Safe_sequence_base& __x);
+ _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT;
/** For use in _Safe_sequence. */
- __gnu_cxx::__mutex& _M_get_mutex() throw ();
+ __gnu_cxx::__mutex&
+ _M_get_mutex() throw ();
public:
/** Invalidates all iterators. */
===================================================================
@@ -0,0 +1,125 @@
+// 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
===================================================================
@@ -58,7 +58,7 @@
/** Iterators that derive from _Safe_iterator_base can be determined singular
* or non-singular.
**/
- inline bool
+ inline bool
__check_singular_aux(const _Safe_iterator_base* __x)
{ return __x->_M_singular(); }
===================================================================
@@ -127,6 +127,25 @@
void
_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
#include <debug/safe_sequence.tcc>
===================================================================
@@ -80,7 +80,7 @@
~_Safe_local_iterator_base() { this->_M_detach(); }
_Safe_unordered_container_base*
- _M_get_container() const _GLIBCXX_NOEXCEPT;
+ _M_get_container() const noexcept;
public:
/** Attaches this iterator to the given container, detaching it
@@ -132,15 +132,16 @@
protected:
// 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)
{ }
- // 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&)
noexcept
: _Safe_unordered_container_base() { }
+ // When moved unordered containers iterators are swapped.
_Safe_unordered_container_base(_Safe_unordered_container_base&& __x)
noexcept
: _Safe_unordered_container_base()
@@ -148,7 +149,7 @@
/** Notify all iterators that reference this container that the
container is being destroyed. */
- ~_Safe_unordered_container_base()
+ ~_Safe_unordered_container_base() noexcept
{ this->_M_detach_all(); }
/** Detach all iterators, leaving them singular. */
@@ -161,7 +162,7 @@
* one container now reference the other container.
*/
void
- _M_swap(_Safe_unordered_container_base& __x);
+ _M_swap(_Safe_unordered_container_base& __x) noexcept;
public:
/** Attach an iterator to this container. */
===================================================================
@@ -57,7 +57,31 @@
template<typename _Container>
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,
are not singular, and for which @c __pred(x) returns @c
true. @c __pred will be invoked with the normal iterators nested
===================================================================
@@ -30,10 +30,11 @@
#define _GLIBCXX_DEBUG_SET_H 1
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <utility>
-namespace std _GLIBCXX_VISIBILITY(default)
+namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
@@ -41,18 +42,19 @@
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> >
class set
- : public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>,
- public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ 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 __gnu_debug::_Safe_container<
+ set, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator;
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:
// types:
typedef _Key key_type;
@@ -77,33 +79,18 @@
// 23.3.3.1 construct/copy/destroy:
+#if __cplusplus < 201103L
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)
: _Base(__x) { }
- set(const _Base& __x)
- : _Base(__x) { }
+ ~set() { }
+#else
+ set() = default;
+ set(const set&) = default;
+ set(set&&) = default;
-#if __cplusplus >= 201103L
- set(set&& __x)
- noexcept(is_nothrow_copy_constructible<_Compare>::value)
- : _Base(std::move(__x))
- { this->_M_swap(__x); }
-
set(initializer_list<value_type> __l,
const _Compare& __comp = _Compare(),
const allocator_type& __a = allocator_type())
@@ -117,47 +104,52 @@
: _Base(__x, __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)
- : _Base(__l, __a)
- { }
+ : _Base(__l, __a) { }
template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last,
const allocator_type& __a)
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
- __gnu_debug::__base(__last), __a)
- { }
+ __gnu_debug::__base(__last), __a) { }
+
+ ~set() = default;
#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&
operator=(const set& __x)
{
+ this->_M_safe() = __x;
_M_base() = __x;
- this->_M_invalidate_all();
return *this;
}
+#else
+ set&
+ operator=(const set&) = default;
-#if __cplusplus >= 201103L
set&
- operator=(set&& __x)
- 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;
- }
+ operator=(set&&) = default;
set&
operator=(initializer_list<value_type> __l)
@@ -372,15 +364,11 @@
void
swap(set& __x)
#if __cplusplus >= 201103L
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{
-#if __cplusplus >= 201103L
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
-#endif
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
}
void
@@ -452,14 +440,6 @@
const _Base&
_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>
===================================================================
@@ -31,6 +31,7 @@
#include <string>
#include <debug/safe_sequence.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
namespace __gnu_debug
@@ -39,12 +40,14 @@
template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
typename _Allocator = std::allocator<_CharT> >
class basic_string
+ : public __gnu_debug::_Safe_container<
+ basic_string<_CharT, _Traits, _Allocator>, _Allocator,
+ _Safe_sequence, false>
: public std::basic_string<_CharT, _Traits, _Allocator>,
- public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
- _Allocator> >
{
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:
// types:
@@ -58,10 +61,10 @@
typedef typename _Base::pointer pointer;
typedef typename _Base::const_pointer const_pointer;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
- iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
- basic_string> const_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ typename _Base::iterator, basic_string> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ typename _Base::const_iterator, basic_string> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -71,18 +74,29 @@
// 21.3.1 construct/copy/destroy:
explicit basic_string(const _Allocator& __a = _Allocator())
// _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) { }
+#if __cplusplus < 201103L
+ basic_string(const basic_string& __str)
+ : _Base(__str) { }
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 42. string ctors specify wrong default allocator
- basic_string(const basic_string& __str)
- : _Base(__str, 0, _Base::npos, __str.get_allocator())
+ ~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
// 42. string ctors specify wrong default allocator
basic_string(const basic_string& __str, size_type __pos,
@@ -113,32 +127,27 @@
__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&
operator=(const basic_string& __str)
{
- *static_cast<_Base*>(this) = __str;
- this->_M_invalidate_all();
+ this->_M_safe() = __str;
+ _M_base() = __str;
return *this;
}
+#else
+ basic_string&
+ operator=(const basic_string&) = default;
basic_string&
+ operator=(basic_string&&) = default;
+#endif
+
+ basic_string&
operator=(const _CharT* __s)
{
__glibcxx_check_string(__s);
- *static_cast<_Base*>(this) = __s;
+ _M_base() = __s;
this->_M_invalidate_all();
return *this;
}
@@ -146,25 +155,16 @@
basic_string&
operator=(_CharT __c)
{
- *static_cast<_Base*>(this) = __c;
+ _M_base() = __c;
this->_M_invalidate_all();
return *this;
}
#if __cplusplus >= 201103L
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)
{
- *static_cast<_Base*>(this) = __l;
+ _M_base() = __l;
this->_M_invalidate_all();
return *this;
}
@@ -704,12 +704,13 @@
}
void
- swap(basic_string<_CharT,_Traits,_Allocator>& __x)
+ swap(basic_string& __x)
+#if __cplusplus >= 201103L
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
+#endif
{
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
- this->_M_invalidate_all();
- __x._M_invalidate_all();
}
// 21.3.6 string operations:
@@ -801,7 +802,7 @@
{ return _Base::find_first_of(__c, __pos); }
size_type
- find_last_of(const basic_string& __str,
+ find_last_of(const basic_string& __str,
size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
{ return _Base::find_last_of(__str, __pos); }
@@ -922,7 +923,7 @@
const _Base&
_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>
===================================================================
@@ -35,6 +35,7 @@
# include <unordered_map>
#include <debug/safe_unordered_container.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>
@@ -48,21 +49,21 @@
typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_map
- : public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
- public __gnu_debug::_Safe_unordered_container<unordered_map<_Key, _Tp,
- _Hash, _Pred, _Alloc> >
+ : public __gnu_debug::_Safe_container<
+ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, _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,
_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::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 __gnu_cxx::__alloc_traits<typename
- _Base::allocator_type> _Alloc_traits;
-
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
@@ -72,14 +73,14 @@
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<_Base_iterator,
- unordered_map> iterator;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
- unordered_map> const_iterator;
- typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
- unordered_map> local_iterator;
- typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
- unordered_map> const_local_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_iterator, unordered_map> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_const_iterator, unordered_map> const_iterator;
+ typedef __gnu_debug::_Safe_local_iterator<
+ _Base_local_iterator, unordered_map> local_iterator;
+ typedef __gnu_debug::_Safe_local_iterator<
+ _Base_const_local_iterator, unordered_map> const_local_iterator;
explicit
unordered_map(size_type __n = 10,
@@ -89,10 +90,10 @@
: _Base(__n, __hf, __eql, __a) { }
template<typename _InputIterator>
- unordered_map(_InputIterator __first, _InputIterator __last,
+ unordered_map(_InputIterator __first, _InputIterator __last,
size_type __n = 0,
- const hasher& __hf = hasher(),
- const key_equal& __eql = key_equal(),
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
@@ -108,18 +109,16 @@
explicit
unordered_map(const allocator_type& __a)
- : _Base(__a)
- { }
+ : _Base(__a) { }
unordered_map(const unordered_map& __umap,
const allocator_type& __a)
- : _Base(__umap._M_base(), __a)
- { }
+ : _Base(__umap, __a) { }
unordered_map(unordered_map&& __umap,
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,
size_type __n = 0,
@@ -128,31 +127,13 @@
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
- ~unordered_map() noexcept { }
+ ~unordered_map() = default;
unordered_map&
- operator=(const unordered_map& __x)
- {
- _M_base() = __x._M_base();
- this->_M_invalidate_all();
- return *this;
- }
+ operator=(const unordered_map&) = default;
unordered_map&
- operator=(unordered_map&& __x)
- 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;
- }
+ operator=(unordered_map&&) = default;
unordered_map&
operator=(initializer_list<value_type> __l)
@@ -164,12 +145,10 @@
void
swap(unordered_map& __x)
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
{
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- _Safe_base::_M_swap(__x);
}
void
@@ -179,7 +158,7 @@
this->_M_invalidate_all();
}
- iterator
+ iterator
begin() noexcept
{ return iterator(_Base::begin(), this); }
@@ -301,7 +280,7 @@
{
__glibcxx_check_insert(__hint);
size_type __bucket_count = this->bucket_count();
- _Base_iterator __it = _Base::insert(__hint.base(), __obj);
+ _Base_iterator __it = _Base::insert(__hint.base(), __obj);
_M_check_rehashed(__bucket_count);
return iterator(__it, this);
}
@@ -409,7 +388,7 @@
[__victim](_Base_const_local_iterator __it)
{ return __it._M_curr() == __victim._M_cur; });
size_type __bucket_count = this->bucket_count();
- _Base_iterator __next = _Base::erase(__it.base());
+ _Base_iterator __next = _Base::erase(__it.base());
_M_check_rehashed(__bucket_count);
return iterator(__next, this);
}
@@ -449,28 +428,10 @@
private:
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)
{
if (__prev_count != this->bucket_count())
- _M_invalidate_locals();
+ this->_M_invalidate_locals();
}
};
@@ -502,23 +463,20 @@
typename _Pred = std::equal_to<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_multimap
- : public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
- _Pred, _Alloc>,
- public __gnu_debug::_Safe_unordered_container<unordered_multimap<_Key,
- _Tp, _Hash, _Pred, _Alloc> >
+ : public __gnu_debug::_Safe_container<
+ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>, _Alloc,
+ __gnu_debug::_Safe_unordered_container>,
+ public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
{
typedef _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash,
_Pred, _Alloc> _Base;
- typedef __gnu_debug::_Safe_unordered_container<unordered_multimap>
- _Safe_base;
+ typedef __gnu_debug::_Safe_container<unordered_multimap,
+ _Alloc, __gnu_debug::_Safe_unordered_container> _Safe;
typedef typename _Base::const_iterator _Base_const_iterator;
typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_local_iterator _Base_const_local_iterator;
typedef typename _Base::local_iterator _Base_local_iterator;
- typedef __gnu_cxx::__alloc_traits<typename
- _Base::allocator_type> _Alloc_traits;
-
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
@@ -528,10 +486,10 @@
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<_Base_iterator,
- unordered_multimap> iterator;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
- unordered_multimap> const_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_iterator, unordered_multimap> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_const_iterator, unordered_multimap> const_iterator;
typedef __gnu_debug::_Safe_local_iterator<
_Base_local_iterator, unordered_multimap> local_iterator;
typedef __gnu_debug::_Safe_local_iterator<
@@ -545,10 +503,10 @@
: _Base(__n, __hf, __eql, __a) { }
template<typename _InputIterator>
- unordered_multimap(_InputIterator __first, _InputIterator __last,
+ unordered_multimap(_InputIterator __first, _InputIterator __last,
size_type __n = 0,
- const hasher& __hf = hasher(),
- const key_equal& __eql = key_equal(),
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
@@ -557,25 +515,23 @@
unordered_multimap(const unordered_multimap&) = default;
- unordered_multimap(const _Base& __x)
+ unordered_multimap(const _Base& __x)
: _Base(__x) { }
unordered_multimap(unordered_multimap&&) = default;
explicit
unordered_multimap(const allocator_type& __a)
- : _Base(__a)
- { }
+ : _Base(__a) { }
unordered_multimap(const unordered_multimap& __umap,
const allocator_type& __a)
- : _Base(__umap._M_base(), __a)
- { }
+ : _Base(__umap, __a) { }
unordered_multimap(unordered_multimap&& __umap,
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,
size_type __n = 0,
@@ -584,48 +540,28 @@
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
- ~unordered_multimap() noexcept { }
+ ~unordered_multimap() = default;
unordered_multimap&
- operator=(const unordered_multimap& __x)
- {
- _M_base() = __x._M_base();
- this->_M_invalidate_all();
- return *this;
- }
+ operator=(const unordered_multimap&) = default;
unordered_multimap&
- operator=(unordered_multimap&& __x)
- 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;
- }
+ operator=(unordered_multimap&&) = default;
unordered_multimap&
operator=(initializer_list<value_type> __l)
{
- _M_base() = __l;
+ this->_M_base() = __l;
this->_M_invalidate_all();
return *this;
}
void
swap(unordered_multimap& __x)
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
{
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- _Safe_base::_M_swap(__x);
}
void
@@ -635,7 +571,7 @@
this->_M_invalidate_all();
}
- iterator
+ iterator
begin() noexcept
{ return iterator(_Base::begin(), this); }
@@ -901,28 +837,10 @@
private:
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)
{
if (__prev_count != this->bucket_count())
- _M_invalidate_locals();
+ this->_M_invalidate_locals();
}
};
===================================================================
@@ -35,6 +35,7 @@
# include <unordered_set>
#include <debug/safe_unordered_container.h>
+#include <debug/safe_container.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>
@@ -48,20 +49,21 @@
typename _Pred = std::equal_to<_Value>,
typename _Alloc = std::allocator<_Value> >
class unordered_set
- : public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
- public __gnu_debug::_Safe_unordered_container<unordered_set<_Value, _Hash,
- _Pred, _Alloc> >
+ : public __gnu_debug::_Safe_container<
+ unordered_set<_Value, _Hash, _Pred, _Alloc>, _Alloc,
+ __gnu_debug::_Safe_unordered_container>,
+ public _GLIBCXX_STD_C::unordered_set<_Value, _Hash, _Pred, _Alloc>
{
- typedef _GLIBCXX_STD_C::unordered_set<_Value, _Hash,
- _Pred, _Alloc> _Base;
- typedef __gnu_debug::_Safe_unordered_container<unordered_set> _Safe_base;
+ typedef _GLIBCXX_STD_C::unordered_set<
+ _Value, _Hash, _Pred, _Alloc> _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::iterator _Base_iterator;
typedef typename _Base::const_local_iterator _Base_const_local_iterator;
typedef typename _Base::local_iterator _Base_local_iterator;
- typedef __gnu_cxx::__alloc_traits<typename
- _Base::allocator_type> _Alloc_traits;
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
@@ -71,14 +73,14 @@
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<_Base_iterator,
- unordered_set> iterator;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
- unordered_set> const_iterator;
- typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator,
- unordered_set> local_iterator;
- typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator,
- unordered_set> const_local_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_iterator, unordered_set> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_const_iterator, unordered_set> const_iterator;
+ typedef __gnu_debug::_Safe_local_iterator<
+ _Base_local_iterator, unordered_set> local_iterator;
+ typedef __gnu_debug::_Safe_local_iterator<
+ _Base_const_local_iterator, unordered_set> const_local_iterator;
explicit
unordered_set(size_type __n = 10,
@@ -88,10 +90,10 @@
: _Base(__n, __hf, __eql, __a) { }
template<typename _InputIterator>
- unordered_set(_InputIterator __first, _InputIterator __last,
+ unordered_set(_InputIterator __first, _InputIterator __last,
size_type __n = 0,
- const hasher& __hf = hasher(),
- const key_equal& __eql = key_equal(),
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
@@ -107,18 +109,16 @@
explicit
unordered_set(const allocator_type& __a)
- : _Base(__a)
- { }
+ : _Base(__a) { }
unordered_set(const unordered_set& __uset,
const allocator_type& __a)
- : _Base(__uset._M_base(), __a)
- { }
+ : _Base(__uset, __a) { }
unordered_set(unordered_set&& __uset,
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,
size_type __n = 0,
@@ -127,31 +127,13 @@
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
- ~unordered_set() noexcept { }
+ ~unordered_set() = default;
unordered_set&
- operator=(const unordered_set& __x)
- {
- _M_base() = __x._M_base();
- this->_M_invalidate_all();
- return *this;
- }
+ operator=(const unordered_set&) = default;
unordered_set&
- operator=(unordered_set&& __x)
- 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;
- }
+ operator=(unordered_set&&) = default;
unordered_set&
operator=(initializer_list<value_type> __l)
@@ -163,12 +145,10 @@
void
swap(unordered_set& __x)
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
{
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- _Safe_base::_M_swap(__x);
}
void
@@ -178,7 +158,7 @@
this->_M_invalidate_all();
}
- iterator
+ iterator
begin() noexcept
{ return iterator(_Base::begin(), this); }
@@ -290,8 +270,8 @@
insert(const value_type& __obj)
{
size_type __bucket_count = this->bucket_count();
- typedef std::pair<_Base_iterator, bool> __pair_type;
- __pair_type __res = _Base::insert(__obj);
+ std::pair<_Base_iterator, bool> __res
+ = _Base::insert(__obj);
_M_check_rehashed(__bucket_count);
return std::make_pair(iterator(__res.first, this), __res.second);
}
@@ -310,8 +290,8 @@
insert(value_type&& __obj)
{
size_type __bucket_count = this->bucket_count();
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
- __pair_type __res = _Base::insert(std::move(__obj));
+ std::pair<_Base_iterator, bool> __res
+ = _Base::insert(std::move(__obj));
_M_check_rehashed(__bucket_count);
return std::make_pair(iterator(__res.first, this), __res.second);
}
@@ -356,8 +336,8 @@
std::pair<iterator, iterator>
equal_range(const key_type& __key)
{
- typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
- __pair_type __res = _Base::equal_range(__key);
+ std::pair<_Base_iterator, _Base_iterator> __res
+ = _Base::equal_range(__key);
return std::make_pair(iterator(__res.first, this),
iterator(__res.second, this));
}
@@ -446,29 +426,10 @@
private:
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)
{
if (__prev_count != this->bucket_count())
- _M_invalidate_locals();
+ this->_M_invalidate_locals();
}
};
@@ -497,22 +458,21 @@
typename _Pred = std::equal_to<_Value>,
typename _Alloc = std::allocator<_Value> >
class unordered_multiset
- : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
- public __gnu_debug::_Safe_unordered_container<
- unordered_multiset<_Value, _Hash, _Pred, _Alloc> >
+ : public __gnu_debug::_Safe_container<
+ unordered_multiset<_Value, _Hash, _Pred, _Alloc>, _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 __gnu_debug::_Safe_unordered_container<unordered_multiset>
- _Safe_base;
+ typedef _GLIBCXX_STD_C::unordered_multiset<
+ _Value, _Hash, _Pred, _Alloc> _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::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 __gnu_cxx::__alloc_traits<typename
- _Base::allocator_type> _Alloc_traits;
-
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
@@ -522,10 +482,10 @@
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<_Base_iterator,
- unordered_multiset> iterator;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
- unordered_multiset> const_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_iterator, unordered_multiset> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_const_iterator, unordered_multiset> const_iterator;
typedef __gnu_debug::_Safe_local_iterator<
_Base_local_iterator, unordered_multiset> local_iterator;
typedef __gnu_debug::_Safe_local_iterator<
@@ -539,10 +499,10 @@
: _Base(__n, __hf, __eql, __a) { }
template<typename _InputIterator>
- unordered_multiset(_InputIterator __first, _InputIterator __last,
+ unordered_multiset(_InputIterator __first, _InputIterator __last,
size_type __n = 0,
- const hasher& __hf = hasher(),
- const key_equal& __eql = key_equal(),
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
@@ -551,25 +511,23 @@
unordered_multiset(const unordered_multiset&) = default;
- unordered_multiset(const _Base& __x)
+ unordered_multiset(const _Base& __x)
: _Base(__x) { }
unordered_multiset(unordered_multiset&&) = default;
explicit
unordered_multiset(const allocator_type& __a)
- : _Base(__a)
- { }
+ : _Base(__a) { }
unordered_multiset(const unordered_multiset& __uset,
const allocator_type& __a)
- : _Base(__uset._M_base(), __a)
- { }
-
+ : _Base(__uset, __a) { }
+
unordered_multiset(unordered_multiset&& __uset,
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,
size_type __n = 0,
@@ -578,48 +536,28 @@
const allocator_type& __a = allocator_type())
: _Base(__l, __n, __hf, __eql, __a) { }
- ~unordered_multiset() noexcept { }
+ ~unordered_multiset() = default;
unordered_multiset&
- operator=(const unordered_multiset& __x)
- {
- _M_base() = __x._M_base();
- this->_M_invalidate_all();
- return *this;
- }
+ operator=(const unordered_multiset&) = default;
unordered_multiset&
- operator=(unordered_multiset&& __x)
- 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;
- }
+ operator=(unordered_multiset&&) = default;
unordered_multiset&
operator=(initializer_list<value_type> __l)
{
- _M_base() = __l;
+ this->_M_base() = __l;
this->_M_invalidate_all();
return *this;
}
void
swap(unordered_multiset& __x)
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
{
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- _Safe_base::_M_swap(__x);
}
void
@@ -751,7 +689,7 @@
{
__glibcxx_check_insert(__hint);
size_type __bucket_count = this->bucket_count();
- _Base_iterator __it = _Base::insert(__hint.base(), __obj);
+ _Base_iterator __it = _Base::insert(__hint.base(), __obj);
_M_check_rehashed(__bucket_count);
return iterator(__it, this);
}
@@ -760,7 +698,7 @@
insert(value_type&& __obj)
{
size_type __bucket_count = this->bucket_count();
- _Base_iterator __it = _Base::insert(std::move(__obj));
+ _Base_iterator __it = _Base::insert(std::move(__obj));
_M_check_rehashed(__bucket_count);
return iterator(__it, this);
}
@@ -770,7 +708,7 @@
{
__glibcxx_check_insert(__hint);
size_type __bucket_count = this->bucket_count();
- _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
+ _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj));
_M_check_rehashed(__bucket_count);
return iterator(__it, this);
}
@@ -805,8 +743,8 @@
std::pair<iterator, iterator>
equal_range(const key_type& __key)
{
- typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
- __pair_type __res = _Base::equal_range(__key);
+ std::pair<_Base_iterator, _Base_iterator> __res
+ = _Base::equal_range(__key);
return std::make_pair(iterator(__res.first, this),
iterator(__res.second, this));
}
@@ -885,28 +823,10 @@
private:
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)
{
if (__prev_count != this->bucket_count())
- _M_invalidate_locals();
+ this->_M_invalidate_locals();
}
};
===================================================================
@@ -32,8 +32,68 @@
#include <vector>
#include <utility>
#include <debug/safe_sequence.h>
+#include <debug/safe_container.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 __debug
@@ -42,28 +102,30 @@
template<typename _Tp,
typename _Allocator = std::allocator<_Tp> >
class vector
- : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
- public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
+ : public __gnu_debug::_Safe_container<
+ 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 __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::const_iterator _Base_const_iterator;
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:
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector>
- iterator;
- typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector>
- const_iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_iterator, vector> iterator;
+ typedef __gnu_debug::_Safe_iterator<
+ _Base_const_iterator, vector> const_iterator;
typedef typename _Base::size_type size_type;
typedef typename _Base::difference_type difference_type;
@@ -77,26 +139,30 @@
// 23.2.4.1 construct/copy/destroy:
+#if __cplusplus < 201103L
vector() _GLIBCXX_NOEXCEPT
- : _Base(), _M_guaranteed_capacity(0) { }
+ : _Base() { }
+#else
+ vector() = default;
+#endif
explicit
vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
- : _Base(__a), _M_guaranteed_capacity(0) { }
+ : _Base(__a) { }
#if __cplusplus >= 201103L
explicit
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,
const _Allocator& __a = _Allocator())
- : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
+ : _Base(__n, __value, __a) { }
#else
explicit
vector(size_type __n, const _Tp& __value = _Tp(),
const _Allocator& __a = _Allocator())
- : _Base(__n, __value, __a), _M_guaranteed_capacity(__n) { }
+ : _Base(__n, __value, __a) { }
#endif
#if __cplusplus >= 201103L
@@ -109,79 +175,58 @@
const _Allocator& __a = _Allocator())
: _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
__last)),
- __gnu_debug::__base(__last), __a),
- _M_guaranteed_capacity(0)
- { _M_update_guaranteed_capacity(); }
+ __gnu_debug::__base(__last), __a) { }
+#if __cplusplus < 201103L
vector(const vector& __x)
- : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
+ : _Base(__x) { }
- /// Construction from a normal-mode vector
- vector(const _Base& __x)
- : _Base(__x), _M_guaranteed_capacity(__x.size()) { }
+ ~vector() _GLIBCXX_NOEXCEPT { }
+#else
+ 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)
- : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { }
+ : _Base(__x, __a) { }
vector(vector&& __x, const allocator_type& __a)
- : _Base(std::move(__x), __a),
- _M_guaranteed_capacity(this->size())
- {
- if (__x.get_allocator() == __a)
- this->_M_swap(__x);
- else
- __x._M_invalidate_all();
- __x._M_guaranteed_capacity = 0;
- }
+ : _Safe(std::move(__x._M_safe()), __a),
+ _Base(std::move(__x._M_base()), __a),
+ _Safe_vector(std::move(__x)) { }
vector(initializer_list<value_type> __l,
const allocator_type& __a = allocator_type())
- : _Base(__l, __a),
- _M_guaranteed_capacity(__l.size()) { }
+ : _Base(__l, __a) { }
+
+ ~vector() = default;
#endif
- ~vector() _GLIBCXX_NOEXCEPT { }
+ /// Construction from a normal-mode vector
+ vector(const _Base& __x)
+ : _Base(__x) { }
+#if __cplusplus < 201103L
vector&
operator=(const vector& __x)
{
+ this->_M_safe() = __x;
_M_base() = __x;
- this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
return *this;
}
+#else
+ vector&
+ operator=(const vector&) = default;
-#if __cplusplus >= 201103L
vector&
- operator=(vector&& __x) 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();
- _M_update_guaranteed_capacity();
- __x._M_invalidate_all();
- __x._M_guaranteed_capacity = 0;
- return *this;
- }
+ operator=(vector&&) = default;
vector&
operator=(initializer_list<value_type> __l)
{
_M_base() = __l;
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
return *this;
}
#endif
@@ -199,7 +244,7 @@
_Base::assign(__gnu_debug::__base(__first),
__gnu_debug::__base(__last));
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
void
@@ -207,7 +252,7 @@
{
_Base::assign(__n, __u);
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#if __cplusplus >= 201103L
@@ -216,7 +261,7 @@
{
_Base::assign(__l);
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#endif
@@ -281,37 +326,37 @@
void
resize(size_type __sz)
{
- bool __realloc = _M_requires_reallocation(__sz);
+ bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size())
this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz);
if (__realloc)
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
void
resize(size_type __sz, const _Tp& __c)
{
- bool __realloc = _M_requires_reallocation(__sz);
+ bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size())
this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c);
if (__realloc)
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#else
void
resize(size_type __sz, _Tp __c = _Tp())
{
- bool __realloc = _M_requires_reallocation(__sz);
+ bool __realloc = this->_M_requires_reallocation(__sz);
if (__sz < this->size())
this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c);
if (__realloc)
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#endif
@@ -321,7 +366,7 @@
{
if (_Base::_M_shrink_to_fit())
{
- _M_guaranteed_capacity = _Base::capacity();
+ this->_M_guaranteed_capacity = _Base::capacity();
this->_M_invalidate_all();
}
}
@@ -331,7 +376,7 @@
capacity() const _GLIBCXX_NOEXCEPT
{
#ifdef _GLIBCXX_DEBUG_PEDANTIC
- return _M_guaranteed_capacity;
+ return this->_M_guaranteed_capacity;
#else
return _Base::capacity();
#endif
@@ -342,10 +387,10 @@
void
reserve(size_type __n)
{
- bool __realloc = _M_requires_reallocation(__n);
+ bool __realloc = this->_M_requires_reallocation(__n);
_Base::reserve(__n);
- if (__n > _M_guaranteed_capacity)
- _M_guaranteed_capacity = __n;
+ if (__n > this->_M_guaranteed_capacity)
+ this->_M_guaranteed_capacity = __n;
if (__realloc)
this->_M_invalidate_all();
}
@@ -403,11 +448,11 @@
void
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);
if (__realloc)
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#if __cplusplus >= 201103L
@@ -421,11 +466,11 @@
void
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)...);
if (__realloc)
this->_M_invalidate_all();
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#endif
@@ -443,7 +488,7 @@
emplace(const_iterator __position, _Args&&... __args)
{
__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();
_Base_iterator __res = _Base::emplace(__position.base(),
std::forward<_Args>(__args)...);
@@ -451,7 +496,7 @@
this->_M_invalidate_all();
else
this->_M_invalidate_after_nth(__offset);
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
return iterator(__res, this);
}
#endif
@@ -464,14 +509,14 @@
#endif
{
__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();
_Base_iterator __res = _Base::insert(__position.base(), __x);
if (__realloc)
this->_M_invalidate_all();
else
this->_M_invalidate_after_nth(__offset);
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
return iterator(__res, this);
}
@@ -492,14 +537,14 @@
insert(const_iterator __position, size_type __n, const _Tp& __x)
{
__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();
_Base_iterator __res = _Base::insert(__position.base(), __n, __x);
if (__realloc)
this->_M_invalidate_all();
else
this->_M_invalidate_after_nth(__offset);
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
return iterator(__res, this);
}
#else
@@ -507,14 +552,14 @@
insert(iterator __position, size_type __n, const _Tp& __x)
{
__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();
_Base::insert(__position.base(), __n, __x);
if (__realloc)
this->_M_invalidate_all();
else
this->_M_invalidate_after_nth(__offset);
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#endif
@@ -540,7 +585,7 @@
this->_M_invalidate_all();
else
this->_M_invalidate_after_nth(__offset);
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
return iterator(__res, this);
}
#else
@@ -563,7 +608,7 @@
this->_M_invalidate_all();
else
this->_M_invalidate_after_nth(__offset);
- _M_update_guaranteed_capacity();
+ this->_M_update_guaranteed_capacity();
}
#endif
@@ -611,16 +656,12 @@
void
swap(vector& __x)
#if __cplusplus >= 201103L
- noexcept(_Alloc_traits::_S_nothrow_swap())
+ noexcept( noexcept(declval<_Base>().swap(__x)) )
#endif
{
-#if __cplusplus >= 201103L
- if (!_Alloc_traits::_S_propagate_on_swap())
- __glibcxx_check_equal_allocs(__x);
-#endif
+ _Safe::_M_swap(__x);
_Base::swap(__x);
- this->_M_swap(__x);
- std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
+ std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
}
void
@@ -628,7 +669,7 @@
{
_Base::clear();
this->_M_invalidate_all();
- _M_guaranteed_capacity = 0;
+ this->_M_guaranteed_capacity = 0;
}
_Base&
@@ -638,20 +679,7 @@
_M_base() const _GLIBCXX_NOEXCEPT { return *this; }
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
_M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
{
typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
===================================================================
@@ -23,8 +23,8 @@
// <http://www.gnu.org/licenses/>.
#include <debug/debug.h>
-#include <debug/safe_sequence.h>
-#include <debug/safe_unordered_container.h>
+#include <debug/safe_base.h>
+#include <debug/safe_unordered_base.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>
#include <algorithm>
@@ -235,7 +235,7 @@
void
_Safe_sequence_base::
- _M_swap(_Safe_sequence_base& __x)
+ _M_swap(_Safe_sequence_base& __x) noexcept
{
// We need to lock both sequences to swap
using namespace __gnu_cxx;
@@ -382,7 +382,7 @@
_Safe_unordered_container_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); }
void
@@ -455,7 +455,7 @@
void
_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
using namespace __gnu_cxx;
===================================================================
@@ -32,9 +32,11 @@
typedef std::forward_list<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { T() };
+ auto it = v1.begin();
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -46,11 +46,13 @@
typedef std::forward_list<T, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.push_front(T());
+ auto it = v1.begin();
test_type v2(alloc_type(2));
v2.push_front(T());
v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,34 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,34 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,34 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,44 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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 @@
typedef std::map<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
+
test_type v2(std::move(v1));
+
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -38,9 +38,11 @@
typedef std::map<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+
test_type v2(alloc_type(2));
v2 = { test_type::value_type{} };
v2 = std::move(v1);
+
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(2 == v2.get_allocator().get_personality());
}
@@ -52,11 +54,15 @@
typedef std::map<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
+
test_type v2(alloc_type(2));
v2 = { test_type::value_type{} };
v2 = std::move(v1);
+
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,45 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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 @@
typedef std::multimap<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
+
test_type v2(std::move(v1));
+
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -52,11 +52,13 @@
typedef std::multimap<T, U, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
test_type v2(alloc_type(2));
v2 = { test_type::value_type{} };
v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,45 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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 @@
typedef std::multiset<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
+
test_type v2(std::move(v1));
+
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -50,11 +50,13 @@
typedef std::multiset<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
test_type v2(alloc_type(2));
v2 = { test_type::value_type{} };
v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,45 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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 @@
typedef std::set<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
+
test_type v2(std::move(v1));
+
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -50,11 +50,13 @@
typedef std::set<T, Cmp, alloc_type> test_type;
test_type v1(alloc_type(1));
v1 = { test_type::value_type{} };
+ auto it = v1.begin();
test_type v2(alloc_type(2));
v2 = { test_type::value_type{} };
v2 = std::move(v1);
VERIFY(0 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,45 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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 @@
test_type v1(alloc_type(1));
v1.emplace(std::piecewise_construct,
std::make_tuple(T()), std::make_tuple(T()));
+ auto it = v1.begin();
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -66,6 +66,8 @@
v1.emplace(std::piecewise_construct,
std::make_tuple(1), std::make_tuple(1));
+ auto it = v1.begin();
+
test_type v2(alloc_type(2));
v2.emplace(std::piecewise_construct,
std::make_tuple(2), std::make_tuple(2));
@@ -79,6 +81,8 @@
VERIFY( counter_type::move_assign_count == 0 );
VERIFY( counter_type::destructor_count == 2 );
+
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,49 @@
+// 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 @@
test_type v1(alloc_type(1));
v1.emplace(std::piecewise_construct,
std::make_tuple(T()), std::make_tuple(T()));
+ auto it = v1.begin();
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -66,6 +66,8 @@
v1.emplace(std::piecewise_construct,
std::make_tuple(1), std::make_tuple(1));
+ auto it = v1.begin();
+
test_type v2(alloc_type(2));
v2.emplace(std::piecewise_construct,
std::make_tuple(2), std::make_tuple(2));
@@ -79,6 +81,8 @@
VERIFY( counter_type::move_assign_count == 0 );
VERIFY( counter_type::destructor_count == 2 );
+
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,49 @@
+// 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 @@
typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(T());
+ auto it = v1.begin();
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -63,6 +63,8 @@
test_type v1(alloc_type(1));
v1.emplace(0);
+ auto it = v1.begin();
+
test_type v2(alloc_type(2));
v2.emplace(0);
@@ -76,6 +78,8 @@
VERIFY( counter_type::move_count == 0 );
VERIFY( counter_type::copy_count == 0 );
VERIFY( counter_type::destructor_count == 1 );
+
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,47 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,49 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,49 @@
+// 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 @@
typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
test_type v1(alloc_type(1));
v1.insert(T());
+ auto it = v1.begin();
test_type v2(std::move(v1));
VERIFY(1 == v1.get_allocator().get_personality());
VERIFY(1 == v2.get_allocator().get_personality());
+ VERIFY( it == v2.begin() );
}
void test02()
===================================================================
@@ -63,6 +63,8 @@
test_type v1(alloc_type(1));
v1.emplace(0);
+ auto it = v1.begin();
+
test_type v2(alloc_type(2));
v2.emplace(0);
@@ -76,6 +78,8 @@
VERIFY( counter_type::move_count == 0 );
VERIFY( counter_type::copy_count == 0 );
VERIFY( counter_type::destructor_count == 1 );
+
+ VERIFY( it == v2.begin() );
}
int main()
===================================================================
@@ -0,0 +1,45 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,49 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,49 @@
+// 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;
+}
===================================================================
@@ -0,0 +1,48 @@
+// 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 @@
val_type *first = &v.front() + 1;
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
@@ -206,10 +204,8 @@
typename vector_type::iterator first = v.begin() + 1;
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
@@ -233,10 +229,8 @@
typename list_type::iterator first = l.begin(); ++first;
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>