Index: include/Makefile.am =================================================================== --- include/Makefile.am (revision 209446) +++ include/Makefile.am (working copy) @@ -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 \ Index: include/debug/deque =================================================================== --- include/debug/deque (revision 209446) +++ include/debug/deque (working copy) @@ -31,6 +31,7 @@ #include #include +#include #include namespace std _GLIBCXX_VISIBILITY(default) @@ -40,21 +41,26 @@ /// Class std::deque with safety/checking/debug instrumentation. template > class deque - : public _GLIBCXX_STD_C::deque<_Tp, _Allocator>, - public __gnu_debug::_Safe_sequence > + : 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() _GLIBCXX_NOEXCEPT { } +#else + deque() = default; + deque(const deque&) = default; + deque(deque&&) = default; + + deque(initializer_list __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 __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 __l) { - *static_cast<_Base*>(this) = __l; + _M_base() = __l; this->_M_invalidate_all(); return *this; } @@ -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 Index: include/debug/forward_list =================================================================== --- include/debug/forward_list (revision 209446) +++ include/debug/forward_list (working copy) @@ -33,8 +33,113 @@ #include #include +#include #include +namespace __gnu_debug +{ + /// Special iterators swap and invalidation for forward_list because of the + /// before_begin iterator. + template + 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); + + 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 + 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 are casted to const_iterator, not a problem. + const_iterator* __victim = static_cast(__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; + } + } + + /* Special forward_list _M_swap version that do not swap the + * before-begin ownership.*/ + template + void + _Safe_forward_list<_SafeSequence>:: + _M_swap(_Safe_sequence_base& __other) noexcept + { + __gnu_cxx::__scoped_lock sentry(_M_this()._M_get_mutex()); + 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); + } +} + namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug @@ -42,119 +147,88 @@ /// Class std::forward_list with safety/checking/debug instrumentation. template > class forward_list - : public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>, - public __gnu_debug::_Safe_sequence > + : 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), __al), + _Base(std::move(__list), __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> 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 +421,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 +716,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 - 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(__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 - 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 bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) Index: include/debug/list =================================================================== --- include/debug/list (revision 209446) +++ include/debug/list (working copy) @@ -31,6 +31,7 @@ #include #include +#include #include namespace std _GLIBCXX_VISIBILITY(default) @@ -40,15 +41,20 @@ /// Class std::list with safety/checking/debug instrumentation. template > class list - : public _GLIBCXX_STD_C::list<_Tp, _Allocator>, - public __gnu_debug::_Safe_sequence > + : 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: +#if __cplusplus < 201103L list() _GLIBCXX_NOEXCEPT : _Base() { } + list(const list& __x) + : _Base(__x) { } + + ~list() _GLIBCXX_NOEXCEPT { } +#else + list() = default; + list(const list&) = default; + list(list&&) = default; + + list(initializer_list __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 __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 __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 Index: include/debug/macros.h =================================================================== --- include/debug/macros.h (revision 209446) +++ include/debug/macros.h (working copy) @@ -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) Index: include/debug/map.h =================================================================== --- include/debug/map.h (revision 209446) +++ include/debug/map.h (working copy) @@ -30,6 +30,7 @@ #define _GLIBCXX_DEBUG_MAP_H 1 #include +#include #include #include @@ -41,19 +42,20 @@ template, typename _Allocator = std::allocator > > class map - : public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>, - public __gnu_debug::_Safe_sequence > + : 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 _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 - 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() _GLIBCXX_NOEXCEPT { } +#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 __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), __a), + _Base(std::move(__m), __a) { } map(initializer_list __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 + 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 __l) @@ -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 +#include #include #include @@ -41,20 +42,20 @@ template, typename _Allocator = std::allocator > > class multimap - : public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>, - public __gnu_debug::_Safe_sequence > + : 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 _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 - 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() _GLIBCXX_NOEXCEPT { } +#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 __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), __a), + _Base(std::move(__m), __a) { } multimap(initializer_list __l, const allocator_type& __a) - : _Base(__l, __a) - { } + : _Base(__l, __a) { } template 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 + 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 __l) @@ -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 +#include #include #include @@ -41,19 +42,19 @@ template, typename _Allocator = std::allocator<_Key> > class multiset - : public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>, - public __gnu_debug::_Safe_sequence > + : 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 _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 - 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() _GLIBCXX_NOEXCEPT { } +#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 __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), __a), + _Base(std::move(__m), __a) { } multiset(initializer_list __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 + 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 __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 @@ -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 Index: include/debug/safe_base.h =================================================================== --- include/debug/safe_base.h (revision 209446) +++ include/debug/safe_base.h (working copy) @@ -188,22 +188,18 @@ 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 sequence is being destroyed. */ - ~_Safe_sequence_base() + ~_Safe_sequence_base() _GLIBCXX_NOEXCEPT { this->_M_detach_all(); } /** Detach all iterators, leaving them singular. */ @@ -231,7 +227,7 @@ * one container now reference the other container. */ void - _M_swap(_Safe_sequence_base& __x); + _M_swap(_Safe_sequence_base& __x) _GLIBCXX_NOEXCEPT; /** For use in _Safe_sequence. */ __gnu_cxx::__mutex& _M_get_mutex() throw (); Index: include/debug/safe_container.h =================================================================== --- include/debug/safe_container.h (revision 0) +++ include/debug/safe_container.h (working copy) @@ -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 +// . + +/** @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 + +namespace __gnu_debug +{ + /// Safe class dealing with some allocator dependent operations. + template class _SafeBase, + bool _IsCpp11AllocatorAware = 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 (_IsCpp11AllocatorAware) + { + 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 (_IsCpp11AllocatorAware) + { + 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 Index: include/debug/safe_sequence.h =================================================================== --- include/debug/safe_sequence.h (revision 209446) +++ include/debug/safe_sequence.h (working copy) @@ -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 + 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 Index: include/debug/safe_unordered_base.h =================================================================== --- include/debug/safe_unordered_base.h (revision 209446) +++ include/debug/safe_unordered_base.h (working copy) @@ -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 do 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. */ Index: include/debug/safe_unordered_container.h =================================================================== --- include/debug/safe_unordered_container.h (revision 209446) +++ include/debug/safe_unordered_container.h (working copy) @@ -54,10 +54,33 @@ * template _Safe_local_iterator for this container. Iterators will * then be tracked automatically. */ - template + template class _Safe_unordered_container : public _Safe_unordered_container_base { - public: + _SafeContainer& + _M_cont() noexcept + { return *static_cast<_SafeContainer*>(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 Index: include/debug/safe_unordered_container.tcc =================================================================== --- include/debug/safe_unordered_container.tcc (revision 209446) +++ include/debug/safe_unordered_container.tcc (working copy) @@ -31,14 +31,14 @@ namespace __gnu_debug { - template + template template void - _Safe_unordered_container<_Container>:: + _Safe_unordered_container<_SafeContainer>:: _M_invalidate_if(_Predicate __pred) { - typedef typename _Container::iterator iterator; - typedef typename _Container::const_iterator const_iterator; + typedef typename _SafeContainer::iterator iterator; + typedef typename _SafeContainer::const_iterator const_iterator; __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); for (_Safe_iterator_base* __iter = _M_iterators; __iter;) @@ -63,14 +63,14 @@ } - template + template template void - _Safe_unordered_container<_Container>:: + _Safe_unordered_container<_SafeContainer>:: _M_invalidate_local_if(_Predicate __pred) { - typedef typename _Container::local_iterator local_iterator; - typedef typename _Container::const_local_iterator const_local_iterator; + typedef typename _SafeContainer::local_iterator local_iterator; + typedef typename _SafeContainer::const_local_iterator const_local_iterator; __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); for (_Safe_iterator_base* __iter = _M_local_iterators; __iter;) Index: include/debug/set.h =================================================================== --- include/debug/set.h (revision 209446) +++ include/debug/set.h (working copy) @@ -30,6 +30,7 @@ #define _GLIBCXX_DEBUG_SET_H 1 #include +#include #include #include @@ -41,18 +42,19 @@ template, typename _Allocator = std::allocator<_Key> > class set - : public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>, - public __gnu_debug::_Safe_sequence > + : 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 _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 - 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() _GLIBCXX_NOEXCEPT { } +#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 __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), __a), + _Base(std::move(__x), __a) { } set(initializer_list __l, const allocator_type& __a) - : _Base(__l, __a) - { } + : _Base(__l, __a) { } template 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 + 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 __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 Index: include/debug/string =================================================================== --- include/debug/string (revision 209446) +++ include/debug/string (working copy) @@ -31,6 +31,7 @@ #include #include +#include #include namespace __gnu_debug @@ -39,12 +40,14 @@ template, 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 > { typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; - typedef __gnu_debug::_Safe_sequence _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 - iterator; - typedef __gnu_debug::_Safe_iterator 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 reverse_iterator; typedef std::reverse_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() _GLIBCXX_NOEXCEPT { } +#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: @@ -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 Index: include/debug/unordered_map =================================================================== --- include/debug/unordered_map (revision 209446) +++ include/debug/unordered_map (working copy) @@ -35,6 +35,7 @@ # include #include +#include #include #include @@ -48,21 +49,21 @@ typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator > > class unordered_map - : public _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>, - public __gnu_debug::_Safe_unordered_container > + : 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 _Safe_base; + typedef __gnu_debug::_Safe_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 _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, @@ -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), __a), + _Base(std::move(__umap), __a) { } unordered_map(initializer_list __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 __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 @@ -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 > > class unordered_multimap - : public _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, - _Pred, _Alloc>, - public __gnu_debug::_Safe_unordered_container > + : 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 - _Safe_base; + typedef __gnu_debug::_Safe_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 _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< @@ -564,18 +522,16 @@ 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), __a), + _Base(std::move(__umap), __a) { } unordered_multimap(initializer_list __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 __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 @@ -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(); } }; Index: include/debug/unordered_set =================================================================== --- include/debug/unordered_set (revision 209446) +++ include/debug/unordered_set (working copy) @@ -35,6 +35,7 @@ # include #include +#include #include #include @@ -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 > + : 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 _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 _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, @@ -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), __a), + _Base(std::move(__uset), __a) { } unordered_set(initializer_list __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 __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 @@ -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 __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 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 - _Safe_base; + typedef _GLIBCXX_STD_C::unordered_multiset< + _Value, _Hash, _Pred, _Alloc> _Base; + typedef __gnu_debug::_Safe_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 _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< @@ -558,18 +518,16 @@ 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), __a), + _Base(std::move(__uset), __a) { } unordered_multiset(initializer_list __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 __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 @@ -805,8 +743,8 @@ std::pair 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(); } }; Index: include/debug/vector =================================================================== --- include/debug/vector (revision 209446) +++ include/debug/vector (working copy) @@ -32,8 +32,68 @@ #include #include #include +#include #include +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 + class _Safe_vector + { + typedef typename _BaseSequence::size_type size_type; + + const _SafeSequence& + _M_seq() const { return *static_cast(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 > class vector - : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, - public __gnu_debug::_Safe_sequence > + : 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 _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 > _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), __a), + _Base(std::move(__x), __a), + _Safe_vector(std::move(__x)) { } vector(initializer_list __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 __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; Index: src/c++11/debug.cc =================================================================== --- src/c++11/debug.cc (revision 209446) +++ src/c++11/debug.cc (working copy) @@ -23,8 +23,8 @@ // . #include -#include -#include +#include +#include #include #include #include @@ -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; Index: testsuite/23_containers/forward_list/allocator/move.cc =================================================================== --- testsuite/23_containers/forward_list/allocator/move.cc (revision 209446) +++ testsuite/23_containers/forward_list/allocator/move.cc (working copy) @@ -32,9 +32,11 @@ typedef std::forward_list 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() Index: testsuite/23_containers/forward_list/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/forward_list/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/forward_list/allocator/move_assign.cc (working copy) @@ -46,11 +46,13 @@ typedef std::forward_list 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() Index: testsuite/23_containers/forward_list/debug/construct1_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/construct1_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/construct1_neg.cc (working copy) @@ -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 +// . +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_construct1 >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/forward_list/debug/construct2_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/construct2_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/construct2_neg.cc (working copy) @@ -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 +// . +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_construct2 >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/forward_list/debug/construct3_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/construct3_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/construct3_neg.cc (working copy) @@ -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 +// . +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_construct3 >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/forward_list/debug/construct4_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/construct4_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/construct4_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::forward_list 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; +} Index: testsuite/23_containers/forward_list/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::forward_list 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; +} Index: testsuite/23_containers/forward_list/debug/move_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator alloc_type; + typedef __gnu_debug::forward_list 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; +} Index: testsuite/23_containers/map/allocator/move.cc =================================================================== --- testsuite/23_containers/map/allocator/move.cc (revision 209446) +++ testsuite/23_containers/map/allocator/move.cc (working copy) @@ -38,9 +38,13 @@ typedef std::map 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() Index: testsuite/23_containers/map/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/map/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/map/allocator/move_assign.cc (working copy) @@ -38,9 +38,11 @@ typedef std::map 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 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() Index: testsuite/23_containers/map/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/map/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/map/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_debug::map, 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; +} Index: testsuite/23_containers/map/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/map/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/map/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_debug::map, 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; +} Index: testsuite/23_containers/map/debug/move_neg.cc =================================================================== --- testsuite/23_containers/map/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/map/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator > alloc_type; + typedef __gnu_debug::map, 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; +} Index: testsuite/23_containers/multimap/allocator/move.cc =================================================================== --- testsuite/23_containers/multimap/allocator/move.cc (revision 209446) +++ testsuite/23_containers/multimap/allocator/move.cc (working copy) @@ -38,9 +38,13 @@ typedef std::multimap 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() Index: testsuite/23_containers/multimap/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/multimap/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/multimap/allocator/move_assign.cc (working copy) @@ -52,11 +52,13 @@ typedef std::multimap 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() Index: testsuite/23_containers/multimap/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/multimap/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/multimap/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_debug::multimap, 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; +} Index: testsuite/23_containers/multimap/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/multimap/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/multimap/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_debug::multimap, 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; +} Index: testsuite/23_containers/multimap/debug/move_neg.cc =================================================================== --- testsuite/23_containers/multimap/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/multimap/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator > alloc_type; + typedef __gnu_debug::multimap, 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; +} Index: testsuite/23_containers/multiset/allocator/move.cc =================================================================== --- testsuite/23_containers/multiset/allocator/move.cc (revision 209446) +++ testsuite/23_containers/multiset/allocator/move.cc (working copy) @@ -36,9 +36,13 @@ typedef std::multiset 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() Index: testsuite/23_containers/multiset/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/multiset/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/multiset/allocator/move_assign.cc (working copy) @@ -50,11 +50,13 @@ typedef std::multiset 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() Index: testsuite/23_containers/multiset/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/multiset/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/multiset/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::multiset, 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; +} Index: testsuite/23_containers/multiset/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/multiset/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/multiset/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::multiset, 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; +} Index: testsuite/23_containers/multiset/debug/move_neg.cc =================================================================== --- testsuite/23_containers/multiset/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/multiset/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator alloc_type; + typedef __gnu_debug::multiset, 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; +} Index: testsuite/23_containers/set/allocator/move.cc =================================================================== --- testsuite/23_containers/set/allocator/move.cc (revision 209446) +++ testsuite/23_containers/set/allocator/move.cc (working copy) @@ -38,9 +38,13 @@ typedef std::set 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() Index: testsuite/23_containers/set/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/set/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/set/allocator/move_assign.cc (working copy) @@ -50,11 +50,13 @@ typedef std::set 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() Index: testsuite/23_containers/set/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/set/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/set/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::set, 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; +} Index: testsuite/23_containers/set/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/set/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/set/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::set, 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; +} Index: testsuite/23_containers/set/debug/move_neg.cc =================================================================== --- testsuite/23_containers/set/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/set/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator alloc_type; + typedef __gnu_debug::set, 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; +} Index: testsuite/23_containers/unordered_map/allocator/move.cc =================================================================== --- testsuite/23_containers/unordered_map/allocator/move.cc (revision 209446) +++ testsuite/23_containers/unordered_map/allocator/move.cc (working copy) @@ -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() Index: testsuite/23_containers/unordered_map/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/unordered_map/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/unordered_map/allocator/move_assign.cc (working copy) @@ -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() Index: testsuite/23_containers/unordered_map/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/unordered_map/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/unordered_map/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator> alloc_type; + typedef __gnu_debug::unordered_map, + std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_map/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/unordered_map/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/unordered_map/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_debug::unordered_map, std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_map/debug/move_neg.cc =================================================================== --- testsuite/23_containers/unordered_map/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/unordered_map/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator > alloc_type; + typedef __gnu_debug::unordered_map< + int, int, std::hash, std::equal_to, 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; +} Index: testsuite/23_containers/unordered_multimap/allocator/move.cc =================================================================== --- testsuite/23_containers/unordered_multimap/allocator/move.cc (revision 209446) +++ testsuite/23_containers/unordered_multimap/allocator/move.cc (working copy) @@ -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() Index: testsuite/23_containers/unordered_multimap/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/unordered_multimap/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/unordered_multimap/allocator/move_assign.cc (working copy) @@ -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() Index: testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator> alloc_type; + typedef __gnu_debug::unordered_multimap, std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator> alloc_type; + typedef __gnu_debug::unordered_multimap, + std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_multimap/debug/move_neg.cc =================================================================== --- testsuite/23_containers/unordered_multimap/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/unordered_multimap/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator > alloc_type; + typedef __gnu_debug::unordered_multimap< + int, int, std::hash, std::equal_to, 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; +} Index: testsuite/23_containers/unordered_multiset/allocator/move.cc =================================================================== --- testsuite/23_containers/unordered_multiset/allocator/move.cc (revision 209446) +++ testsuite/23_containers/unordered_multiset/allocator/move.cc (working copy) @@ -44,9 +44,11 @@ typedef std::unordered_multiset 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() Index: testsuite/23_containers/unordered_multiset/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/unordered_multiset/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/unordered_multiset/allocator/move_assign.cc (working copy) @@ -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() Index: testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::unordered_multiset, + std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::unordered_multiset, + std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_multiset/debug/move_neg.cc =================================================================== --- testsuite/23_containers/unordered_multiset/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/unordered_multiset/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator alloc_type; + typedef __gnu_debug::unordered_multiset< + int, std::hash, std::equal_to, 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; +} Index: testsuite/23_containers/unordered_set/allocator/move.cc =================================================================== --- testsuite/23_containers/unordered_set/allocator/move.cc (revision 209446) +++ testsuite/23_containers/unordered_set/allocator/move.cc (working copy) @@ -44,9 +44,11 @@ typedef std::unordered_set 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() Index: testsuite/23_containers/unordered_set/allocator/move_assign.cc =================================================================== --- testsuite/23_containers/unordered_set/allocator/move_assign.cc (revision 209446) +++ testsuite/23_containers/unordered_set/allocator/move_assign.cc (working copy) @@ -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() Index: testsuite/23_containers/unordered_set/debug/construct5_neg.cc =================================================================== --- testsuite/23_containers/unordered_set/debug/construct5_neg.cc (revision 0) +++ testsuite/23_containers/unordered_set/debug/construct5_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::unordered_set, + std::equal_to, 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; +} Index: testsuite/23_containers/unordered_set/debug/move_assign_neg.cc =================================================================== --- testsuite/23_containers/unordered_set/debug/move_assign_neg.cc (revision 0) +++ testsuite/23_containers/unordered_set/debug/move_assign_neg.cc (working copy) @@ -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 +// . +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_debug::unordered_set, + std::equal_to, + 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; +} Index: testsuite/23_containers/unordered_set/debug/move_neg.cc =================================================================== --- testsuite/23_containers/unordered_set/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/unordered_set/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator alloc_type; + typedef __gnu_debug::unordered_set< + int, std::hash, std::equal_to, 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; +} Index: testsuite/23_containers/vector/debug/move_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/move_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/move_neg.cc (working copy) @@ -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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#include + +#include +#include + +using __gnu_test::uneq_allocator; + +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef uneq_allocator alloc_type; + typedef __gnu_debug::vector 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; +} Index: testsuite/util/debug/checks.h =================================================================== --- testsuite/util/debug/checks.h (revision 209446) +++ testsuite/util/debug/checks.h (working copy) @@ -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