diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7ef5ab59de6..f46bdc47481 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,125 @@ +2014-05-06 François Dumont + + * include/debug/macros.h [__glibcxx_check_equal_allocs]: Add + parameter to pass the 2 instances to check allocator equality. + * include/debug/safe_container.h: New, define _Safe_container<>. + * include/Makefile.am: Add previous. + * include/debug/deque (std::__debug::deque<>): Inherit + _Safe_container<>. Use default implementation for all special + functions. + * include/debug/forward_list (std::__debug::forward_list<>): + Likewise. + * include/debug/list (std::__debug::list<>): Likewise. + * include/debug/map.h (std::__debug::map<>): Likewise. + * include/debug/multimap.h (std::__debug::multimap<>): Likewise. + * include/debug/set.h (std::__debug::set<>): Likewise. + * include/debug/multiset.h (std::__debug::multiset<>): Likewise. + * include/debug/string (std::__debug::basic_string<>): Likewise. + * include/debug/unordered_map + (std::__debug::unordered_map<>): Likewise. + (std::__debug::unordered_multimap<>): Likewise. + * include/debug/unordered_set + (std::__debug::unordered_set<>): Likewise. + (std::__debug::unordered_multiset<>): Likewise. + * include/debug/vector (std::__debug::vector<>): Likewise. + * include/debug/safe_base.h (_Safe_sequence_base()): Add + noexcept. + (_Safe_sequence_base(_Safe_sequence_base&&): Remove. + (~_Safe_sequence_base()): Add noexcept. + * include/debug/safe_sequence.h + (std::__debug::_Safe_node_sequence<>): New. + * include/debug/safe_unordered_base.h + (_Safe_unordered_container_base()): Add noexcept. + (~_Safe_unordered_container_base()): Likewise. + (_M_swap(_Safe_unordered_container_base&)): Likewise. + * include/debug/safe_unordered_container.h: + (_Safe_unordered_container<>::_M_invalidate_locals()): New. + (_Safe_unordered_container<>::_M_invalidate_all()): New. + * src/c++11/debug.cc: Limit includes, adapt methods noexcept + qualifications. + * testsuite/util/debug/checks.h (check_construct1): Just implement + an invalid constructor invocation and no other operations + potentially not supported by some types of container. + (check_construct2): Likewise. + (check_construct3): Likewise. + * testsuite/23_containers/forward_list/allocator/move.cc: Add + check on iterators to make sure they are correctly moved in debug + mode. + * testsuite/23_containers/forward_list/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/map/allocator/move.cc: Likewise. + * testsuite/23_containers/map/allocator/move_assign.cc: Likewise. + * testsuite/23_containers/multimap/allocator/move.cc: Likewise. + * testsuite/23_containers/multimap/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/multiset/allocator/move.cc: Likewise. + * testsuite/23_containers/multiset/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/set/allocator/move.cc: Likewise. + * testsuite/23_containers/set/allocator/move_assign.cc: Likewise. + * testsuite/23_containers/unordered_map/allocator/move.cc: + Likewise. + * testsuite/23_containers/unordered_map/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/unordered_multimap/allocator/move.cc: + Likewise. + * testsuite/23_containers/unordered_multimap/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/unordered_multiset/allocator/move.cc: + Likewise. + * testsuite/23_containers/unordered_multiset/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/unordered_set/allocator/move.cc: + Likewise. + * testsuite/23_containers/unordered_set/allocator/move_assign.cc: + Likewise. + * testsuite/23_containers/forward_list/debug/construct1_neg.cc: + New. + * testsuite/23_containers/forward_list/debug/construct2_neg.cc: + New. + * testsuite/23_containers/forward_list/debug/construct3_neg.cc: + New. + * testsuite/23_containers/forward_list/debug/construct4_neg.cc: + New. + * testsuite/23_containers/forward_list/debug/move_assign_neg.cc: + New. + * testsuite/23_containers/forward_list/debug/move_neg.cc: New. + * testsuite/23_containers/map/debug/construct5_neg.cc: New. + * testsuite/23_containers/map/debug/move_assign_neg.cc: New. + * testsuite/23_containers/map/debug/move_neg.cc: New. + * testsuite/23_containers/multimap/debug/construct5_neg.cc: New. + * testsuite/23_containers/multimap/debug/move_assign_neg.cc: New. + * testsuite/23_containers/multimap/debug/move_neg.cc: New. + * testsuite/23_containers/multiset/debug/construct5_neg.cc: New. + * testsuite/23_containers/multiset/debug/move_assign_neg.cc: New. + * testsuite/23_containers/multiset/debug/move_neg.cc: New. + * testsuite/23_containers/set/debug/construct5_neg.cc: New. + * testsuite/23_containers/set/debug/move_assign_neg.cc: New. + * testsuite/23_containers/set/debug/move_neg.cc: New. + * testsuite/23_containers/unordered_map/debug/construct5_neg.cc: + New. + * testsuite/23_containers/unordered_map/debug/move_assign_neg.cc: + New. + * testsuite/23_containers/unordered_map/debug/move_neg.cc: New. + * testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc: + New. + * testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc: + New. + * testsuite/23_containers/unordered_multimap/debug/move_neg.cc: + New. + * testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc: + New. + * testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc: + New. + * testsuite/23_containers/unordered_multiset/debug/move_neg.cc: + New. + * testsuite/23_containers/unordered_set/debug/construct5_neg.cc: + New. + * testsuite/23_containers/unordered_set/debug/move_assign_neg.cc: + New. + * testsuite/23_containers/unordered_set/debug/move_neg.cc: New. + * testsuite/23_containers/vector/debug/move_neg.cc: New. + 2014-05-05 Andreas Schwab * config/abi/post/ia64-linux-gnu/baseline_symbols.txt diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 85b0f31a0d6..0d676dbdf39 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -733,6 +733,7 @@ debug_headers = \ ${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 \ diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 225d06c92d1..75be7489b1a 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -31,6 +31,7 @@ #include #include +#include #include namespace std _GLIBCXX_VISIBILITY(default) @@ -40,36 +41,59 @@ namespace __debug /// 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 _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 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 typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; - typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque> - iterator; - typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,deque> - const_iterator; + typedef __gnu_debug::_Safe_iterator<_Base_iterator, deque> + iterator; + typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, deque> + const_iterator; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; - typedef _Tp value_type; - typedef _Allocator allocator_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 23.2.1.1 construct/copy/destroy: - deque() : _Base() { } +#if __cplusplus < 201103L + deque() + : _Base() { } + + deque(const deque& __x) + : _Base(__x) { } + + ~deque() { } +#else + deque() = default; + deque(const deque&) = default; + deque(deque&&) = default; + + deque(initializer_list __l, + const allocator_type& __a = allocator_type()) + : _Base(__l, __a) { } + + ~deque() = default; +#endif explicit deque(const _Allocator& __a) @@ -96,55 +120,35 @@ namespace __debug #else template #endif - deque(_InputIterator __first, _InputIterator __last, + deque(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), __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; } - -#if __cplusplus >= 201103L +#else deque& - operator=(deque&& __x) noexcept - { - // NB: DR 1204. - // NB: DR 675. - __glibcxx_check_self_move_assign(__x); - clear(); - swap(__x); - return *this; - } + operator=(const deque&) = default; + + deque& + operator=(deque&&) = default; deque& operator=(initializer_list __l) { - *static_cast<_Base*>(this) = __l; + _M_base() = __l; this->_M_invalidate_all(); return *this; } @@ -156,9 +160,9 @@ namespace __debug #else template #endif - void - assign(_InputIterator __first, _InputIterator __last) - { + void + assign(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _Base::assign(__gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -241,7 +245,7 @@ namespace __debug typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; this->_M_invalidate_if(_After_nth(__n, _Base::begin())); } - + public: // 23.2.1.2 capacity: using _Base::size; @@ -369,24 +373,24 @@ namespace __debug { emplace_back(std::move(__x)); } template - void - emplace_front(_Args&&... __args) + void + emplace_front(_Args&&... __args) { _Base::emplace_front(std::forward<_Args>(__args)...); this->_M_invalidate_all(); } template - void - emplace_back(_Args&&... __args) + void + emplace_back(_Args&&... __args) { _Base::emplace_back(std::forward<_Args>(__args)...); this->_M_invalidate_all(); } template - iterator - emplace(const_iterator __position, _Args&&... __args) + iterator + emplace(const_iterator __position, _Args&&... __args) { __glibcxx_check_insert(__position); _Base_iterator __res = _Base::emplace(__position.base(), @@ -447,9 +451,9 @@ namespace __debug template> iterator - insert(const_iterator __position, + insert(const_iterator __position, _InputIterator __first, _InputIterator __last) - { + { __glibcxx_check_insert_range(__position, __first, __last); _Base_iterator __res = _Base::insert(__position.base(), __gnu_debug::__base(__first), @@ -459,10 +463,10 @@ namespace __debug } #else template - void - insert(iterator __position, + void + insert(iterator __position, _InputIterator __first, _InputIterator __last) - { + { __glibcxx_check_insert_range(__position, __first, __last); _Base::insert(__position.base(), __gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -529,7 +533,7 @@ namespace __debug #else return __first; #endif - else if (__first.base() == _Base::begin() + else if (__first.base() == _Base::begin() || __last.base() == _Base::end()) { this->_M_detach_singular(); @@ -559,10 +563,13 @@ namespace __debug } 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 @@ -573,10 +580,10 @@ namespace __debug } _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& - _M_base() const _GLIBCXX_NOEXCEPT { return *this; } + _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index 12f6d7fbe1d..c67fb464860 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -33,8 +33,139 @@ #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); + + void _M_swap_single(_Safe_sequence_base&) noexcept; + + protected: + void + _M_invalidate_all() + { + using _Base_const_iterator = __decltype(_M_this()._M_base().cend()); + this->_M_invalidate_if([this](_Base_const_iterator __it) + { + return __it != _M_this()._M_base().cbefore_begin() + && __it != _M_this()._M_base().cend(); }); + } + + void _M_swap(_Safe_sequence_base&) noexcept; + }; + + template + void + _Safe_forward_list<_SafeSequence>:: + _M_swap_aux(_Safe_sequence_base& __lhs, + _Safe_iterator_base*& __lhs_iterators, + _Safe_sequence_base& __rhs, + _Safe_iterator_base*& __rhs_iterators) + { + using const_iterator = typename _SafeSequence::const_iterator; + _Safe_iterator_base* __bbegin_its = 0; + _Safe_iterator_base* __last_bbegin = 0; + _SafeSequence& __rseq = static_cast<_SafeSequence&>(__rhs); + + for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;) + { + // Even iterator is cast to const_iterator, not a problem. + const_iterator* __victim = static_cast(__iter); + __iter = __iter->_M_next; + if (__victim->base() == __rseq._M_base().cbefore_begin()) + { + __victim->_M_unlink(); + if (__lhs_iterators == __victim) + __lhs_iterators = __victim->_M_next; + if (__bbegin_its) + { + __victim->_M_next = __bbegin_its; + __bbegin_its->_M_prior = __victim; + } + else + __last_bbegin = __victim; + __bbegin_its = __victim; + } + else + __victim->_M_sequence = &__lhs; + } + + if (__bbegin_its) + { + if (__rhs_iterators) + { + __rhs_iterators->_M_prior = __last_bbegin; + __last_bbegin->_M_next = __rhs_iterators; + } + __rhs_iterators = __bbegin_its; + } + } + + template + void + _Safe_forward_list<_SafeSequence>:: + _M_swap_single(_Safe_sequence_base& __other) noexcept + { + std::swap(_M_this()._M_iterators, __other._M_iterators); + std::swap(_M_this()._M_const_iterators, __other._M_const_iterators); + // Useless, always 1 on forward_list + //std::swap(_M_this()_M_version, __other._M_version); + _Safe_iterator_base* __this_its = _M_this()._M_iterators; + _M_swap_aux(__other, __other._M_iterators, + _M_this(), _M_this()._M_iterators); + _Safe_iterator_base* __this_const_its = _M_this()._M_const_iterators; + _M_swap_aux(__other, __other._M_const_iterators, + _M_this(), _M_this()._M_const_iterators); + _M_swap_aux(_M_this(), __this_its, + __other, __other._M_iterators); + _M_swap_aux(_M_this(), __this_const_its, + __other, __other._M_const_iterators); + } + + /* Special forward_list _M_swap version that does not swap the + * before-begin ownership.*/ + template + void + _Safe_forward_list<_SafeSequence>:: + _M_swap(_Safe_sequence_base& __other) noexcept + { + // We need to lock both sequences to swap + using namespace __gnu_cxx; + __mutex *__this_mutex = &_M_this()._M_get_mutex(); + __mutex *__other_mutex = + &static_cast<_SafeSequence&>(__other)._M_get_mutex(); + if (__this_mutex == __other_mutex) + { + __scoped_lock __lock(*__this_mutex); + _M_swap_single(__other); + } + else + { + __scoped_lock __l1(__this_mutex < __other_mutex + ? *__this_mutex : *__other_mutex); + __scoped_lock __l2(__this_mutex < __other_mutex + ? *__other_mutex : *__this_mutex); + _M_swap_single(__other); + } + } +} + namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug @@ -42,133 +173,102 @@ namespace __debug /// 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 _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; + typedef typename _Base::iterator _Base_iterator; + typedef typename _Base::const_iterator _Base_const_iterator; public: - typedef typename _Base::reference reference; - typedef typename _Base::const_reference const_reference; + 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 typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; - typedef _Tp value_type; - typedef _Alloc allocator_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; + typedef _Tp value_type; + typedef typename _Base::allocator_type allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; // 23.2.3.1 construct/copy/destroy: explicit - forward_list(const _Alloc& __al = _Alloc()) + forward_list(const allocator_type& __al = allocator_type()) : _Base(__al) { } - forward_list(const forward_list& __list, const _Alloc& __al) + forward_list(const forward_list& __list, const allocator_type& __al) : _Base(__list, __al) { } - forward_list(forward_list&& __list, const _Alloc& __al) - : _Base(std::move(__list._M_base()), __al) - { - if (__list.get_allocator() == __al) - this->_M_swap(__list); - else - __list._M_invalidate_all(); - } + forward_list(forward_list&& __list, const allocator_type& __al) + : _Safe(std::move(__list._M_safe()), __al), + _Base(std::move(__list._M_base()), __al) + { } explicit - forward_list(size_type __n, const _Alloc& __al = _Alloc()) + forward_list(size_type __n, const allocator_type& __al = allocator_type()) : _Base(__n, __al) { } forward_list(size_type __n, const _Tp& __value, - const _Alloc& __al = _Alloc()) + const allocator_type& __al = allocator_type()) : _Base(__n, __value, __al) { } template> forward_list(_InputIterator __first, _InputIterator __last, - const _Alloc& __al = _Alloc()) - : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, + 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; + return *this; } template> void - assign(_InputIterator __first, _InputIterator __last) - { + assign(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _Base::assign(__gnu_debug::__base(__first), __gnu_debug::__base(__last)); this->_M_invalidate_all(); - } + } void assign(size_type __n, const _Tp& __val) @@ -292,16 +392,16 @@ namespace __debug template> - iterator - insert_after(const_iterator __pos, - _InputIterator __first, _InputIterator __last) - { + iterator + insert_after(const_iterator __pos, + _InputIterator __first, _InputIterator __last) + { __glibcxx_check_insert_range_after(__pos, __first, __last); return iterator(_Base::insert_after(__pos.base(), __gnu_debug::__base(__first), __gnu_debug::__base(__last)), this); - } + } iterator insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) @@ -347,12 +447,10 @@ namespace __debug 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 @@ -380,7 +478,7 @@ namespace __debug { this->_M_revalidate_singular(); __throw_exception_again; - } + } } void @@ -408,7 +506,7 @@ namespace __debug { this->_M_revalidate_singular(); __throw_exception_again; - } + } } void @@ -422,7 +520,7 @@ namespace __debug void splice_after(const_iterator __pos, forward_list&& __list) { - __glibcxx_check_insert_after(__pos); + __glibcxx_check_insert_after(__pos); _GLIBCXX_DEBUG_VERIFY(&__list != this, _M_message(__gnu_debug::__msg_self_splice) ._M_sequence(*this, "this")); @@ -477,7 +575,7 @@ namespace __debug splice_after(const_iterator __pos, forward_list&& __list, const_iterator __before, const_iterator __last) { - __glibcxx_check_insert_after(__pos); + __glibcxx_check_insert_after(__pos); __glibcxx_check_valid_range(__before, __last); _GLIBCXX_DEBUG_VERIFY(__before._M_attached_to(&__list), _M_message(__gnu_debug::__msg_splice_other) @@ -508,8 +606,8 @@ namespace __debug ._M_iterator(__before, "before") ._M_iterator(__last, "last")); _GLIBCXX_DEBUG_VERIFY(&__list != this || __tmp != __pos.base(), - _M_message(__gnu_debug::__msg_splice_overlap) - ._M_iterator(__tmp, "position") + _M_message(__gnu_debug::__msg_splice_overlap) + ._M_iterator(__tmp, "position") ._M_iterator(__before, "before") ._M_iterator(__last, "last")); // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -542,8 +640,8 @@ namespace __debug } template - void - remove_if(_Pred __pred) + void + remove_if(_Pred __pred) { _Base_iterator __x = _Base::before_begin(); _Base_iterator __old = __x++; @@ -574,8 +672,8 @@ namespace __debug } template - void - unique(_BinPred __binary_pred) + void + unique(_BinPred __binary_pred) { _Base_iterator __first = _Base::begin(); _Base_iterator __last = _Base::end(); @@ -613,8 +711,8 @@ namespace __debug { merge(std::move(__list)); } template - void - merge(forward_list&& __list, _Comp __comp) + void + merge(forward_list&& __list, _Comp __comp) { if (this != &__list) { @@ -624,7 +722,7 @@ namespace __debug this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it) { - return __it != __list._M_base().cbefore_begin() + return __it != __list._M_base().cbefore_begin() && __it != __list._M_base().cend(); }); _Base::merge(std::move(__list._M_base()), __comp); @@ -632,141 +730,57 @@ namespace __debug } template - void - merge(forward_list& __list, _Comp __comp) - { merge(std::move(__list), __comp); } + void + merge(forward_list& __list, _Comp __comp) + { merge(std::move(__list), __comp); } using _Base::sort; using _Base::reverse; _Base& - _M_base() noexcept { return *this; } + _M_base() noexcept { return *this; } 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) + const forward_list<_Tp, _Alloc>& __ly) { return __lx._M_base() == __ly._M_base(); } template inline bool operator<(const forward_list<_Tp, _Alloc>& __lx, - const forward_list<_Tp, _Alloc>& __ly) + const forward_list<_Tp, _Alloc>& __ly) { return __lx._M_base() < __ly._M_base(); } template inline bool operator!=(const forward_list<_Tp, _Alloc>& __lx, - const forward_list<_Tp, _Alloc>& __ly) + const forward_list<_Tp, _Alloc>& __ly) { return !(__lx == __ly); } /// Based on operator< template inline bool operator>(const forward_list<_Tp, _Alloc>& __lx, - const forward_list<_Tp, _Alloc>& __ly) + const forward_list<_Tp, _Alloc>& __ly) { return (__ly < __lx); } /// Based on operator< template inline bool operator>=(const forward_list<_Tp, _Alloc>& __lx, - const forward_list<_Tp, _Alloc>& __ly) + const forward_list<_Tp, _Alloc>& __ly) { return !(__lx < __ly); } /// Based on operator< template inline bool operator<=(const forward_list<_Tp, _Alloc>& __lx, - const forward_list<_Tp, _Alloc>& __ly) + const forward_list<_Tp, _Alloc>& __ly) { return !(__ly < __lx); } /// See std::forward_list::swap(). diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index 9918bc5d808..2454ecc5458 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -31,6 +31,7 @@ #include #include +#include #include namespace std _GLIBCXX_VISIBILITY(default) @@ -40,39 +41,61 @@ namespace __debug /// 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 _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; - 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; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator<_Base_iterator, list> - iterator; + iterator; typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list> - const_iterator; + const_iterator; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; - typedef _Tp value_type; - typedef _Allocator allocator_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 23.2.2.1 construct/copy/destroy: - list() _GLIBCXX_NOEXCEPT +#if __cplusplus < 201103L + list() : _Base() { } + list(const list& __x) + : _Base(__x) { } + + ~list() { } +#else + list() = default; + list(const list&) = default; + list(list&&) = default; + + list(initializer_list __l, + const allocator_type& __a = allocator_type()) + : _Base(__l, __a) { } + + ~list() = default; +#endif + explicit list(const _Allocator& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } @@ -103,51 +126,31 @@ namespace __debug : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), __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; } - -#if __cplusplus >= 201103L +#else list& - operator=(list&& __x) - { - // NB: DR 1204. - // NB: DR 675. - __glibcxx_check_self_move_assign(__x); - clear(); - swap(__x); - return *this; - } + operator=(const list&) = default; + + list& + operator=(list&&) = default; list& operator=(initializer_list __l) { - static_cast<_Base&>(*this) = __l; this->_M_invalidate_all(); + _M_base() = __l; return *this; } @@ -165,9 +168,9 @@ namespace __debug #else template #endif - void - assign(_InputIterator __first, _InputIterator __last) - { + void + assign(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _Base::assign(__gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -245,16 +248,14 @@ namespace __debug { 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)); - } + this->_M_invalidate_if(_Equal(__victim)); __try { @@ -272,16 +273,14 @@ namespace __debug { 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)); - } + this->_M_invalidate_if(_Equal(__victim)); __try { @@ -299,16 +298,14 @@ namespace __debug { 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)); - } + this->_M_invalidate_if(_Equal(__victim)); __try { @@ -382,8 +379,8 @@ namespace __debug #if __cplusplus >= 201103L template - iterator - emplace(const_iterator __position, _Args&&... __args) + iterator + emplace(const_iterator __position, _Args&&... __args) { __glibcxx_check_insert(__position); return iterator(_Base::emplace(__position.base(), @@ -435,9 +432,9 @@ namespace __debug template> iterator - insert(const_iterator __position, _InputIterator __first, + insert(const_iterator __position, _InputIterator __first, _InputIterator __last) - { + { __glibcxx_check_insert_range(__position, __first, __last); return iterator(_Base::insert(__position.base(), __gnu_debug::__base(__first), @@ -447,9 +444,9 @@ namespace __debug #else template void - insert(iterator __position, _InputIterator __first, + insert(iterator __position, _InputIterator __first, _InputIterator __last) - { + { __glibcxx_check_insert_range(__position, __first, __last); _Base::insert(__position.base(), __gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -494,7 +491,7 @@ namespace __debug __victim != __last.base(); ++__victim) { _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(), - _M_message(__gnu_debug::__msg_valid_range) + _M_message(__gnu_debug::__msg_valid_range) ._M_iterator(__first, "position") ._M_iterator(__last, "last")); this->_M_invalidate_if(_Equal(__victim)); @@ -504,9 +501,12 @@ namespace __debug 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 @@ -629,9 +629,9 @@ namespace __debug } template - void - remove_if(_Predicate __pred) - { + void + remove_if(_Predicate __pred) + { for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); ) { if (__pred(*__x)) @@ -659,9 +659,9 @@ namespace __debug } template - void - unique(_BinaryPredicate __binary_pred) - { + void + unique(_BinaryPredicate __binary_pred) + { _Base_iterator __first = _Base::begin(); _Base_iterator __last = _Base::end(); if (__first == __last) @@ -701,13 +701,13 @@ namespace __debug #endif template - void + void #if __cplusplus >= 201103L - merge(list&& __x, _Compare __comp) + merge(list&& __x, _Compare __comp) #else - merge(list& __x, _Compare __comp) + merge(list& __x, _Compare __comp) #endif - { + { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 300. list::merge() specification incomplete if (this != &__x) @@ -723,32 +723,25 @@ namespace __debug #if __cplusplus >= 201103L template - void - merge(list& __x, _Compare __comp) - { merge(std::move(__x), __comp); } + void + merge(list& __x, _Compare __comp) + { merge(std::move(__x), __comp); } #endif void sort() { _Base::sort(); } template - void - sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } + void + sort(_StrictWeakOrdering __pred) { _Base::sort(__pred); } using _Base::reverse; _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& - _M_base() const _GLIBCXX_NOEXCEPT { return *this; } - - private: - void - _M_invalidate_all() - { - this->_M_invalidate_if(_Not_equal(_Base::end())); - } + _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h index 7ce374c7589..8e07aec2fe1 100644 --- a/libstdc++-v3/include/debug/macros.h +++ b/libstdc++-v3/include/debug/macros.h @@ -347,10 +347,10 @@ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \ _M_message(__gnu_debug::__msg_valid_load_factor) \ ._M_sequence(*this, "this")) -#define __glibcxx_check_equal_allocs(_Other) \ -_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \ +#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) diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h index fda6ac1eee5..8baeb6fc2e5 100644 --- a/libstdc++-v3/include/debug/map.h +++ b/libstdc++-v3/include/debug/map.h @@ -30,6 +30,7 @@ #define _GLIBCXX_DEBUG_MAP_H 1 #include +#include #include #include @@ -41,69 +42,55 @@ namespace __debug 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 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; - typedef _Tp mapped_type; - typedef std::pair value_type; - typedef _Compare key_compare; - typedef _Allocator allocator_type; - typedef typename _Base::reference reference; - typedef typename _Base::const_reference const_reference; + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator<_Base_iterator, map> - iterator; + iterator; typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, map> - const_iterator; + const_iterator; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 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) { } - -#if __cplusplus >= 201103L - map(map&& __x) - noexcept(is_nothrow_copy_constructible<_Compare>::value) - : _Base(std::move(__x)) - { this->_M_swap(__x); } + ~map() { } +#else + map() = default; + map(const map&) = default; + map(map&&) = default; map(initializer_list __l, const _Compare& __c = _Compare(), @@ -118,46 +105,53 @@ namespace __debug : _Base(__m, __a) { } map(map&& __m, const allocator_type& __a) - : _Base(std::move(__m._M_base()), __a) { } + : _Safe(std::move(__m._M_safe()), __a), + _Base(std::move(__m._M_base()), __a) { } map(initializer_list __l, const allocator_type& __a) : _Base(__l, __a) { } template - map(_InputIterator __first, _InputIterator __last, + map(_InputIterator __first, _InputIterator __last, const allocator_type& __a) - : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, - __last)), - __gnu_debug::__base(__last), __a) + : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, + __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; } - -#if __cplusplus >= 201103L +#else 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=(const map&) = default; + + map& + operator=(map&&) = default; map& operator=(initializer_list __l) @@ -173,7 +167,7 @@ namespace __debug using _Base::get_allocator; // iterators: - iterator + iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } @@ -269,9 +263,9 @@ namespace __debug template::value>::type> - std::pair - insert(_Pair&& __x) - { + std::pair + insert(_Pair&& __x) + { std::pair<_Base_iterator, bool> __res = _Base::insert(std::forward<_Pair>(__x)); return std::pair(iterator(__res.first, this), @@ -300,9 +294,9 @@ namespace __debug template::value>::type> - iterator - insert(const_iterator __position, _Pair&& __x) - { + iterator + insert(const_iterator __position, _Pair&& __x) + { __glibcxx_check_insert(__position); return iterator(_Base::insert(__position.base(), std::forward<_Pair>(__x)), this); @@ -310,9 +304,9 @@ namespace __debug #endif template - void - insert(_InputIterator __first, _InputIterator __last) - { + void + insert(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _Base::insert(__gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -395,15 +389,11 @@ namespace __debug 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 @@ -463,18 +453,10 @@ namespace __debug } _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } 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())); - } + _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template +#include #include #include @@ -41,70 +42,55 @@ namespace __debug 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 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; - typedef _Tp mapped_type; - typedef std::pair value_type; - typedef _Compare key_compare; - typedef _Allocator allocator_type; - typedef typename _Base::reference reference; - typedef typename _Base::const_reference const_reference; + typedef _Key key_type; + typedef _Tp mapped_type; + typedef std::pair value_type; + typedef _Compare key_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator<_Base_iterator, multimap> - iterator; + iterator; typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, - multimap> const_iterator; + multimap> const_iterator; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 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) { } - -#if __cplusplus >= 201103L - multimap(multimap&& __x) - noexcept(is_nothrow_copy_constructible<_Compare>::value) - : _Base(std::move(__x)) - { this->_M_swap(__x); } + ~multimap() { } +#else + multimap() = default; + multimap(const multimap&) = default; + multimap(multimap&&) = default; multimap(initializer_list __l, const _Compare& __c = _Compare(), @@ -119,47 +105,52 @@ namespace __debug : _Base(__m, __a) { } multimap(multimap&& __m, const allocator_type& __a) - : _Base(std::move(__m._M_base()), __a) { } + : _Safe(std::move(__m._M_safe()), __a), + _Base(std::move(__m._M_base()), __a) { } multimap(initializer_list __l, const allocator_type& __a) - : _Base(__l, __a) - { } + : _Base(__l, __a) { } template - multimap(_InputIterator __first, _InputIterator __last, + 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; } - -#if __cplusplus >= 201103L +#else 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=(const multimap&) = default; + + multimap& + operator=(multimap&&) = default; multimap& operator=(initializer_list __l) @@ -247,7 +238,7 @@ namespace __debug this); } #endif - + iterator insert(const value_type& __x) { return iterator(_Base::insert(__x), this); } @@ -256,9 +247,9 @@ namespace __debug template::value>::type> - iterator - insert(_Pair&& __x) - { return iterator(_Base::insert(std::forward<_Pair>(__x)), this); } + iterator + insert(_Pair&& __x) + { return iterator(_Base::insert(std::forward<_Pair>(__x)), this); } #endif #if __cplusplus >= 201103L @@ -282,9 +273,9 @@ namespace __debug template::value>::type> - iterator - insert(const_iterator __position, _Pair&& __x) - { + iterator + insert(const_iterator __position, _Pair&& __x) + { __glibcxx_check_insert(__position); return iterator(_Base::insert(__position.base(), std::forward<_Pair>(__x)), this); @@ -292,9 +283,9 @@ namespace __debug #endif template - void - insert(_InputIterator __first, _InputIterator __last) - { + void + insert(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _Base::insert(__gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -379,15 +370,11 @@ namespace __debug 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 @@ -447,18 +434,10 @@ namespace __debug } _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } 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,69 +42,54 @@ namespace __debug 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 _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 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; - typedef _Key value_type; - typedef _Compare key_compare; - typedef _Compare value_compare; - typedef _Allocator allocator_type; - typedef typename _Base::reference reference; - typedef typename _Base::const_reference const_reference; + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator<_Base_iterator, multiset> - iterator; + iterator; typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, - multiset> const_iterator; + multiset> const_iterator; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 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) { } - -#if __cplusplus >= 201103L - multiset(multiset&& __x) - noexcept(is_nothrow_copy_constructible<_Compare>::value) - : _Base(std::move(__x)) - { this->_M_swap(__x); } + ~multiset() { } +#else + multiset() = default; + multiset(const multiset&) = default; + multiset(multiset&&) = default; multiset(initializer_list __l, const _Compare& __comp = _Compare(), @@ -118,47 +104,53 @@ namespace __debug : _Base(__m, __a) { } multiset(multiset&& __m, const allocator_type& __a) - : _Base(std::move(__m._M_base()), __a) { } + : _Safe(std::move(__m._M_safe()), __a), + _Base(std::move(__m._M_base()), __a) { } multiset(initializer_list __l, const allocator_type& __a) : _Base(__l, __a) { } template - multiset(_InputIterator __first, _InputIterator __last, + multiset(_InputIterator __first, _InputIterator __last, const allocator_type& __a) - : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, - __last)), - __gnu_debug::__base(__last), __a) - { } + : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, + __last)), + __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; } - -#if __cplusplus >= 201103L +#else 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=(const multiset&) = default; + + multiset& + operator=(multiset&&) = default; multiset& operator=(initializer_list __l) @@ -233,7 +225,8 @@ namespace __debug 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 @@ namespace __debug 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 @@ -440,18 +429,10 @@ namespace __debug } _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } 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 diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h index 631ac773ddb..fc589159a37 100644 --- a/libstdc++-v3/include/debug/safe_base.h +++ b/libstdc++-v3/include/debug/safe_base.h @@ -52,7 +52,7 @@ namespace __gnu_debug public: /** The sequence this iterator references; may be NULL to indicate a singular iterator. */ - _Safe_sequence_base* _M_sequence; + _Safe_sequence_base* _M_sequence; /** The version number of this iterator. The sentinel value 0 is * used to indicate an invalidated iterator (i.e., one that is @@ -61,15 +61,15 @@ namespace __gnu_debug * referenced by _M_sequence for the iterator to be * non-singular. */ - unsigned int _M_version; + unsigned int _M_version; /** Pointer to the previous iterator in the sequence's list of iterators. Only valid when _M_sequence != NULL. */ - _Safe_iterator_base* _M_prior; + _Safe_iterator_base* _M_prior; /** Pointer to the next iterator in the sequence's list of iterators. Only valid when _M_sequence != NULL. */ - _Safe_iterator_base* _M_next; + _Safe_iterator_base* _M_next; protected: /** Initializes the iterator and makes it singular. */ @@ -104,7 +104,8 @@ namespace __gnu_debug ~_Safe_iterator_base() { this->_M_detach(); } /** For use in _Safe_iterator. */ - __gnu_cxx::__mutex& _M_get_mutex() throw (); + __gnu_cxx::__mutex& + _M_get_mutex() throw (); public: /** Attaches this iterator to the given sequence, detaching it @@ -112,30 +113,37 @@ namespace __gnu_debug * new sequence is the NULL pointer, the iterator is left * unattached. */ - void _M_attach(_Safe_sequence_base* __seq, bool __constant); + void + _M_attach(_Safe_sequence_base* __seq, bool __constant); /** Likewise, but not thread-safe. */ - void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw (); + void + _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw (); /** Detach the iterator for whatever sequence it is attached to, * if any. */ - void _M_detach(); + void + _M_detach(); /** Likewise, but not thread-safe. */ - void _M_detach_single() throw (); + void + _M_detach_single() throw (); /** Determines if we are attached to the given sequence. */ - bool _M_attached_to(const _Safe_sequence_base* __seq) const + bool + _M_attached_to(const _Safe_sequence_base* __seq) const { return _M_sequence == __seq; } /** Is this iterator singular? */ - _GLIBCXX_PURE bool _M_singular() const throw (); + _GLIBCXX_PURE bool + _M_singular() const throw (); /** Can we compare this iterator to the given iterator @p __x? Returns true if both iterators are nonsingular and reference the same sequence. */ - _GLIBCXX_PURE bool _M_can_compare(const _Safe_iterator_base& __x) const throw (); + _GLIBCXX_PURE bool + _M_can_compare(const _Safe_iterator_base& __x) const throw (); /** Invalidate the iterator, making it singular. */ void @@ -188,17 +196,13 @@ namespace __gnu_debug 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); } + : _Safe_sequence_base() { } #endif /** Notify all iterators that reference this sequence that the @@ -231,10 +235,11 @@ namespace __gnu_debug * one container now reference the other container. */ void - _M_swap(_Safe_sequence_base& __x); + _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT; /** For use in _Safe_sequence. */ - __gnu_cxx::__mutex& _M_get_mutex() throw (); + __gnu_cxx::__mutex& + _M_get_mutex() throw (); public: /** Invalidates all iterators. */ diff --git a/libstdc++-v3/include/debug/safe_container.h b/libstdc++-v3/include/debug/safe_container.h new file mode 100644 index 00000000000..a429ae02343 --- /dev/null +++ b/libstdc++-v3/include/debug/safe_container.h @@ -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 _IsCxx11AllocatorAware = true> + class _Safe_container + : public _SafeBase<_SafeContainer> + { + typedef _SafeBase<_SafeContainer> _Base; + + _SafeContainer& + _M_cont() _GLIBCXX_NOEXCEPT + { return *static_cast<_SafeContainer*>(this); } + + protected: + _Safe_container& + _M_safe() _GLIBCXX_NOEXCEPT + { return *this; } + +#if __cplusplus >= 201103L + _Safe_container() = default; + _Safe_container(const _Safe_container&) = default; + _Safe_container(_Safe_container&& __x) noexcept + : _Safe_container() + { _Base::_M_swap(__x); } + + _Safe_container(_Safe_container&& __x, + const _Alloc& __a) + : _Safe_container() + { + if (__x._M_cont().get_allocator() == __a) + _Base::_M_swap(__x); + else + __x._M_invalidate_all(); + } +#endif + + public: + // Copy assignment invalidate all iterators. + _Safe_container& + operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT + { + this->_M_invalidate_all(); + return *this; + } + +#if __cplusplus >= 201103L + _Safe_container& + operator=(_Safe_container&& __x) noexcept + { + __glibcxx_check_self_move_assign(__x); + + if (_IsCxx11AllocatorAware) + { + typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits; + + bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign() + || _M_cont().get_allocator() == __x._M_cont().get_allocator(); + if (__xfer_memory) + _Base::_M_swap(__x); + else + this->_M_invalidate_all(); + } + else + _Base::_M_swap(__x); + + __x._M_invalidate_all(); + return *this; + } + + void + _M_swap(_Safe_container& __x) noexcept + { + if (_IsCxx11AllocatorAware) + { + typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits; + + if (!_Alloc_traits::_S_propagate_on_swap()) + __glibcxx_check_equal_allocs(this->_M_cont()._M_base(), + __x._M_cont()._M_base()); + } + + _Base::_M_swap(__x); + } +#endif + }; + +} // namespace __gnu_debug + +#endif diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index d563db0a8f4..b6f136322f4 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -58,7 +58,7 @@ namespace __gnu_debug /** Iterators that derive from _Safe_iterator_base can be determined singular * or non-singular. **/ - inline bool + inline bool __check_singular_aux(const _Safe_iterator_base* __x) { return __x->_M_singular(); } @@ -127,12 +127,12 @@ namespace __gnu_debug typedef std::iterator_traits<_Iterator> _Traits; public: - typedef _Iterator iterator_type; - typedef typename _Traits::iterator_category iterator_category; - typedef typename _Traits::value_type value_type; - typedef typename _Traits::difference_type difference_type; - typedef typename _Traits::reference reference; - typedef typename _Traits::pointer pointer; + typedef _Iterator iterator_type; + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; /// @post the iterator is singular and unattached _Safe_iterator() _GLIBCXX_NOEXCEPT : _M_current() { } @@ -191,13 +191,13 @@ namespace __gnu_debug * constant iterator. */ template - _Safe_iterator( - const _Safe_iterator<_MutableIterator, - typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, - typename _Sequence::iterator::iterator_type>::__value), - _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT + _Safe_iterator( + const _Safe_iterator<_MutableIterator, + typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator, + typename _Sequence::iterator::iterator_type>::__value), + _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base()) - { + { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 408. Is vector > forbidden? _GLIBCXX_DEBUG_VERIFY(!__x._M_singular() @@ -497,7 +497,7 @@ namespace __gnu_debug template inline bool operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs, - const _Safe_iterator<_Iterator, _Sequence>& __rhs) + const _Safe_iterator<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), @@ -531,7 +531,7 @@ namespace __gnu_debug template inline bool operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, - const _Safe_iterator<_Iterator, _Sequence>& __rhs) + const _Safe_iterator<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), @@ -599,7 +599,7 @@ namespace __gnu_debug template inline bool operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, - const _Safe_iterator<_Iterator, _Sequence>& __rhs) + const _Safe_iterator<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), @@ -667,7 +667,7 @@ namespace __gnu_debug template inline bool operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs, - const _Safe_iterator<_Iterator, _Sequence>& __rhs) + const _Safe_iterator<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(), diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h b/libstdc++-v3/include/debug/safe_local_iterator.h index 77552ced0b1..50da161ebce 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.h +++ b/libstdc++-v3/include/debug/safe_local_iterator.h @@ -69,12 +69,12 @@ namespace __gnu_debug typedef std::iterator_traits<_Iterator> _Traits; public: - typedef _Iterator iterator_type; - typedef typename _Traits::iterator_category iterator_category; - typedef typename _Traits::value_type value_type; - typedef typename _Traits::difference_type difference_type; - typedef typename _Traits::reference reference; - typedef typename _Traits::pointer pointer; + typedef _Iterator iterator_type; + typedef typename _Traits::iterator_category iterator_category; + typedef typename _Traits::value_type value_type; + typedef typename _Traits::difference_type difference_type; + typedef typename _Traits::reference reference; + typedef typename _Traits::pointer pointer; /// @post the iterator is singular and unattached _Safe_local_iterator() : _M_current() { } diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h index 245d85147d2..8649436e4d8 100644 --- a/libstdc++-v3/include/debug/safe_sequence.h +++ b/libstdc++-v3/include/debug/safe_sequence.h @@ -116,17 +116,36 @@ namespace __gnu_debug true. @c __pred will be invoked with the normal iterators nested in the safe ones. */ template - void - _M_invalidate_if(_Predicate __pred); + void + _M_invalidate_if(_Predicate __pred); /** Transfers all iterators @c x that reference @c from sequence, are not singular, and for which @c __pred(x) returns @c true. @c __pred will be invoked with the normal iterators nested in the safe ones. */ template - void - _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred); + 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 diff --git a/libstdc++-v3/include/debug/safe_sequence.tcc b/libstdc++-v3/include/debug/safe_sequence.tcc index fad779caae4..5fef446359e 100644 --- a/libstdc++-v3/include/debug/safe_sequence.tcc +++ b/libstdc++-v3/include/debug/safe_sequence.tcc @@ -37,11 +37,11 @@ namespace __gnu_debug _Safe_sequence<_Sequence>:: _M_invalidate_if(_Predicate __pred) { - typedef typename _Sequence::iterator iterator; - typedef typename _Sequence::const_iterator const_iterator; + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex()); - for (_Safe_iterator_base* __iter = _M_iterators; __iter;) + for (_Safe_iterator_base* __iter = _M_iterators; __iter;) { iterator* __victim = static_cast(__iter); __iter = __iter->_M_next; @@ -51,7 +51,7 @@ namespace __gnu_debug } } - for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) + for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;) { const_iterator* __victim = static_cast(__iter2); __iter2 = __iter2->_M_next; @@ -68,8 +68,8 @@ namespace __gnu_debug _Safe_sequence<_Sequence>:: _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred) { - typedef typename _Sequence::iterator iterator; - typedef typename _Sequence::const_iterator const_iterator; + typedef typename _Sequence::iterator iterator; + typedef typename _Sequence::const_iterator const_iterator; _Safe_iterator_base* __transfered_iterators = 0; _Safe_iterator_base* __transfered_const_iterators = 0; @@ -79,7 +79,7 @@ namespace __gnu_debug // We lock __from first and detach iterator(s) to transfer __gnu_cxx::__scoped_lock sentry(__from._M_get_mutex()); - for (_Safe_iterator_base* __iter = __from._M_iterators; __iter;) + for (_Safe_iterator_base* __iter = __from._M_iterators; __iter;) { iterator* __victim = static_cast(__iter); __iter = __iter->_M_next; diff --git a/libstdc++-v3/include/debug/safe_unordered_base.h b/libstdc++-v3/include/debug/safe_unordered_base.h index bbb274f34e4..31c5c894cc1 100644 --- a/libstdc++-v3/include/debug/safe_unordered_base.h +++ b/libstdc++-v3/include/debug/safe_unordered_base.h @@ -80,7 +80,7 @@ namespace __gnu_debug ~_Safe_local_iterator_base() { this->_M_detach(); } _Safe_unordered_container_base* - _M_get_container() const _GLIBCXX_NOEXCEPT; + _M_get_container() const noexcept; public: /** Attaches this iterator to the given container, detaching it @@ -132,15 +132,16 @@ namespace __gnu_debug protected: // Initialize with a version number of 1 and no iterators - _Safe_unordered_container_base() + _Safe_unordered_container_base() noexcept : _M_local_iterators(nullptr), _M_const_local_iterators(nullptr) { } - // Initialize with a version number of 1 and no iterators + // Copy constructor does not copy iterators. _Safe_unordered_container_base(const _Safe_unordered_container_base&) noexcept : _Safe_unordered_container_base() { } + // When moved unordered containers iterators are swapped. _Safe_unordered_container_base(_Safe_unordered_container_base&& __x) noexcept : _Safe_unordered_container_base() @@ -148,7 +149,7 @@ namespace __gnu_debug /** 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 @@ namespace __gnu_debug * 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. */ diff --git a/libstdc++-v3/include/debug/safe_unordered_container.h b/libstdc++-v3/include/debug/safe_unordered_container.h index 825dee9439e..96933feaf3c 100644 --- a/libstdc++-v3/include/debug/safe_unordered_container.h +++ b/libstdc++-v3/include/debug/safe_unordered_container.h @@ -57,7 +57,31 @@ namespace __gnu_debug template class _Safe_unordered_container : public _Safe_unordered_container_base { - public: + private: + _Container& + _M_cont() noexcept + { return *static_cast<_Container*>(this); } + + protected: + void + _M_invalidate_locals() + { + auto __local_end = _M_cont()._M_base().end(0); + this->_M_invalidate_local_if( + [__local_end](__decltype(_M_cont()._M_base().cend(0)) __it) + { return __it != __local_end; }); + } + + void + _M_invalidate_all() + { + auto __end = _M_cont()._M_base().end(); + this->_M_invalidate_if( + [__end](__decltype(_M_cont()._M_base().cend()) __it) + { return __it != __end; }); + _M_invalidate_locals(); + } + /** Invalidates all iterators @c x that reference this container, are not singular, and for which @c __pred(x) returns @c true. @c __pred will be invoked with the normal iterators nested diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h index c83e2afa96c..d70febe5a39 100644 --- a/libstdc++-v3/include/debug/set.h +++ b/libstdc++-v3/include/debug/set.h @@ -30,10 +30,11 @@ #define _GLIBCXX_DEBUG_SET_H 1 #include +#include #include #include -namespace std _GLIBCXX_VISIBILITY(default) +namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug { @@ -41,68 +42,54 @@ namespace __debug 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 _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 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; - typedef _Key value_type; - typedef _Compare key_compare; - typedef _Compare value_compare; - typedef _Allocator allocator_type; - typedef typename _Base::reference reference; - typedef typename _Base::const_reference const_reference; + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + typedef _Allocator allocator_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; typedef __gnu_debug::_Safe_iterator<_Base_iterator, set> - iterator; + iterator; typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, set> - const_iterator; + const_iterator; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 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) { } - -#if __cplusplus >= 201103L - set(set&& __x) - noexcept(is_nothrow_copy_constructible<_Compare>::value) - : _Base(std::move(__x)) - { this->_M_swap(__x); } + ~set() { } +#else + set() = default; + set(const set&) = default; + set(set&&) = default; set(initializer_list __l, const _Compare& __comp = _Compare(), @@ -117,47 +104,52 @@ namespace __debug : _Base(__x, __a) { } set(set&& __x, const allocator_type& __a) - : _Base(std::move(__x._M_base()), __a) { } + : _Safe(std::move(__x._M_safe()), __a), + _Base(std::move(__x._M_base()), __a) { } set(initializer_list __l, const allocator_type& __a) - : _Base(__l, __a) - { } + : _Base(__l, __a) { } template - set(_InputIterator __first, _InputIterator __last, + 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; } - -#if __cplusplus >= 201103L +#else 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=(const set&) = default; + + set& + operator=(set&&) = default; set& operator=(initializer_list __l) @@ -285,9 +277,9 @@ namespace __debug #endif template - void - insert(_InputIterator __first, _InputIterator __last) - { + void + insert(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _Base::insert(__gnu_debug::__base(__first), __gnu_debug::__base(__last)); @@ -322,7 +314,7 @@ namespace __debug { _Base_iterator __victim = _Base::find(__x); if (__victim == _Base::end()) - return 0; + return 0; else { this->_M_invalidate_if(_Equal(__victim)); @@ -372,15 +364,11 @@ namespace __debug 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 @@ -431,7 +419,7 @@ namespace __debug equal_range(const key_type& __x) { std::pair<_Base_iterator, _Base_iterator> __res = - _Base::equal_range(__x); + _Base::equal_range(__x); return std::make_pair(iterator(__res.first, this), iterator(__res.second, this)); } @@ -442,24 +430,16 @@ namespace __debug equal_range(const key_type& __x) const { std::pair<_Base_iterator, _Base_iterator> __res = - _Base::equal_range(__x); + _Base::equal_range(__x); return std::make_pair(const_iterator(__res.first, this), const_iterator(__res.second, this)); } _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } 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())); - } + _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string index 8edc9c473cc..8510ee4b59a 100644 --- a/libstdc++-v3/include/debug/string +++ b/libstdc++-v3/include/debug/string @@ -31,70 +31,82 @@ #include #include +#include #include namespace __gnu_debug { /// Class std::basic_string with safety/checking/debug instrumentation. template, - typename _Allocator = std::allocator<_CharT> > + typename _Allocator = std::allocator<_CharT> > class basic_string - : public std::basic_string<_CharT, _Traits, _Allocator>, - public __gnu_debug::_Safe_sequence > + : public __gnu_debug::_Safe_container< + basic_string<_CharT, _Traits, _Allocator>, + _Allocator, _Safe_sequence, false>, + public std::basic_string<_CharT, _Traits, _Allocator> { - typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; - typedef __gnu_debug::_Safe_sequence _Safe_base; + typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; + typedef __gnu_debug::_Safe_container< + basic_string, _Allocator, _Safe_sequence, false> _Safe; public: // types: - typedef _Traits traits_type; - typedef typename _Traits::char_type value_type; - typedef _Allocator allocator_type; - typedef typename _Base::size_type size_type; - typedef typename _Base::difference_type difference_type; - typedef typename _Base::reference reference; - typedef typename _Base::const_reference const_reference; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; + typedef typename _Base::reference reference; + typedef typename _Base::const_reference const_reference; + 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; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; using _Base::npos; // 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) { } - - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 42. string ctors specify wrong default allocator +#if __cplusplus < 201103L basic_string(const basic_string& __str) - : _Base(__str, 0, _Base::npos, __str.get_allocator()) + : _Base(__str) { } + + ~basic_string() { } +#else + basic_string(const basic_string&) = default; + basic_string(basic_string&&) = default; + + basic_string(std::initializer_list<_CharT> __l, + const _Allocator& __a = _Allocator()) + : _Base(__l, __a) { } + ~basic_string() = default; +#endif // C++11 + + // Provides conversion from a normal-mode string to a debug-mode string + basic_string(const _Base& __base) + : _Base(__base) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 42. string ctors specify wrong default allocator basic_string(const basic_string& __str, size_type __pos, - size_type __n = _Base::npos, - const _Allocator& __a = _Allocator()) - : _Base(__str, __pos, __n, __a) - { } + size_type __n = _Base::npos, + const _Allocator& __a = _Allocator()) + : _Base(__str, __pos, __n, __a) { } basic_string(const _CharT* __s, size_type __n, const _Allocator& __a = _Allocator()) - : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) - { } + : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) { } basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) : _Base(__gnu_debug::__check_string(__s), __a) @@ -102,43 +114,36 @@ namespace __gnu_debug basic_string(size_type __n, _CharT __c, const _Allocator& __a = _Allocator()) - : _Base(__n, __c, __a) - { } + : _Base(__n, __c, __a) { } template basic_string(_InputIterator __begin, _InputIterator __end, const _Allocator& __a = _Allocator()) : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin, __end)), - __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 { } + __gnu_debug::__base(__end), __a) { } +#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 +151,16 @@ namespace __gnu_debug 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; } @@ -576,7 +572,7 @@ namespace __gnu_debug // 151. can't currently clear() empty container __glibcxx_check_erase_range(__first, __last); typename _Base::iterator __res = _Base::erase(__first.base(), - __last.base()); + __last.base()); this->_M_invalidate_all(); return iterator(__res, this); } @@ -704,12 +700,10 @@ namespace __gnu_debug } void - swap(basic_string<_CharT,_Traits,_Allocator>& __x) + swap(basic_string& __x) { + _Safe::_M_swap(__x); _Base::swap(__x); - this->_M_swap(__x); - this->_M_invalidate_all(); - __x._M_invalidate_all(); } // 21.3.6 string operations: @@ -801,7 +795,7 @@ namespace __gnu_debug { return _Base::find_first_of(__c, __pos); } size_type - find_last_of(const basic_string& __str, + find_last_of(const basic_string& __str, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT { return _Base::find_last_of(__str, __pos); } @@ -910,19 +904,19 @@ namespace __gnu_debug // 5. string::compare specification questionable int compare(size_type __pos1, size_type __n1,const _CharT* __s, - size_type __n2) const + size_type __n2) const { __glibcxx_check_string_len(__s, __n2); return _Base::compare(__pos1, __n1, __s, __n2); } _Base& - _M_base() _GLIBCXX_NOEXCEPT { return *this; } + _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& - _M_base() const _GLIBCXX_NOEXCEPT { return *this; } + _M_base() const _GLIBCXX_NOEXCEPT { return *this; } - using _Safe_base::_M_invalidate_all; + using _Safe::_M_invalidate_all; }; template diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 626beba5f46..b1596e29070 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -35,6 +35,7 @@ # include #include +#include #include #include @@ -48,38 +49,38 @@ namespace __debug 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 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; + _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::local_iterator _Base_local_iterator; public: - typedef typename _Base::size_type size_type; - typedef typename _Base::hasher hasher; - typedef typename _Base::key_equal key_equal; - typedef typename _Base::allocator_type allocator_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; - typedef typename _Base::key_type key_type; - typedef typename _Base::value_type value_type; + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; - typedef __gnu_debug::_Safe_iterator<_Base_iterator, - unordered_map> iterator; - typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, - unordered_map> const_iterator; - typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator, - unordered_map> local_iterator; - typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator, - unordered_map> const_local_iterator; + typedef __gnu_debug::_Safe_iterator< + _Base_iterator, unordered_map> iterator; + typedef __gnu_debug::_Safe_iterator< + _Base_const_iterator, unordered_map> const_iterator; + typedef __gnu_debug::_Safe_local_iterator< + _Base_local_iterator, unordered_map> local_iterator; + typedef __gnu_debug::_Safe_local_iterator< + _Base_const_local_iterator, unordered_map> const_local_iterator; explicit unordered_map(size_type __n = 10, @@ -89,10 +90,10 @@ namespace __debug : _Base(__n, __hf, __eql, __a) { } template - unordered_map(_InputIterator __first, _InputIterator __last, + unordered_map(_InputIterator __first, _InputIterator __last, size_type __n = 0, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal(), + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), @@ -108,18 +109,16 @@ namespace __debug explicit unordered_map(const allocator_type& __a) - : _Base(__a) - { } + : _Base(__a) { } unordered_map(const unordered_map& __umap, const allocator_type& __a) - : _Base(__umap._M_base(), __a) - { } + : _Base(__umap, __a) { } unordered_map(unordered_map&& __umap, const allocator_type& __a) - : _Base(std::move(__umap._M_base()), __a) - { } + : _Safe(std::move(__umap._M_safe()), __a), + _Base(std::move(__umap._M_base()), __a) { } unordered_map(initializer_list __l, size_type __n = 0, @@ -128,31 +127,13 @@ namespace __debug 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 @@ namespace __debug void swap(unordered_map& __x) - noexcept(_Alloc_traits::_S_nothrow_swap()) + noexcept( noexcept(declval<_Base>().swap(__x)) ) { - if (!_Alloc_traits::_S_propagate_on_swap()) - __glibcxx_check_equal_allocs(__x); + _Safe::_M_swap(__x); _Base::swap(__x); - _Safe_base::_M_swap(__x); } void @@ -179,7 +158,7 @@ namespace __debug this->_M_invalidate_all(); } - iterator + iterator begin() noexcept { return iterator(_Base::begin(), this); } @@ -301,7 +280,7 @@ namespace __debug { __glibcxx_check_insert(__hint); size_type __bucket_count = this->bucket_count(); - _Base_iterator __it = _Base::insert(__hint.base(), __obj); + _Base_iterator __it = _Base::insert(__hint.base(), __obj); _M_check_rehashed(__bucket_count); return iterator(__it, this); } @@ -348,7 +327,7 @@ namespace __debug __glibcxx_check_valid_range(__first, __last); size_type __bucket_count = this->bucket_count(); _Base::insert(__gnu_debug::__base(__first), - __gnu_debug::__base(__last)); + __gnu_debug::__base(__last)); _M_check_rehashed(__bucket_count); } @@ -409,7 +388,7 @@ namespace __debug [__victim](_Base_const_local_iterator __it) { return __it._M_curr() == __victim._M_cur; }); size_type __bucket_count = this->bucket_count(); - _Base_iterator __next = _Base::erase(__it.base()); + _Base_iterator __next = _Base::erase(__it.base()); _M_check_rehashed(__bucket_count); return iterator(__next, this); } @@ -442,35 +421,17 @@ namespace __debug } _Base& - _M_base() noexcept { return *this; } + _M_base() noexcept { return *this; } const _Base& - _M_base() const noexcept { return *this; } + _M_base() const noexcept { return *this; } 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,38 +463,35 @@ namespace __debug 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 typename _Base::const_iterator _Base_const_iterator; - typedef typename _Base::iterator _Base_iterator; + _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::local_iterator _Base_local_iterator; - - typedef __gnu_cxx::__alloc_traits _Alloc_traits; + typedef typename _Base::local_iterator _Base_local_iterator; public: - typedef typename _Base::size_type size_type; - typedef typename _Base::hasher hasher; - typedef typename _Base::key_equal key_equal; - typedef typename _Base::allocator_type allocator_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; - typedef typename _Base::key_type key_type; - typedef typename _Base::value_type value_type; + 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; + _Base_local_iterator, unordered_multimap> local_iterator; typedef __gnu_debug::_Safe_local_iterator< _Base_const_local_iterator, unordered_multimap> const_local_iterator; @@ -545,10 +503,10 @@ namespace __debug : _Base(__n, __hf, __eql, __a) { } template - unordered_multimap(_InputIterator __first, _InputIterator __last, + unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n = 0, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal(), + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), @@ -557,25 +515,23 @@ namespace __debug unordered_multimap(const unordered_multimap&) = default; - unordered_multimap(const _Base& __x) + unordered_multimap(const _Base& __x) : _Base(__x) { } unordered_multimap(unordered_multimap&&) = default; explicit unordered_multimap(const allocator_type& __a) - : _Base(__a) - { } + : _Base(__a) { } unordered_multimap(const unordered_multimap& __umap, const allocator_type& __a) - : _Base(__umap._M_base(), __a) - { } + : _Base(__umap, __a) { } unordered_multimap(unordered_multimap&& __umap, const allocator_type& __a) - : _Base(std::move(__umap._M_base()), __a) - { } + : _Safe(std::move(__umap._M_safe()), __a), + _Base(std::move(__umap._M_base()), __a) { } unordered_multimap(initializer_list __l, size_type __n = 0, @@ -584,48 +540,28 @@ namespace __debug 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 @@ -635,7 +571,7 @@ namespace __debug this->_M_invalidate_all(); } - iterator + iterator begin() noexcept { return iterator(_Base::begin(), this); } @@ -894,35 +830,17 @@ namespace __debug } _Base& - _M_base() noexcept { return *this; } + _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } 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(); } }; diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index a17efd0a5fe..63a68776084 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -35,6 +35,7 @@ # include #include +#include #include #include @@ -48,37 +49,38 @@ namespace __debug 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 typename _Base::const_iterator _Base_const_iterator; - typedef typename _Base::iterator _Base_iterator; + 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 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; - typedef typename _Base::key_equal key_equal; - typedef typename _Base::allocator_type allocator_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; - typedef typename _Base::key_type key_type; - typedef typename _Base::value_type value_type; + typedef typename _Base::key_type key_type; + typedef typename _Base::value_type value_type; - typedef __gnu_debug::_Safe_iterator<_Base_iterator, - unordered_set> iterator; - typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, - unordered_set> const_iterator; - typedef __gnu_debug::_Safe_local_iterator<_Base_local_iterator, - unordered_set> local_iterator; - typedef __gnu_debug::_Safe_local_iterator<_Base_const_local_iterator, - unordered_set> const_local_iterator; + typedef __gnu_debug::_Safe_iterator< + _Base_iterator, unordered_set> iterator; + typedef __gnu_debug::_Safe_iterator< + _Base_const_iterator, unordered_set> const_iterator; + typedef __gnu_debug::_Safe_local_iterator< + _Base_local_iterator, unordered_set> local_iterator; + typedef __gnu_debug::_Safe_local_iterator< + _Base_const_local_iterator, unordered_set> const_local_iterator; explicit unordered_set(size_type __n = 10, @@ -88,10 +90,10 @@ namespace __debug : _Base(__n, __hf, __eql, __a) { } template - unordered_set(_InputIterator __first, _InputIterator __last, + unordered_set(_InputIterator __first, _InputIterator __last, size_type __n = 0, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal(), + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), @@ -101,24 +103,22 @@ namespace __debug unordered_set(const unordered_set&) = default; unordered_set(const _Base& __x) - : _Base(__x) { } + : _Base(__x) { } unordered_set(unordered_set&&) = default; explicit unordered_set(const allocator_type& __a) - : _Base(__a) - { } + : _Base(__a) { } unordered_set(const unordered_set& __uset, const allocator_type& __a) - : _Base(__uset._M_base(), __a) - { } + : _Base(__uset, __a) { } unordered_set(unordered_set&& __uset, const allocator_type& __a) - : _Base(std::move(__uset._M_base()), __a) - { } + : _Safe(std::move(__uset._M_safe()), __a), + _Base(std::move(__uset._M_base()), __a) { } unordered_set(initializer_list __l, size_type __n = 0, @@ -127,31 +127,13 @@ namespace __debug 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 @@ namespace __debug void swap(unordered_set& __x) - noexcept(_Alloc_traits::_S_nothrow_swap()) + noexcept( noexcept(declval<_Base>().swap(__x)) ) { - if (!_Alloc_traits::_S_propagate_on_swap()) - __glibcxx_check_equal_allocs(__x); + _Safe::_M_swap(__x); _Base::swap(__x); - _Safe_base::_M_swap(__x); } void @@ -178,7 +158,7 @@ namespace __debug this->_M_invalidate_all(); } - iterator + iterator begin() noexcept { return iterator(_Base::begin(), this); } @@ -290,8 +270,8 @@ namespace __debug 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 @@ namespace __debug 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 @@ namespace __debug 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)); } @@ -439,36 +419,17 @@ namespace __debug } _Base& - _M_base() noexcept { return *this; } + _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } 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,37 +458,36 @@ namespace __debug 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 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; + 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::local_iterator _Base_local_iterator; public: - typedef typename _Base::size_type size_type; - typedef typename _Base::hasher hasher; - typedef typename _Base::key_equal key_equal; - typedef typename _Base::allocator_type allocator_type; + typedef typename _Base::size_type size_type; + typedef typename _Base::hasher hasher; + typedef typename _Base::key_equal key_equal; + typedef typename _Base::allocator_type allocator_type; - typedef typename _Base::key_type key_type; - typedef typename _Base::value_type value_type; + 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; + _Base_local_iterator, unordered_multiset> local_iterator; typedef __gnu_debug::_Safe_local_iterator< _Base_const_local_iterator, unordered_multiset> const_local_iterator; @@ -539,10 +499,10 @@ namespace __debug : _Base(__n, __hf, __eql, __a) { } template - unordered_multiset(_InputIterator __first, _InputIterator __last, + unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n = 0, - const hasher& __hf = hasher(), - const key_equal& __eql = key_equal(), + const hasher& __hf = hasher(), + const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), @@ -551,25 +511,23 @@ namespace __debug unordered_multiset(const unordered_multiset&) = default; - unordered_multiset(const _Base& __x) + unordered_multiset(const _Base& __x) : _Base(__x) { } unordered_multiset(unordered_multiset&&) = default; explicit unordered_multiset(const allocator_type& __a) - : _Base(__a) - { } + : _Base(__a) { } unordered_multiset(const unordered_multiset& __uset, const allocator_type& __a) - : _Base(__uset._M_base(), __a) - { } - + : _Base(__uset, __a) { } + unordered_multiset(unordered_multiset&& __uset, const allocator_type& __a) - : _Base(std::move(__uset._M_base()), __a) - { } + : _Safe(std::move(__uset._M_safe()), __a), + _Base(std::move(__uset._M_base()), __a) { } unordered_multiset(initializer_list __l, size_type __n = 0, @@ -578,48 +536,28 @@ namespace __debug 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 @@ -751,7 +689,7 @@ namespace __debug { __glibcxx_check_insert(__hint); size_type __bucket_count = this->bucket_count(); - _Base_iterator __it = _Base::insert(__hint.base(), __obj); + _Base_iterator __it = _Base::insert(__hint.base(), __obj); _M_check_rehashed(__bucket_count); return iterator(__it, this); } @@ -760,7 +698,7 @@ namespace __debug insert(value_type&& __obj) { size_type __bucket_count = this->bucket_count(); - _Base_iterator __it = _Base::insert(std::move(__obj)); + _Base_iterator __it = _Base::insert(std::move(__obj)); _M_check_rehashed(__bucket_count); return iterator(__it, this); } @@ -770,7 +708,7 @@ namespace __debug { __glibcxx_check_insert(__hint); size_type __bucket_count = this->bucket_count(); - _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj)); + _Base_iterator __it = _Base::insert(__hint.base(), std::move(__obj)); _M_check_rehashed(__bucket_count); return iterator(__it, this); } @@ -805,8 +743,8 @@ namespace __debug 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)); } @@ -878,35 +816,17 @@ namespace __debug } _Base& - _M_base() noexcept { return *this; } + _M_base() noexcept { return *this; } const _Base& - _M_base() const noexcept { return *this; } + _M_base() const noexcept { return *this; } 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(); } }; diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index 2e9cd656b5c..427d19fd4a9 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -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,61 +102,67 @@ namespace __debug 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 _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 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 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; + typedef typename _Base::size_type size_type; + typedef typename _Base::difference_type difference_type; - typedef _Tp value_type; - typedef _Allocator allocator_type; - typedef typename _Base::pointer pointer; - typedef typename _Base::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef _Tp value_type; + typedef _Allocator allocator_type; + typedef typename _Base::pointer pointer; + typedef typename _Base::const_pointer const_pointer; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; // 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 @@ -105,83 +171,62 @@ namespace __debug #else template #endif - vector(_InputIterator __first, _InputIterator __last, + vector(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) - : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, + : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first, __last)), - __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()) { } - -#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() _GLIBCXX_NOEXCEPT { } +#else + vector(const vector&) = default; + vector(vector&&) = default; vector(const vector& __x, const allocator_type& __a) - : _Base(__x, __a), _M_guaranteed_capacity(__x.size()) { } + : _Base(__x, __a) { } vector(vector&& __x, const allocator_type& __a) - : _Base(std::move(__x), __a), - _M_guaranteed_capacity(this->size()) - { - if (__x.get_allocator() == __a) - this->_M_swap(__x); - else - __x._M_invalidate_all(); - __x._M_guaranteed_capacity = 0; - } + : _Safe(std::move(__x._M_safe()), __a), + _Base(std::move(__x._M_base()), __a), + _Safe_vector(std::move(__x)) { } vector(initializer_list __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; } - -#if __cplusplus >= 201103L +#else 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=(const vector&) = default; + + vector& + 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 @@ -192,14 +237,14 @@ namespace __debug #else template #endif - void - assign(_InputIterator __first, _InputIterator __last) - { + void + assign(_InputIterator __first, _InputIterator __last) + { __glibcxx_check_valid_range(__first, __last); _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 @@ namespace __debug { _Base::assign(__n, __u); this->_M_invalidate_all(); - _M_update_guaranteed_capacity(); + this->_M_update_guaranteed_capacity(); } #if __cplusplus >= 201103L @@ -216,7 +261,7 @@ namespace __debug { _Base::assign(__l); this->_M_invalidate_all(); - _M_update_guaranteed_capacity(); + this->_M_update_guaranteed_capacity(); } #endif @@ -281,37 +326,37 @@ namespace __debug 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 @@ namespace __debug { 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 @@ namespace __debug 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 @@ namespace __debug 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,29 +448,29 @@ namespace __debug 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 template - typename __gnu_cxx::__enable_if::__value, + typename __gnu_cxx::__enable_if::__value, void>::__type - push_back(_Tp&& __x) + push_back(_Tp&& __x) { emplace_back(std::move(__x)); } template - void - emplace_back(_Args&&... __args) + 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 @@ -439,11 +484,11 @@ namespace __debug #if __cplusplus >= 201103L template - iterator - emplace(const_iterator __position, _Args&&... __args) + iterator + 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 @@ namespace __debug 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,23 +509,23 @@ namespace __debug #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); } #if __cplusplus >= 201103L template - typename __gnu_cxx::__enable_if::__value, + typename __gnu_cxx::__enable_if::__value, iterator>::__type - insert(const_iterator __position, _Tp&& __x) - { return emplace(__position, std::move(__x)); } + insert(const_iterator __position, _Tp&& __x) + { return emplace(__position, std::move(__x)); } iterator insert(const_iterator __position, initializer_list __l) @@ -492,14 +537,14 @@ namespace __debug 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,24 +552,24 @@ namespace __debug 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 #if __cplusplus >= 201103L template> - iterator - insert(const_iterator __position, + iterator + insert(const_iterator __position, _InputIterator __first, _InputIterator __last) - { + { __glibcxx_check_insert_range(__position, __first, __last); /* Hard to guess if invalidation will occur, because __last @@ -540,15 +585,15 @@ namespace __debug 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 template - void - insert(iterator __position, + void + insert(iterator __position, _InputIterator __first, _InputIterator __last) - { + { __glibcxx_check_insert_range(__position, __first, __last); /* Hard to guess if invalidation will occur, because __last @@ -563,7 +608,7 @@ namespace __debug 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 @@ namespace __debug 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 @@ namespace __debug { _Base::clear(); this->_M_invalidate_all(); - _M_guaranteed_capacity = 0; + this->_M_guaranteed_capacity = 0; } _Base& @@ -638,19 +679,6 @@ namespace __debug _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 { diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc index c5dc6fba620..d51cbf69975 100644 --- a/libstdc++-v3/src/c++11/debug.cc +++ b/libstdc++-v3/src/c++11/debug.cc @@ -23,8 +23,8 @@ // . #include -#include -#include +#include +#include #include #include #include @@ -235,7 +235,7 @@ namespace __gnu_debug 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 @@ namespace __gnu_debug _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 @@ namespace __gnu_debug 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; diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc index cc0356a2350..7d91e2585fa 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc @@ -32,9 +32,11 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc index cd19ddff916..08e8dc06c61 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move_assign.cc @@ -46,11 +46,13 @@ void test02() 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() diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct1_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct1_neg.cc new file mode 100644 index 00000000000..241d350806b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct1_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct2_neg.cc new file mode 100644 index 00000000000..05061f2dcd9 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct2_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct3_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct3_neg.cc new file mode 100644 index 00000000000..a3363f7d821 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct3_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct4_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct4_neg.cc new file mode 100644 index 00000000000..24ed6286e3c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/construct4_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc new file mode 100644 index 00000000000..91e459fd3c3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_neg.cc new file mode 100644 index 00000000000..5b65cff6173 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc index 7247de35ed9..496ccebb602 100644 --- a/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc @@ -38,9 +38,13 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc index ce29e1d40a3..3a8f1f1c832 100644 --- a/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc @@ -38,9 +38,11 @@ void test01() 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 @@ void test02() 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() diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/map/debug/construct5_neg.cc new file mode 100644 index 00000000000..bbcf8352a36 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc new file mode 100644 index 00000000000..0d63fe944bf --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/map/debug/move_neg.cc new file mode 100644 index 00000000000..050294f9f08 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc index 5e24475e1ca..f2216bbbb06 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc @@ -38,9 +38,13 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc index 119b13058cd..6b1386120ac 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc @@ -52,11 +52,13 @@ void test02() 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() diff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/construct5_neg.cc new file mode 100644 index 00000000000..acb358dd023 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc new file mode 100644 index 00000000000..e514a28dbed --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_neg.cc new file mode 100644 index 00000000000..18393785acd --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc index 8ed3b7d602f..a65b2bb4b68 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc @@ -36,9 +36,13 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc index 3436f4b465c..956f885462c 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc @@ -50,11 +50,13 @@ void test02() 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() diff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/construct5_neg.cc new file mode 100644 index 00000000000..89c4ff27216 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc new file mode 100644 index 00000000000..af879d94dad --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_neg.cc new file mode 100644 index 00000000000..2dab9a791e5 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc index 2427b4baf26..09bcd719321 100644 --- a/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc @@ -38,9 +38,13 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc index 1100aac3daa..416e0b44315 100644 --- a/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc @@ -50,11 +50,13 @@ void test02() 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() diff --git a/libstdc++-v3/testsuite/23_containers/set/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/set/debug/construct5_neg.cc new file mode 100644 index 00000000000..c30066ad3dc --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc new file mode 100644 index 00000000000..b7f51efd393 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/set/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/set/debug/move_neg.cc new file mode 100644 index 00000000000..2bbebe77e2c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc index 8b573941078..534d9f82bc8 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc @@ -45,9 +45,11 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc index eff287d13f6..0e54a231e3c 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc @@ -66,6 +66,8 @@ void test02() 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 @@ void test02() VERIFY( counter_type::move_assign_count == 0 ); VERIFY( counter_type::destructor_count == 2 ); + + VERIFY( it == v2.begin() ); } int main() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/construct5_neg.cc new file mode 100644 index 00000000000..312b775e356 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc new file mode 100644 index 00000000000..ef5db1165f3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_neg.cc new file mode 100644 index 00000000000..97c1d4f306a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc index b1f92b6494e..b8685d4e403 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc @@ -45,9 +45,11 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move_assign.cc index 815ffdd905c..5d71b38dacc 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move_assign.cc @@ -66,6 +66,8 @@ void test02() 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 @@ void test02() VERIFY( counter_type::move_assign_count == 0 ); VERIFY( counter_type::destructor_count == 2 ); + + VERIFY( it == v2.begin() ); } int main() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc new file mode 100644 index 00000000000..90a578996ec --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc new file mode 100644 index 00000000000..b6de1eef581 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_neg.cc new file mode 100644 index 00000000000..0a1c6391aac --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc index 44c45fde37b..f935f961413 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc @@ -44,9 +44,11 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move_assign.cc index 8db50560d5a..769d01fcb35 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move_assign.cc @@ -63,6 +63,8 @@ void test02() 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 @@ void test02() VERIFY( counter_type::move_count == 0 ); VERIFY( counter_type::copy_count == 0 ); VERIFY( counter_type::destructor_count == 1 ); + + VERIFY( it == v2.begin() ); } int main() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc new file mode 100644 index 00000000000..1a1f709ccb6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc new file mode 100644 index 00000000000..52a8df2a9f2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_neg.cc new file mode 100644 index 00000000000..d8177c9354c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc index d24df74526d..fbaa522cb23 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc @@ -44,9 +44,11 @@ void test01() 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() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move_assign.cc index 321be008482..dd51e5cdd73 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move_assign.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move_assign.cc @@ -63,6 +63,8 @@ void test02() 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 @@ void test02() VERIFY( counter_type::move_count == 0 ); VERIFY( counter_type::copy_count == 0 ); VERIFY( counter_type::destructor_count == 1 ); + + VERIFY( it == v2.begin() ); } int main() diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/construct5_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/construct5_neg.cc new file mode 100644 index 00000000000..db7eb3cc7ce --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/construct5_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc new file mode 100644 index 00000000000..9d2a8abc425 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_neg.cc new file mode 100644 index 00000000000..af91b0c14ce --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/move_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/move_neg.cc new file mode 100644 index 00000000000..f2e6c618716 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/move_neg.cc @@ -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; +} diff --git a/libstdc++-v3/testsuite/util/debug/checks.h b/libstdc++-v3/testsuite/util/debug/checks.h index f7f5ccc4898..af63c8c17d9 100644 --- a/libstdc++-v3/testsuite/util/debug/checks.h +++ b/libstdc++-v3/testsuite/util/debug/checks.h @@ -179,10 +179,8 @@ namespace __gnu_test 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 @@ namespace __gnu_test 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 @@ namespace __gnu_test 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