summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-25 20:53:39 +0000
committerfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-25 20:53:39 +0000
commit8e9bca591d9307979fde531663fb4d34da242aae (patch)
tree655bd05d685adc6a2c1cc45fb794a00e1ae25b76 /libstdc++-v3/include
parent39bf7c517034933b46170285a64bafbd95cf0861 (diff)
downloadgcc-8e9bca591d9307979fde531663fb4d34da242aae.tar.gz
2010-11-25 François Dumont <francois.cppdevs@free.fr>
* src/debug.cc: Introduce a mutex pool in get_safe_base_mutex. Move code used to manipulate sequence safe iterators from safe iterator methods to safe sequence ones. Remove usage of safe iterator mutex, keep _Safe_iterator_base::_M_get_mutex for library backward binary compatibility. * src/Makefile.am: Build debug.cc in gnu++0x mode for _Hash_impl usage. * src/Makefile.in: Regenerate * include/debug/safe_base.h: Add _Safe_iterator_base _M_invalidate and _M_reset. Add _Safe_sequence_base _M_attach, _M_attach_single, _M_detach and _M_detach_single. * include/debug.safe_iterator.h, safe_iterator.tcc: Remove _Safe_iterator _M_invalidate and _M_invalidate_single. Implement all methods in terms of normal iterators rather than safe ones. * include/debug/safe_sequence.h: Replace _Safe_sequence _M_transfe_iter with _M_transfer_from_if taking the source sequence and a predicate signaling when a safe iterator shall be transfered. Add _Equal_to predicate. * include/debug/safe_sequence.tcc: New. * include/Makefile.am: Adjust. * include/Makefile.in: Regenerate. * include/debug/forward_list: Swap safe iterators in move constructor. Do not invalidate before begin in _M_invalidate_all method. Reimplement safe methods using normal iterators rather than safe ones. * include/debug/set.h, unordered_map, multiset.h, vector, unordered_set, deque, map.h, list, multimap.h: Reimplement safe method using normal iterators rather than safe ones. * testsuite/23_containers/forward_list/debug/clear.cc, swap.cc, move_constructor.cc, splice_after.cc, splice_after1.cc, splice_after2.cc, splice_after3.cc, splice_after4.cc: New. * testsuite/23_containers/vector/debug/multithreaded_swap.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167152 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/debug/deque67
-rw-r--r--libstdc++-v3/include/debug/forward_list208
-rw-r--r--libstdc++-v3/include/debug/list129
-rw-r--r--libstdc++-v3/include/debug/map.h51
-rw-r--r--libstdc++-v3/include/debug/multimap.h67
-rw-r--r--libstdc++-v3/include/debug/multiset.h69
-rw-r--r--libstdc++-v3/include/debug/safe_base.h25
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.h38
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.tcc57
-rw-r--r--libstdc++-v3/include/debug/safe_sequence.h100
-rw-r--r--libstdc++-v3/include/debug/safe_sequence.tcc150
-rw-r--r--libstdc++-v3/include/debug/set.h59
-rw-r--r--libstdc++-v3/include/debug/unordered_map108
-rw-r--r--libstdc++-v3/include/debug/unordered_set82
-rw-r--r--libstdc++-v3/include/debug/vector61
17 files changed, 734 insertions, 539 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 3fb1876fb47..6587179a4ef 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -708,6 +708,7 @@ debug_headers = \
${debug_srcdir}/safe_iterator.h \
${debug_srcdir}/safe_iterator.tcc \
${debug_srcdir}/safe_sequence.h \
+ ${debug_srcdir}/safe_sequence.tcc \
${debug_srcdir}/set \
${debug_srcdir}/set.h \
${debug_srcdir}/string \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 82cdd922049..7ed93210258 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -941,6 +941,7 @@ debug_headers = \
${debug_srcdir}/safe_iterator.h \
${debug_srcdir}/safe_iterator.tcc \
${debug_srcdir}/safe_sequence.h \
+ ${debug_srcdir}/safe_sequence.tcc \
${debug_srcdir}/set \
${debug_srcdir}/set.h \
${debug_srcdir}/string \
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index 9c21598ea67..cf63c3af090 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -47,14 +47,17 @@ namespace __debug
typedef _GLIBCXX_STD_D::deque<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ typedef typename _Base::iterator _Base_iterator;
+ typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public:
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque>
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,deque>
iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque>
- const_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;
@@ -219,6 +222,15 @@ namespace __debug
{ return const_reverse_iterator(begin()); }
#endif
+ private:
+ void
+ _M_invalidate_after_nth(difference_type __n)
+ {
+ 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;
using _Base::max_size;
@@ -227,12 +239,9 @@ namespace __debug
void
resize(size_type __sz)
{
- typedef typename _Base::const_iterator _Base_const_iterator;
- typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
-
bool __invalidate_all = __sz > this->size();
if (__sz < this->size())
- this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+ this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz);
@@ -243,12 +252,9 @@ namespace __debug
void
resize(size_type __sz, const _Tp& __c)
{
- typedef typename _Base::const_iterator _Base_const_iterator;
- typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
-
bool __invalidate_all = __sz > this->size();
if (__sz < this->size())
- this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+ this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c);
@@ -259,12 +265,9 @@ namespace __debug
void
resize(size_type __sz, _Tp __c = _Tp())
{
- typedef typename _Base::const_iterator _Base_const_iterator;
- typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
-
bool __invalidate_all = __sz > this->size();
if (__sz < this->size())
- this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+ this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c);
@@ -369,8 +372,8 @@ namespace __debug
emplace(iterator __position, _Args&&... __args)
{
__glibcxx_check_insert(__position);
- typename _Base::iterator __res = _Base::emplace(__position.base(),
- std::forward<_Args>(__args)...);
+ _Base_iterator __res = _Base::emplace(__position.base(),
+ std::forward<_Args>(__args)...);
this->_M_invalidate_all();
return iterator(__res, this);
}
@@ -380,7 +383,7 @@ namespace __debug
insert(iterator __position, const _Tp& __x)
{
__glibcxx_check_insert(__position);
- typename _Base::iterator __res = _Base::insert(__position.base(), __x);
+ _Base_iterator __res = _Base::insert(__position.base(), __x);
this->_M_invalidate_all();
return iterator(__res, this);
}
@@ -421,8 +424,7 @@ namespace __debug
pop_front()
{
__glibcxx_check_nonempty();
- iterator __victim = begin();
- __victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(_Base::begin()));
_Base::pop_front();
}
@@ -430,9 +432,7 @@ namespace __debug
pop_back()
{
__glibcxx_check_nonempty();
- iterator __victim = end();
- --__victim;
- __victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(--_Base::end()));
_Base::pop_back();
}
@@ -440,14 +440,15 @@ namespace __debug
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- if (__position == begin() || __position == end()-1)
+ _Base_iterator __victim = __position.base();
+ if (__victim == _Base::begin() || __victim == _Base::end()-1)
{
- __position._M_invalidate();
- return iterator(_Base::erase(__position.base()), this);
+ this->_M_invalidate_if(_Equal(__victim));
+ return iterator(_Base::erase(__victim), this);
}
else
{
- typename _Base::iterator __res = _Base::erase(__position.base());
+ _Base_iterator __res = _Base::erase(__victim);
this->_M_invalidate_all();
return iterator(__res, this);
}
@@ -459,13 +460,13 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- if (__first == begin() || __last == end())
+ if (__first.base() == _Base::begin() || __last.base() == _Base::end())
{
this->_M_detach_singular();
- for (iterator __position = __first; __position != __last; )
+ for (_Base_iterator __position = __first.base();
+ __position != __last.base(); ++__position)
{
- iterator __victim = __position++;
- __victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position));
}
__try
{
@@ -480,8 +481,8 @@ namespace __debug
}
else
{
- typename _Base::iterator __res = _Base::erase(__first.base(),
- __last.base());
+ _Base_iterator __res = _Base::erase(__first.base(),
+ __last.base());
this->_M_invalidate_all();
return iterator(__res, this);
}
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index 6869269eacb..03b661ec221 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -48,13 +48,15 @@ namespace __debug
typedef _GLIBCXX_STD_D::forward_list<_Tp, _Alloc> _Base;
typedef __gnu_debug::_Safe_sequence<forward_list> _Safe_base;
+ 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 __gnu_debug::_Safe_iterator<typename _Base::iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,
forward_list> iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
forward_list> const_iterator;
typedef typename _Base::size_type size_type;
@@ -75,7 +77,7 @@ namespace __debug
{ }
forward_list(forward_list&& __list, const _Alloc& __al)
- : _Base(std::move(__list), __al)
+ : _Base(std::move(__list._M_base()), __al)
{
this->_M_swap(__list);
}
@@ -103,7 +105,10 @@ namespace __debug
{ }
forward_list(forward_list&& __list)
- : _Base(std::move(__list)) { }
+ : _Base(std::move(__list._M_base()))
+ {
+ this->_M_swap(__list);
+ }
forward_list(std::initializer_list<_Tp> __il,
const _Alloc& __al = _Alloc())
@@ -231,8 +236,8 @@ namespace __debug
pop_front()
{
__glibcxx_check_nonempty();
- iterator __victim = begin();
- __victim._M_invalidate();
+ this->_M_invalidate_if([this](_Base_const_iterator __it)
+ { return __it == this->_M_base().cbegin(); });
_Base::pop_front();
}
@@ -288,25 +293,37 @@ namespace __debug
return iterator(_Base::insert_after(__pos.base(), __il), this);
}
+ private:
+ _Base_iterator
+ _M_erase_after(_Base_const_iterator __pos)
+ {
+ _Base_const_iterator __next = std::next(__pos);
+ this->_M_invalidate_if([__next](_Base_const_iterator __it)
+ { return __it == __next; });
+ return _Base::erase_after(__pos);
+ }
+ public:
iterator
erase_after(const_iterator __pos)
{
__glibcxx_check_erase_after(__pos);
- const_iterator __victim = __pos;
- ++__victim;
- __victim._M_invalidate();
- return iterator(_Base::erase_after(__pos.base()), this);
+ return iterator(_M_erase_after(__pos.base()), this);
}
iterator
erase_after(const_iterator __pos, const_iterator __last)
{
__glibcxx_check_erase_range_after(__pos, __last);
- for (const_iterator __victim = std::next(__pos); __victim != __last; )
+ for (_Base_const_iterator __victim = std::next(__pos.base());
+ __victim != __last.base(); ++__victim)
{
- const_iterator __old = __victim;
- ++__victim;
- __old._M_invalidate();
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range2)
+ ._M_sequence(*this, "this")
+ ._M_iterator(__pos, "pos")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if([__victim](_Base_const_iterator __it)
+ { return __it == __victim; });
}
return iterator(_Base::erase_after(__pos.base(), __last.base()), this);
}
@@ -324,15 +341,15 @@ namespace __debug
this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end()
- iterator __victim = begin();
- iterator __end = end();
+ _Base_iterator __victim = _Base::begin();
+ _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
- while (__victim != __end)
+ for (; __victim != __end; ++__victim)
{
- iterator __real_victim = __victim++;
- __real_victim._M_invalidate();
+ this->_M_invalidate_if([__victim](_Base_const_iterator __it)
+ { return __it == __victim; });
}
__try
@@ -352,15 +369,15 @@ namespace __debug
this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
- iterator __victim = begin();
- iterator __end = end();
+ _Base_iterator __victim = _Base::begin();
+ _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
- while (__victim != __end)
+ for (; __victim != __end; ++__victim)
{
- iterator __real_victim = __victim++;
- __real_victim._M_invalidate();
+ this->_M_invalidate_if([__victim](_Base_const_iterator __it)
+ { return __it == __victim; });
}
__try
@@ -382,29 +399,6 @@ namespace __debug
}
// 23.2.3.5 forward_list operations:
- private:
- void
- _M_splice_after(const_iterator __pos, forward_list&& __list,
- const_iterator __before, const_iterator __last)
- {
- for (const_iterator __tmp = std::next(__before); __tmp != __last; )
- {
- _GLIBCXX_DEBUG_VERIFY(&__list != this || __tmp != __pos,
- _M_message(__gnu_debug::__msg_splice_overlap)
- ._M_iterator(__tmp, "position")
- ._M_iterator(__before, "before")
- ._M_iterator(__last, "last"));
- const_iterator __victim = __tmp++;
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 250. splicing invalidates iterators
- this->_M_transfer_iter(__victim);
- }
-
- _Base::splice_after(__pos.base(), std::move(__list._M_base()),
- __before.base(), __last.base());
- }
-
- public:
void
splice_after(const_iterator __pos, forward_list&& __list)
{
@@ -412,8 +406,12 @@ namespace __debug
_GLIBCXX_DEBUG_VERIFY(&__list != this,
_M_message(__gnu_debug::__msg_self_splice)
._M_sequence(*this, "this"));
- _M_splice_after(__pos, std::move(__list),
- __list.before_begin(), __list.end());
+ this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
+ {
+ return __it != __list._M_base().cbefore_begin()
+ && __it != __list._M_base().end();
+ });
+ _Base::splice_after(__pos.base(), std::move(__list._M_base()));
}
void
@@ -431,7 +429,9 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 250. splicing invalidates iterators
- this->_M_transfer_iter(__i);
+ _Base_const_iterator __next = std::next(__i.base());
+ this->_M_transfer_from_if(__list, [__next](_Base_const_iterator __it)
+ { return __it == __next; });
_Base::splice_after(__pos.base(), std::move(__list._M_base()),
__i.base());
}
@@ -457,21 +457,39 @@ namespace __debug
._M_sequence(__list, "list")
._M_iterator(__before, "before")
._M_iterator(__last, "last"));
- _M_splice_after(__pos, std::move(__list), __before, __last);
+
+ for (_Base_const_iterator __tmp = std::next(__before.base());
+ __tmp != __last.base(); ++__tmp)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(),
+ _M_message(__gnu_debug::__msg_valid_range2)
+ ._M_sequence(__list, "list")
+ ._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_iterator(__before, "before")
+ ._M_iterator(__last, "last"));
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 250. splicing invalidates iterators
+ this->_M_transfer_from_if(__list, [__tmp](_Base_const_iterator __it)
+ { return __it == __tmp; });
+ }
+
+ _Base::splice_after(__pos.base(), std::move(__list._M_base()),
+ __before.base(), __last.base());
}
void
remove(const _Tp& __val)
{
- iterator __x = before_begin();
- iterator __old = __x++;
- while (__x.base() != _Base::end())
+ _Base_iterator __x = _Base::before_begin();
+ _Base_iterator __old = __x++;
+ while (__x != _Base::end())
{
if (*__x == __val)
- {
- erase_after(__old);
- __x = __old; ++__x;
- }
+ __x = _M_erase_after(__old);
else
__old = __x++;
}
@@ -481,15 +499,12 @@ namespace __debug
void
remove_if(_Pred __pred)
{
- iterator __x = before_begin();
- iterator __old = __x++;
- while (__x.base() != _Base::end())
+ _Base_iterator __x = _Base::before_begin();
+ _Base_iterator __old = __x++;
+ while (__x != _Base::end())
{
if (__pred(*__x))
- {
- erase_after(__old);
- __x = std::next(__old);
- }
+ __x = _M_erase_after(__old);
else
__old = __x++;
}
@@ -498,20 +513,17 @@ namespace __debug
void
unique()
{
- iterator __first = begin();
- iterator __last = end();
+ _Base_iterator __first = _Base::begin();
+ _Base_iterator __last = _Base::end();
if (__first == __last)
return;
- iterator __next = __first;
- while (++__next != __last)
+ _Base_iterator __next = std::next(__first);
+ while (__next != __last)
{
if (*__first == *__next)
- {
- erase_after(__first);
- __next = __first;
- }
+ __next = _M_erase_after(__first);
else
- __first = __next;
+ __first = __next++;
}
}
@@ -519,20 +531,17 @@ namespace __debug
void
unique(_BinPred __binary_pred)
{
- iterator __first = begin();
- iterator __last = end();
+ _Base_iterator __first = _Base::begin();
+ _Base_iterator __last = _Base::end();
if (__first == __last)
return;
- iterator __next = __first;
- while (++__next != __last)
+ _Base_iterator __next = std::next(__first);
+ while (__next != __last)
{
if (__binary_pred(*__first, *__next))
- {
- erase_after(__first);
- __next = __first;
- }
+ __next = _M_erase_after(__first);
else
- __first = __next;
+ __first = __next++;
}
}
@@ -544,11 +553,11 @@ namespace __debug
__glibcxx_check_sorted(_Base::begin(), _Base::end());
__glibcxx_check_sorted(__list._M_base().begin(),
__list._M_base().end());
- for (iterator __tmp = __list.begin(); __tmp != __list.end();)
+ this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
{
- iterator __victim = __tmp++;
- this->_M_transfer_iter(__victim);
- }
+ return __it != __list._M_base().cbefore_begin()
+ && __it != __list._M_base().cend();
+ });
_Base::merge(std::move(__list._M_base()));
}
}
@@ -562,11 +571,12 @@ namespace __debug
__glibcxx_check_sorted_pred(_Base::begin(), _Base::end(), __comp);
__glibcxx_check_sorted_pred(__list._M_base().begin(),
__list._M_base().end(), __comp);
- for (iterator __tmp = __list.begin(); __tmp != __list.end();)
+ this->_M_transfer_from_if(__list,
+ [&__list](_Base_const_iterator __it)
{
- iterator __victim = __tmp++;
- this->_M_transfer_iter(__victim);
- }
+ return __it != __list._M_base().cbefore_begin()
+ && __it != __list._M_base().cend();
+ });
_Base::merge(std::move(__list._M_base()), __comp);
}
}
@@ -584,9 +594,11 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
- typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if([this](_Base_const_iterator __it)
+ {
+ return __it != this->_M_base().cbefore_begin()
+ && __it != this->_M_base().cend();
+ });
}
};
@@ -644,11 +656,13 @@ namespace __gnu_debug
template<class _Tp, class _Alloc>
struct _BeforeBeginHelper<std::__debug::forward_list<_Tp, _Alloc> >
{
- typedef typename forward_list<_Tp, _Alloc>::const_iterator _It;
+ typedef std::__debug::forward_list<_Tp, _Alloc> _Sequence;
+ typedef typename _Sequence::const_iterator _It;
+ typedef typename _It::iterator_type _BaseIt;
static bool
- _M_Is(_It __it, const forward_list<_Tp, _Alloc>* __seq)
- { return __it == __seq->before_begin(); }
+ _M_Is(_BaseIt __it, const _Sequence* __seq)
+ { return __it == __seq->_M_base().cbefore_begin(); }
};
}
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index b6567846e9b..54b736c8a9c 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -47,13 +47,17 @@ namespace __debug
typedef _GLIBCXX_STD_D::list<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<list> _Safe_base;
+ 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 __gnu_debug::_Safe_iterator<typename _Base::iterator, list>
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator, list>
iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, list>
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, list>
const_iterator;
typedef typename _Base::size_type size_type;
@@ -230,15 +234,14 @@ namespace __debug
this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
- iterator __victim = begin();
- iterator __end = end();
+ _Base_iterator __victim = _Base::begin();
+ _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
- while (__victim != __end)
+ for (; __victim != __end; ++__victim)
{
- iterator __real_victim = __victim++;
- __real_victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(__victim));
}
__try
@@ -258,15 +261,14 @@ namespace __debug
this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
- iterator __victim = begin();
- iterator __end = end();
+ _Base_iterator __victim = _Base::begin();
+ _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
- while (__victim != __end)
+ for (; __victim != __end; ++__victim)
{
- iterator __real_victim = __victim++;
- __real_victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(__victim));
}
__try
@@ -286,15 +288,14 @@ namespace __debug
this->_M_detach_singular();
// if __sz < size(), invalidate all iterators in [begin+__sz, end())
- iterator __victim = begin();
- iterator __end = end();
+ _Base_iterator __victim = _Base::begin();
+ _Base_iterator __end = _Base::end();
for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
++__victim;
- while (__victim != __end)
+ for (; __victim != __end; ++__victim)
{
- iterator __real_victim = __victim++;
- __real_victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(__victim));
}
__try
@@ -349,8 +350,7 @@ namespace __debug
pop_front()
{
__glibcxx_check_nonempty();
- iterator __victim = begin();
- __victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(_Base::begin()));
_Base::pop_front();
}
@@ -364,9 +364,7 @@ namespace __debug
pop_back()
{
__glibcxx_check_nonempty();
- iterator __victim = end();
- --__victim;
- __victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(--_Base::end()));
_Base::pop_back();
}
@@ -418,12 +416,19 @@ namespace __debug
__gnu_debug::__base(__last));
}
+ private:
+ _Base_iterator
+ _M_erase(_Base_iterator __position)
+ {
+ this->_M_invalidate_if(_Equal(__position));
+ return _Base::erase(__position);
+ }
+ public:
iterator
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
- return iterator(_Base::erase(__position.base()), this);
+ return iterator(_M_erase(__position.base()), this);
}
iterator
@@ -432,11 +437,14 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__position, __last);
- for (iterator __victim = __position; __victim != __last; )
+ for (_Base_iterator __victim = __position.base();
+ __victim != __last.base(); ++__victim)
{
- iterator __old = __victim;
- ++__victim;
- __old._M_invalidate();
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__position, "position")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
}
return iterator(_Base::erase(__position.base(), __last.base()), this);
}
@@ -466,7 +474,8 @@ namespace __debug
_GLIBCXX_DEBUG_VERIFY(&__x != this,
_M_message(__gnu_debug::__msg_self_splice)
._M_sequence(*this, "this"));
- this->splice(__position, _GLIBCXX_MOVE(__x), __x.begin(), __x.end());
+ this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
+ _Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()));
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -496,7 +505,7 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 250. splicing invalidates iterators
- this->_M_transfer_iter(__i);
+ this->_M_transfer_from_if(__x, _Equal(__i.base()));
_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
__i.base());
}
@@ -526,17 +535,21 @@ namespace __debug
// We used to perform the splice_alloc check: not anymore, redundant
// after implementing the relevant bits of N1599.
- for (iterator __tmp = __first; __tmp != __last; )
+ for (_Base_iterator __tmp = __first.base();
+ __tmp != __last.base(); ++__tmp)
{
+ _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
_GLIBCXX_DEBUG_VERIFY(&__x != this || __tmp != __position,
_M_message(__gnu_debug::__msg_splice_overlap)
._M_iterator(__tmp, "position")
._M_iterator(__first, "first")
._M_iterator(__last, "last"));
- iterator __victim = __tmp++;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 250. splicing invalidates iterators
- this->_M_transfer_iter(__victim);
+ this->_M_transfer_from_if(__x, _Equal(__tmp));
}
_Base::splice(__position.base(), _GLIBCXX_MOVE(__x._M_base()),
@@ -552,10 +565,10 @@ namespace __debug
void
remove(const _Tp& __value)
{
- for (iterator __x = begin(); __x.base() != _Base::end(); )
+ for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
{
if (*__x == __value)
- __x = erase(__x);
+ __x = _M_erase(__x);
else
++__x;
}
@@ -565,10 +578,10 @@ namespace __debug
void
remove_if(_Predicate __pred)
{
- for (iterator __x = begin(); __x.base() != _Base::end(); )
+ for (_Base_iterator __x = _Base::begin(); __x != _Base::end(); )
{
if (__pred(*__x))
- __x = erase(__x);
+ __x = _M_erase(__x);
else
++__x;
}
@@ -577,18 +590,17 @@ namespace __debug
void
unique()
{
- iterator __first = begin();
- iterator __last = end();
+ _Base_iterator __first = _Base::begin();
+ _Base_iterator __last = _Base::end();
if (__first == __last)
return;
- iterator __next = __first;
- while (++__next != __last)
+ _Base_iterator __next = __first; ++__next;
+ while (__next != __last)
{
if (*__first == *__next)
- erase(__next);
+ __next = _M_erase(__next);
else
- __first = __next;
- __next = __first;
+ __first = __next++;
}
}
@@ -596,18 +608,17 @@ namespace __debug
void
unique(_BinaryPredicate __binary_pred)
{
- iterator __first = begin();
- iterator __last = end();
+ _Base_iterator __first = _Base::begin();
+ _Base_iterator __last = _Base::end();
if (__first == __last)
return;
- iterator __next = __first;
- while (++__next != __last)
+ _Base_iterator __next = __first; ++__next;
+ while (__next != __last)
{
if (__binary_pred(*__first, *__next))
- erase(__next);
+ __next = _M_erase(__next);
else
- __first = __next;
- __next = __first;
+ __first = __next++;
}
}
@@ -624,11 +635,7 @@ namespace __debug
{
__glibcxx_check_sorted(_Base::begin(), _Base::end());
__glibcxx_check_sorted(__x.begin().base(), __x.end().base());
- for (iterator __tmp = __x.begin(); __tmp != __x.end();)
- {
- iterator __victim = __tmp++;
- this->_M_transfer_iter(__victim);
- }
+ this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
_Base::merge(_GLIBCXX_MOVE(__x._M_base()));
}
}
@@ -655,11 +662,7 @@ namespace __debug
__comp);
__glibcxx_check_sorted_pred(__x.begin().base(), __x.end().base(),
__comp);
- for (iterator __tmp = __x.begin(); __tmp != __x.end();)
- {
- iterator __victim = __tmp++;
- this->_M_transfer_iter(__victim);
- }
+ this->_M_transfer_from_if(__x, _Not_equal(__x._M_base().end()));
_Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp);
}
}
@@ -690,9 +693,7 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
- typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index 6e8858c6706..79f9b8287d4 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -48,6 +48,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<map> _Safe_base;
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ typedef typename _Base::iterator _Base_iterator;
+ typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public:
// types:
typedef _Key key_type;
@@ -269,7 +272,7 @@ namespace __debug
erase(const_iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
return iterator(_Base::erase(__position.base()), this);
}
#else
@@ -277,7 +280,7 @@ namespace __debug
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
_Base::erase(__position.base());
}
#endif
@@ -285,15 +288,15 @@ namespace __debug
size_type
erase(const key_type& __x)
{
- iterator __victim = find(__x);
- if (__victim == end())
+ _Base_iterator __victim = _Base::find(__x);
+ if (__victim == _Base::end())
return 0;
else
- {
- __victim._M_invalidate();
- _Base::erase(__victim.base());
- return 1;
- }
+ {
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim);
+ return 1;
+ }
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -303,9 +306,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
- return iterator(__last.base()._M_const_cast(), this);
+ for (_Base_const_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ return iterator(_Base::erase(__first.base(), __last.base()), this);
}
#else
void
@@ -314,8 +324,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
+ for (_Base_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ _Base::erase(__first.base(), __last.base());
}
#endif
@@ -328,7 +346,10 @@ namespace __debug
void
clear()
- { this->erase(begin(), end()); }
+ {
+ this->_M_invalidate_all();
+ _Base::clear();
+ }
// observers:
using _Base::key_comp;
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 56f58ffce3b..58673cc7adf 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -49,6 +49,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ typedef typename _Base::iterator _Base_iterator;
+ typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public:
// types:
typedef _Key key_type;
@@ -59,9 +62,9 @@ namespace __debug
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap>
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator, multimap>
iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
multimap> const_iterator;
typedef typename _Base::size_type size_type;
@@ -216,7 +219,7 @@ namespace __debug
#ifdef __GXX_EXPERIMENTAL_CXX0X__
insert(const_iterator __position, const value_type& __x)
#else
- insert(iterator __position, const value_type& __x)
+ insert(iterator __position, const value_type& __x)
#endif
{
__glibcxx_check_insert(__position);
@@ -250,7 +253,7 @@ namespace __debug
erase(const_iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
return iterator(_Base::erase(__position.base()), this);
}
#else
@@ -258,7 +261,7 @@ namespace __debug
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
_Base::erase(__position.base());
}
#endif
@@ -266,15 +269,16 @@ namespace __debug
size_type
erase(const key_type& __x)
{
- std::pair<iterator, iterator> __victims = this->equal_range(__x);
+ std::pair<_Base_iterator, _Base_iterator> __victims =
+ _Base::equal_range(__x);
size_type __count = 0;
- while (__victims.first != __victims.second)
- {
- iterator __victim = __victims.first++;
- __victim._M_invalidate();
- _Base::erase(__victim.base());
- ++__count;
- }
+ _Base_iterator __victim = __victims.first;
+ while (__victim != __victims.second)
+ {
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim++);
+ ++__count;
+ }
return __count;
}
@@ -285,9 +289,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
- return iterator(__last.base()._M_const_cast(), this);
+ for (_Base_const_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ return iterator(_Base::erase(__first.base(), __last.base()), this);
}
#else
void
@@ -296,8 +307,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
+ for (_Base_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ _Base::erase(__first.base(), __last.base());
}
#endif
@@ -310,7 +329,10 @@ namespace __debug
void
clear()
- { this->erase(begin(), end()); }
+ {
+ this->_M_invalidate_all();
+ _Base::clear();
+ }
// observers:
using _Base::key_comp;
@@ -346,7 +368,6 @@ namespace __debug
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
- typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(iterator(__res.first, this),
@@ -356,9 +377,8 @@ namespace __debug
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
- typedef typename _Base::const_iterator _Base_const_iterator;
std::pair<_Base_const_iterator, _Base_const_iterator> __res =
- _Base::equal_range(__x);
+ _Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
@@ -373,9 +393,8 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 9c950a1d0c2..8462586b844 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -48,6 +48,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::multiset<_Key, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base;
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ typedef typename _Base::iterator _Base_iterator;
+ typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public:
// types:
typedef _Key key_type;
@@ -58,9 +61,9 @@ namespace __debug
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multiset>
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator, multiset>
iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
multiset> const_iterator;
typedef typename _Base::size_type size_type;
@@ -237,7 +240,7 @@ namespace __debug
erase(const_iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
return iterator(_Base::erase(__position.base()), this);
}
#else
@@ -245,7 +248,7 @@ namespace __debug
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
_Base::erase(__position.base());
}
#endif
@@ -253,15 +256,16 @@ namespace __debug
size_type
erase(const key_type& __x)
{
- std::pair<iterator, iterator> __victims = this->equal_range(__x);
+ std::pair<_Base_iterator, _Base_iterator> __victims =
+ _Base::equal_range(__x);
size_type __count = 0;
- while (__victims.first != __victims.second)
- {
- iterator __victim = __victims.first++;
- __victim._M_invalidate();
- _Base::erase(__victim.base());
- ++__count;
- }
+ _Base_iterator __victim = __victims.first;
+ while (__victim != __victims.second)
+ {
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim++);
+ ++__count;
+ }
return __count;
}
@@ -272,9 +276,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
- return __last; // iterator == const_iterator
+ for (_Base_const_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ return iterator(_Base::erase(__first.base(), __last.base()), this);
}
#else
void
@@ -283,8 +294,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
+ for (_Base_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ _Base::erase(__first.base(), __last.base());
}
#endif
@@ -297,7 +316,10 @@ namespace __debug
void
clear()
- { this->erase(begin(), end()); }
+ {
+ this->_M_invalidate_all();
+ _Base::clear();
+ }
// observers:
using _Base::key_comp;
@@ -339,9 +361,8 @@ namespace __debug
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
- typedef typename _Base::iterator _Base_iterator;
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));
}
@@ -351,9 +372,8 @@ namespace __debug
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
- typedef typename _Base::const_iterator _Base_iterator;
- std::pair<_Base_iterator, _Base_iterator> __res =
- _Base::equal_range(__x);
+ std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+ _Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
@@ -368,9 +388,8 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h
index 3e81f9b8a99..2ebdd89b58f 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -137,6 +137,15 @@ namespace __gnu_debug
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 ();
+
+ /** Invalidate the iterator, making it singular. */
+ void
+ _M_invalidate()
+ { _M_version = 0; }
+
+ /** Reset all member variables */
+ void
+ _M_reset() throw ();
};
/**
@@ -214,6 +223,22 @@ namespace __gnu_debug
void
_M_invalidate_all() const
{ if (++_M_version == 0) _M_version = 1; }
+
+ /** Attach an iterator to this sequence. */
+ void
+ _M_attach(_Safe_iterator_base* __it, bool __constant);
+
+ /** Likewise but not thread safe. */
+ void
+ _M_attach_single(_Safe_iterator_base* __it, bool __constant) throw ();
+
+ /** Detach an iterator from this sequence */
+ void
+ _M_detach(_Safe_iterator_base* __it);
+
+ /** Likewise but not thread safe. */
+ void
+ _M_detach_single(_Safe_iterator_base* __it) throw ();
};
} // namespace __gnu_debug
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index 4bcca092826..733a2c6a0a7 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -47,9 +47,10 @@ namespace __gnu_debug
struct _BeforeBeginHelper
{
typedef typename _Sequence::const_iterator _It;
+ typedef typename _It::iterator_type _BaseIt;
static bool
- _M_Is(_It __it, const _Sequence* __seq)
+ _M_Is(_BaseIt __it, const _Sequence* __seq)
{ return false; }
};
@@ -176,7 +177,7 @@ namespace __gnu_debug
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
_M_current = __x._M_current;
- this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
+ this->_M_attach(__x._M_sequence);
return *this;
}
@@ -331,28 +332,18 @@ namespace __gnu_debug
/** Attach iterator to the given sequence. */
void
- _M_attach(const _Sequence* __seq)
+ _M_attach(_Safe_sequence_base* __seq)
{
- _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
- _M_constant());
+ _Safe_iterator_base::_M_attach(__seq, _M_constant());
}
/** Likewise, but not thread-safe. */
void
- _M_attach_single(const _Sequence* __seq)
+ _M_attach_single(_Safe_sequence_base* __seq)
{
- _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq),
- _M_constant());
+ _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
}
- /** Invalidate the iterator, making it singular. */
- void
- _M_invalidate();
-
- /** Likewise, but not thread-safe. */
- void
- _M_invalidate_single();
-
/// Is the iterator dereferenceable?
bool
_M_dereferenceable() const
@@ -405,31 +396,26 @@ namespace __gnu_debug
static std::pair<difference_type, _Distance_precision>
_M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
std::random_access_iterator_tag)
- {
- return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
- }
+ { return std::make_pair(__rhs - __lhs, __dp_exact); }
template<typename _Iterator1, typename _Iterator2>
static std::pair<difference_type, _Distance_precision>
_M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
std::forward_iterator_tag)
- {
- return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
- __dp_equality);
- }
+ { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
/// Is this iterator equal to the sequence's begin() iterator?
bool _M_is_begin() const
- { return *this == _M_get_sequence()->begin(); }
+ { return base() == _M_get_sequence()->_M_base().begin(); }
/// Is this iterator equal to the sequence's end() iterator?
bool _M_is_end() const
- { return *this == _M_get_sequence()->end(); }
+ { return base() == _M_get_sequence()->_M_base().end(); }
/// Is this iterator equal to the sequence's before_begin() iterator if
/// any?
bool _M_is_before_begin() const
- { return _BeforeBeginHelper<_Sequence>::_M_Is(*this, _M_get_sequence()); }
+ { return _BeforeBeginHelper<_Sequence>::_M_Is(base(), _M_get_sequence()); }
};
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc
index d4f2aee584b..fe93c95c59f 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -37,7 +37,8 @@ namespace __gnu_debug
_Safe_iterator<_Iterator, _Sequence>::
_M_can_advance(const difference_type& __n) const
{
- typedef typename _Sequence::const_iterator const_iterator;
+ typedef typename _Sequence::const_iterator const_debug_iterator;
+ typedef typename const_debug_iterator::iterator_type const_iterator;
if (this->_M_singular())
return false;
@@ -45,20 +46,18 @@ namespace __gnu_debug
return true;
if (__n < 0)
{
- const_iterator __begin =
- static_cast<const _Sequence*>(_M_sequence)->begin();
+ const_iterator __begin = _M_get_sequence()->_M_base().begin();
std::pair<difference_type, _Distance_precision> __dist =
- this->_M_get_distance(__begin, *this);
+ this->_M_get_distance(__begin, base());
bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n)
|| (__dist.second != __dp_exact && __dist.first > 0));
return __ok;
}
else
{
- const_iterator __end =
- static_cast<const _Sequence*>(_M_sequence)->end();
+ const_iterator __end = _M_get_sequence()->_M_base().end();
std::pair<difference_type, _Distance_precision> __dist =
- this->_M_get_distance(*this, __end);
+ this->_M_get_distance(base(), __end);
bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n)
|| (__dist.second != __dp_exact && __dist.first > 0));
return __ok;
@@ -77,7 +76,7 @@ namespace __gnu_debug
/* Determine if we can order the iterators without the help of
the container */
std::pair<difference_type, _Distance_precision> __dist =
- this->_M_get_distance(*this, __rhs);
+ this->_M_get_distance(base(), __rhs.base());
switch (__dist.second) {
case __dp_equality:
if (__dist.first == 0)
@@ -91,52 +90,16 @@ namespace __gnu_debug
/* We can only test for equality, but check if one of the
iterators is at an extreme. */
+ /* Optim for classic [begin, it) or [it, end) ranges, limit checks
+ * when code is valid. */
if (_M_is_begin() || __rhs._M_is_end())
return true;
- else if (_M_is_end() || __rhs._M_is_begin())
+ if (_M_is_end() || __rhs._M_is_begin())
return false;
// Assume that this is a valid range; we can't check anything else
return true;
}
-
- template<typename _Iterator, typename _Sequence>
- void
- _Safe_iterator<_Iterator, _Sequence>::
- _M_invalidate()
- {
- __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
- _M_invalidate_single();
- }
-
- template<typename _Iterator, typename _Sequence>
- void
- _Safe_iterator<_Iterator, _Sequence>::
- _M_invalidate_single()
- {
- typedef typename _Sequence::iterator iterator;
- typedef typename _Sequence::const_iterator const_iterator;
-
- if (!this->_M_singular())
- {
- for (_Safe_iterator_base* __iter = _M_sequence->_M_iterators;
- __iter; __iter = __iter->_M_next)
- {
- iterator* __victim = static_cast<iterator*>(__iter);
- if (this->base() == __victim->base())
- __victim->_M_version = 0;
- }
-
- for (_Safe_iterator_base* __iter2 = _M_sequence->_M_const_iterators;
- __iter2; __iter2 = __iter2->_M_next)
- {
- const_iterator* __victim = static_cast<const_iterator*>(__iter2);
- if (__victim->base() == this->base())
- __victim->_M_version = 0;
- }
- _M_version = 0;
- }
- }
} // namespace __gnu_debug
#endif
diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h
index 830372d78a0..843c9b11710 100644
--- a/libstdc++-v3/include/debug/safe_sequence.h
+++ b/libstdc++-v3/include/debug/safe_sequence.h
@@ -57,6 +57,21 @@ namespace __gnu_debug
{ return __value != __x; }
};
+ /** A simple function object that returns true if the passed-in
+ * value is equal to the stored value. */
+ template <typename _Type>
+ class _Equal_to
+ {
+ _Type __value;
+
+ public:
+ explicit _Equal_to(const _Type& __v) : __value(__v) { }
+
+ bool
+ operator()(const _Type& __x) const
+ { return __value == __x; }
+ };
+
/** A function object that returns true when the given random access
iterator is at least @c n steps away from the given iterator. */
template<typename _Iterator>
@@ -99,85 +114,24 @@ namespace __gnu_debug
public:
/** Invalidates all iterators @c x that reference this sequence,
are not singular, and for which @c pred(x) returns @c
- true. The user of this routine should be careful not to make
- copies of the iterators passed to @p pred, as the copies may
- interfere with the invalidation. */
+ true. @c pred will be invoked with the normal iterators nested
+ in the safe ones. */
template<typename _Predicate>
void
_M_invalidate_if(_Predicate __pred);
- /** Transfers all iterators that reference this memory location
- to this sequence from whatever sequence they are attached
- to. */
- template<typename _Iterator>
+ /** 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<typename _Predicate>
void
- _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x);
+ _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred);
};
-
- template<typename _Sequence>
- template<typename _Predicate>
- void
- _Safe_sequence<_Sequence>::
- _M_invalidate_if(_Predicate __pred)
- {
- 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;)
- {
- iterator* __victim = static_cast<iterator*>(__iter);
- __iter = __iter->_M_next;
- if (!__victim->_M_singular())
- {
- if (__pred(__victim->base()))
- __victim->_M_invalidate_single();
- }
- }
-
- for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
- {
- const_iterator* __victim = static_cast<const_iterator*>(__iter2);
- __iter2 = __iter2->_M_next;
- if (!__victim->_M_singular())
- {
- if (__pred(__victim->base()))
- __victim->_M_invalidate_single();
- }
- }
- }
-
- template<typename _Sequence>
- template<typename _Iterator>
- void
- _Safe_sequence<_Sequence>::
- _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x)
- {
- _Safe_sequence_base* __from = __x._M_sequence;
- if (!__from)
- return;
-
- 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 = __from->_M_iterators; __iter;)
- {
- iterator* __victim = static_cast<iterator*>(__iter);
- __iter = __iter->_M_next;
- if (!__victim->_M_singular() && __victim->base() == __x.base())
- __victim->_M_attach_single(static_cast<_Sequence*>(this));
- }
-
- for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators;
- __iter2;)
- {
- const_iterator* __victim = static_cast<const_iterator*>(__iter2);
- __iter2 = __iter2->_M_next;
- if (!__victim->_M_singular() && __victim->base() == __x.base())
- __victim->_M_attach_single(static_cast<_Sequence*>(this));
- }
- }
} // namespace __gnu_debug
+#ifndef _GLIBCXX_EXPORT_TEMPLATE
+# include <debug/safe_sequence.tcc>
+#endif
+
#endif
diff --git a/libstdc++-v3/include/debug/safe_sequence.tcc b/libstdc++-v3/include/debug/safe_sequence.tcc
new file mode 100644
index 00000000000..bf0295cfd05
--- /dev/null
+++ b/libstdc++-v3/include/debug/safe_sequence.tcc
@@ -0,0 +1,150 @@
+// Safe sequence implementation -*- C++ -*-
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file debug/safe_sequence.tcc
+ * This file is a GNU debug extension to the Standard C++ Library.
+ */
+
+#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_TCC
+#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_TCC 1
+
+namespace __gnu_debug
+{
+ template<typename _Sequence>
+ template<typename _Predicate>
+ void
+ _Safe_sequence<_Sequence>::
+ _M_invalidate_if(_Predicate __pred)
+ {
+ 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;)
+ {
+ iterator* __victim = static_cast<iterator*>(__iter);
+ __iter = __iter->_M_next;
+ if (!__victim->_M_singular() && __pred(__victim->base()))
+ {
+ __victim->_M_invalidate();
+ }
+ }
+
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
+ {
+ const_iterator* __victim = static_cast<const_iterator*>(__iter2);
+ __iter2 = __iter2->_M_next;
+ if (!__victim->_M_singular() && __pred(__victim->base()))
+ {
+ __victim->_M_invalidate();
+ }
+ }
+ }
+
+ template<typename _Sequence>
+ template<typename _Predicate>
+ void
+ _Safe_sequence<_Sequence>::
+ _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred)
+ {
+ 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;
+ _Safe_iterator_base* __last_iterator = 0;
+ _Safe_iterator_base* __last_const_iterator = 0;
+ {
+ // 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;)
+ {
+ iterator* __victim = static_cast<iterator*>(__iter);
+ __iter = __iter->_M_next;
+ if (!__victim->_M_singular() && __pred(__victim->base()))
+ {
+ __victim->_M_detach_single();
+ if (__transfered_iterators)
+ {
+ __victim->_M_next = __transfered_iterators;
+ __transfered_iterators->_M_prior = __victim;
+ }
+ else
+ __last_iterator = __victim;
+ __victim->_M_sequence = this;
+ __victim->_M_version = this->_M_version;
+ __transfered_iterators = __victim;
+ }
+ }
+
+ for (_Safe_iterator_base* __iter2 = __from._M_const_iterators;
+ __iter2;)
+ {
+ const_iterator* __victim = static_cast<const_iterator*>(__iter2);
+ __iter2 = __iter2->_M_next;
+ if (!__victim->_M_singular() && __pred(__victim->base()))
+ {
+ __victim->_M_detach_single();
+ if (__transfered_const_iterators)
+ {
+ __victim->_M_next = __transfered_const_iterators;
+ __transfered_const_iterators->_M_prior = __victim;
+ }
+ else
+ __last_const_iterator = __victim;
+ __victim->_M_sequence = this;
+ __victim->_M_version = this->_M_version;
+ __transfered_const_iterators = __victim;
+ }
+ }
+ }
+
+ // Now we can lock *this and add the transfered iterators if any
+ if (__last_iterator || __last_const_iterator)
+ {
+ __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
+ if (__last_iterator)
+ {
+ if (this->_M_iterators)
+ {
+ this->_M_iterators->_M_prior = __last_iterator;
+ __last_iterator->_M_next = this->_M_iterators;
+ }
+ this->_M_iterators = __transfered_iterators;
+ }
+ if (__last_const_iterator)
+ {
+ if (this->_M_const_iterators)
+ {
+ this->_M_const_iterators->_M_prior = __last_const_iterator;
+ __last_const_iterator->_M_next = this->_M_const_iterators;
+ }
+ this->_M_const_iterators = __transfered_const_iterators;
+ }
+ }
+ }
+} // namespace __gnu_debug
+
+#endif
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index b8ff463b2cf..60fbd38f26b 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -48,6 +48,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::set<_Key, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<set> _Safe_base;
+ typedef typename _Base::const_iterator _Base_const_iterator;
+ typedef typename _Base::iterator _Base_iterator;
+ typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public:
// types:
typedef _Key key_type;
@@ -58,9 +61,9 @@ namespace __debug
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, set>
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator, set>
iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, set>
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, set>
const_iterator;
typedef typename _Base::size_type size_type;
@@ -193,7 +196,6 @@ namespace __debug
std::pair<iterator, bool>
insert(const value_type& __x)
{
- typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
return std::pair<iterator, bool>(iterator(__res.first, this),
__res.second);
@@ -248,7 +250,7 @@ namespace __debug
erase(const_iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
return iterator(_Base::erase(__position.base()), this);
}
#else
@@ -256,7 +258,7 @@ namespace __debug
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- __position._M_invalidate();
+ this->_M_invalidate_if(_Equal(__position.base()));
_Base::erase(__position.base());
}
#endif
@@ -264,15 +266,15 @@ namespace __debug
size_type
erase(const key_type& __x)
{
- iterator __victim = find(__x);
- if (__victim == end())
+ _Base_iterator __victim = _Base::find(__x);
+ if (__victim == _Base::end())
return 0;
else
- {
- __victim._M_invalidate();
- _Base::erase(__victim.base());
- return 1;
- }
+ {
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim);
+ return 1;
+ }
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -282,9 +284,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
- return __last; // iterator == const_iterator
+ for (_Base_const_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ return iterator(_Base::erase(__first.base(), __last.base()), this);
}
#else
void
@@ -293,8 +302,16 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- while (__first != __last)
- this->erase(__first++);
+ for (_Base_iterator __victim = __first.base();
+ __victim != __last.base(); ++__victim)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__victim));
+ }
+ _Base::erase(__first.base(), __last.base());
}
#endif
@@ -307,7 +324,10 @@ namespace __debug
void
clear()
- { this->erase(begin(), end()); }
+ {
+ this->_M_invalidate_all();
+ _Base::clear();
+ }
// observers:
using _Base::key_comp;
@@ -349,7 +369,6 @@ namespace __debug
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
- typedef typename _Base::iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(iterator(__res.first, this),
@@ -361,7 +380,6 @@ namespace __debug
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
- typedef typename _Base::const_iterator _Base_iterator;
std::pair<_Base_iterator, _Base_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first, this),
@@ -378,7 +396,6 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
this->_M_invalidate_if(_Not_equal(_M_base().end()));
}
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 6f37e040a26..29484c1ccdc 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -55,6 +55,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::unordered_map<_Key, _Tp, _Hash,
_Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_sequence<unordered_map> _Safe_base;
+ 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::size_type size_type;
@@ -65,9 +68,9 @@ namespace __debug
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,
unordered_map> iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
unordered_map> const_iterator;
explicit
@@ -177,17 +180,14 @@ namespace __debug
std::pair<iterator, bool>
insert(const value_type& __obj)
{
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
- __pair_type __res = _Base::insert(__obj);
+ std::pair<_Base_iterator, bool> __res = _Base::insert(__obj);
return std::make_pair(iterator(__res.first, this), __res.second);
}
iterator
insert(const_iterator, const value_type& __obj)
{
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
- __pair_type __res = _Base::insert(__obj);
- return iterator(__res.first, this);
+ return iterator(_Base::insert(__obj).first, this);
}
template<typename _Pair, typename = typename
@@ -196,8 +196,8 @@ namespace __debug
std::pair<iterator, bool>
insert(_Pair&& __obj)
{
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
- __pair_type __res = _Base::insert(std::forward<_Pair>(__obj));
+ std::pair<_Base_iterator, bool> __res =
+ _Base::insert(std::forward<_Pair>(__obj));
return std::make_pair(iterator(__res.first, this), __res.second);
}
@@ -207,9 +207,8 @@ namespace __debug
iterator
insert(const_iterator, _Pair&& __obj)
{
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
- __pair_type __res = _Base::insert(std::forward<_Pair>(__obj));
- return iterator(__res.first, this);
+ return iterator(_Base::insert(std::forward<_Pair>(__obj)).first,
+ this);
}
void
@@ -236,9 +235,8 @@ namespace __debug
std::pair<iterator, iterator>
equal_range(const key_type& __key)
{
- typedef typename _Base::iterator _Base_iterator;
- 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));
}
@@ -246,9 +244,8 @@ namespace __debug
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{
- typedef typename _Base::const_iterator _Base_iterator;
- typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
- __pair_type __res = _Base::equal_range(__key);
+ std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+ _Base::equal_range(__key);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
@@ -257,10 +254,11 @@ namespace __debug
erase(const key_type& __key)
{
size_type __ret(0);
- iterator __victim(_Base::find(__key), this);
- if (__victim != end())
+ _Base_iterator __victim(_Base::find(__key));
+ if (__victim != _Base::end())
{
- this->erase(__victim);
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim);
__ret = 1;
}
return __ret;
@@ -270,7 +268,7 @@ namespace __debug
erase(const_iterator __it)
{
__glibcxx_check_erase(__it);
- __it._M_invalidate();
+ this->_M_invalidate_if(_Equal(__it.base()));
return iterator(_Base::erase(__it.base()), this);
}
@@ -278,11 +276,15 @@ namespace __debug
erase(const_iterator __first, const_iterator __last)
{
__glibcxx_check_erase_range(__first, __last);
- for (const_iterator __tmp = __first; __tmp != __last;)
- {
- const_iterator __victim = __tmp++;
- __victim._M_invalidate();
- }
+ for (_Base_const_iterator __tmp = __first.base();
+ __tmp != __last.base(); ++__tmp)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__tmp));
+ }
return iterator(_Base::erase(__first.base(),
__last.base()), this);
}
@@ -297,9 +299,8 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
@@ -339,6 +340,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::unordered_multimap<_Key, _Tp, _Hash,
_Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_sequence<unordered_multimap> _Safe_base;
+ 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::size_type size_type;
@@ -349,9 +353,9 @@ namespace __debug
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,
unordered_multimap> iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
unordered_multimap> const_iterator;
explicit
@@ -476,9 +480,9 @@ namespace __debug
template<typename _Pair, typename = typename
std::enable_if<std::is_convertible<_Pair,
value_type>::value>::type>
- iterator
- insert(const_iterator, _Pair&& __obj)
- { return iterator(_Base::insert(std::forward<_Pair>(__obj)), this); }
+ iterator
+ insert(const_iterator, _Pair&& __obj)
+ { return iterator(_Base::insert(std::forward<_Pair>(__obj)), this); }
void
insert(std::initializer_list<value_type> __l)
@@ -504,9 +508,8 @@ namespace __debug
std::pair<iterator, iterator>
equal_range(const key_type& __key)
{
- typedef typename _Base::iterator _Base_iterator;
- 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));
}
@@ -514,9 +517,8 @@ namespace __debug
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{
- typedef typename _Base::const_iterator _Base_iterator;
- typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
- __pair_type __res = _Base::equal_range(__key);
+ std::pair<_Base_const_iterator, _Base_const_iterator> __res =
+ _Base::equal_range(__key);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
@@ -525,10 +527,11 @@ namespace __debug
erase(const key_type& __key)
{
size_type __ret(0);
- iterator __victim(_Base::find(__key), this);
- if (__victim != end())
+ _Base_iterator __victim(_Base::find(__key));
+ if (__victim != _Base::end())
{
- this->erase(__victim);
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim);
__ret = 1;
}
return __ret;
@@ -538,7 +541,7 @@ namespace __debug
erase(const_iterator __it)
{
__glibcxx_check_erase(__it);
- __it._M_invalidate();
+ this->_M_invalidate_if(_Equal(__it.base()));
return iterator(_Base::erase(__it.base()), this);
}
@@ -546,11 +549,15 @@ namespace __debug
erase(const_iterator __first, const_iterator __last)
{
__glibcxx_check_erase_range(__first, __last);
- for (const_iterator __tmp = __first; __tmp != __last;)
- {
- const_iterator __victim = __tmp++;
- __victim._M_invalidate();
- }
+ for (_Base_const_iterator __tmp = __first.base();
+ __tmp != __last.base(); ++__tmp)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__tmp));
+ }
return iterator(_Base::erase(__first.base(),
__last.base()), this);
}
@@ -565,9 +572,8 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 1d42905e236..a606efec26f 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -55,6 +55,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::unordered_set<_Value, _Hash,
_Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_sequence<unordered_set> _Safe_base;
+ 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::size_type size_type;
@@ -65,9 +68,9 @@ namespace __debug
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,
unordered_set> iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
unordered_set> const_iterator;
explicit
@@ -177,7 +180,7 @@ namespace __debug
std::pair<iterator, bool>
insert(const value_type& __obj)
{
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
+ typedef std::pair<_Base_iterator, bool> __pair_type;
__pair_type __res = _Base::insert(__obj);
return std::make_pair(iterator(__res.first, this), __res.second);
}
@@ -185,7 +188,7 @@ namespace __debug
iterator
insert(const_iterator, const value_type& __obj)
{
- typedef std::pair<typename _Base::iterator, bool> __pair_type;
+ typedef std::pair<_Base_iterator, bool> __pair_type;
__pair_type __res = _Base::insert(__obj);
return iterator(__res.first, this);
}
@@ -230,7 +233,6 @@ namespace __debug
std::pair<iterator, iterator>
equal_range(const key_type& __key)
{
- typedef typename _Base::iterator _Base_iterator;
typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
__pair_type __res = _Base::equal_range(__key);
return std::make_pair(iterator(__res.first, this),
@@ -240,9 +242,8 @@ namespace __debug
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{
- typedef typename _Base::const_iterator _Base_iterator;
- typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
- __pair_type __res = _Base::equal_range(__key);
+ std::pair<_Base_const_iterator, _Base_const_iterator>
+ __res = _Base::equal_range(__key);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
@@ -251,10 +252,11 @@ namespace __debug
erase(const key_type& __key)
{
size_type __ret(0);
- iterator __victim(_Base::find(__key), this);
- if (__victim != end())
+ _Base_iterator __victim(_Base::find(__key));
+ if (__victim != _Base::end())
{
- this->erase(__victim);
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim);
__ret = 1;
}
return __ret;
@@ -264,7 +266,7 @@ namespace __debug
erase(const_iterator __it)
{
__glibcxx_check_erase(__it);
- __it._M_invalidate();
+ this->_M_invalidate_if(_Equal(__it.base()));
return iterator(_Base::erase(__it.base()), this);
}
@@ -272,11 +274,15 @@ namespace __debug
erase(const_iterator __first, const_iterator __last)
{
__glibcxx_check_erase_range(__first, __last);
- for (const_iterator __tmp = __first; __tmp != __last;)
- {
- const_iterator __victim = __tmp++;
- __victim._M_invalidate();
- }
+ for (_Base_const_iterator __tmp = __first.base();
+ __tmp != __last.base(); ++__tmp)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__tmp));
+ }
return iterator(_Base::erase(__first.base(),
__last.base()), this);
}
@@ -291,9 +297,8 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
@@ -329,6 +334,9 @@ namespace __debug
typedef _GLIBCXX_STD_D::unordered_multiset<_Value, _Hash,
_Pred, _Alloc> _Base;
typedef __gnu_debug::_Safe_sequence<unordered_multiset> _Safe_base;
+ 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::size_type size_type;
@@ -339,9 +347,9 @@ namespace __debug
typedef typename _Base::key_type key_type;
typedef typename _Base::value_type value_type;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,
unordered_multiset> iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
unordered_multiset> const_iterator;
explicit
@@ -488,7 +496,6 @@ namespace __debug
std::pair<iterator, iterator>
equal_range(const key_type& __key)
{
- typedef typename _Base::iterator _Base_iterator;
typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
__pair_type __res = _Base::equal_range(__key);
return std::make_pair(iterator(__res.first, this),
@@ -498,9 +505,8 @@ namespace __debug
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{
- typedef typename _Base::const_iterator _Base_iterator;
- typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
- __pair_type __res = _Base::equal_range(__key);
+ std::pair<_Base_const_iterator, _Base_const_iterator>
+ __res = _Base::equal_range(__key);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
@@ -509,10 +515,11 @@ namespace __debug
erase(const key_type& __key)
{
size_type __ret(0);
- iterator __victim(_Base::find(__key), this);
- if (__victim != end())
+ _Base_iterator __victim(_Base::find(__key));
+ if (__victim != _Base::end())
{
- this->erase(__victim);
+ this->_M_invalidate_if(_Equal(__victim));
+ _Base::erase(__victim);
__ret = 1;
}
return __ret;
@@ -522,7 +529,7 @@ namespace __debug
erase(const_iterator __it)
{
__glibcxx_check_erase(__it);
- __it._M_invalidate();
+ this->_M_invalidate_if(_Equal(__it.base()));
return iterator(_Base::erase(__it.base()), this);
}
@@ -530,11 +537,15 @@ namespace __debug
erase(const_iterator __first, const_iterator __last)
{
__glibcxx_check_erase_range(__first, __last);
- for (const_iterator __tmp = __first; __tmp != __last;)
- {
- const_iterator __victim = __tmp++;
- __victim._M_invalidate();
- }
+ for (_Base_const_iterator __tmp = __first.base();
+ __tmp != __last.base(); ++__tmp)
+ {
+ _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
+ _M_message(__gnu_debug::__msg_valid_range)
+ ._M_iterator(__first, "first")
+ ._M_iterator(__last, "last"));
+ this->_M_invalidate_if(_Equal(__tmp));
+ }
return iterator(_Base::erase(__first.base(),
__last.base()), this);
}
@@ -549,9 +560,8 @@ namespace __debug
void
_M_invalidate_all()
{
- typedef typename _Base::const_iterator _Base_const_iterator;
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
- this->_M_invalidate_if(_Not_equal(_M_base().end()));
+ this->_M_invalidate_if(_Not_equal(_Base::end()));
}
};
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 9004f2902ae..322c170289a 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -49,16 +49,17 @@ namespace __debug
typedef _GLIBCXX_STD_D::vector<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<vector> _Safe_base;
+ typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_iterator;
- typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
+ typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
public:
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
- typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,vector>
+ typedef __gnu_debug::_Safe_iterator<_Base_iterator,vector>
iterator;
- typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,vector>
+ typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,vector>
const_iterator;
typedef typename _Base::size_type size_type;
@@ -246,7 +247,7 @@ namespace __debug
{
bool __realloc = _M_requires_reallocation(__sz);
if (__sz < this->size())
- this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+ this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz);
if (__realloc)
this->_M_invalidate_all();
@@ -258,7 +259,7 @@ namespace __debug
{
bool __realloc = _M_requires_reallocation(__sz);
if (__sz < this->size())
- this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+ this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c);
if (__realloc)
this->_M_invalidate_all();
@@ -270,7 +271,7 @@ namespace __debug
{
bool __realloc = _M_requires_reallocation(__sz);
if (__sz < this->size())
- this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
+ this->_M_invalidate_after_nth(__sz);
_Base::resize(__sz, __c);
if (__realloc)
this->_M_invalidate_all();
@@ -388,8 +389,7 @@ namespace __debug
pop_back()
{
__glibcxx_check_nonempty();
- iterator __victim = end() - 1;
- __victim._M_invalidate();
+ this->_M_invalidate_if(_Equal(--_Base::end()));
_Base::pop_back();
}
@@ -400,13 +400,13 @@ namespace __debug
{
__glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + 1);
- difference_type __offset = __position - begin();
- typename _Base::iterator __res = _Base::emplace(__position.base(),
- std::forward<_Args>(__args)...);
+ difference_type __offset = __position.base() - _Base::begin();
+ _Base_iterator __res = _Base::emplace(__position.base(),
+ std::forward<_Args>(__args)...);
if (__realloc)
this->_M_invalidate_all();
else
- this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+ this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity();
return iterator(__res, this);
}
@@ -417,12 +417,12 @@ namespace __debug
{
__glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + 1);
- difference_type __offset = __position - begin();
- typename _Base::iterator __res = _Base::insert(__position.base(),__x);
+ 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_if(_After_nth(__offset, _M_base().begin()));
+ this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity();
return iterator(__res, this);
}
@@ -444,12 +444,12 @@ namespace __debug
{
__glibcxx_check_insert(__position);
bool __realloc = _M_requires_reallocation(this->size() + __n);
- difference_type __offset = __position - begin();
+ difference_type __offset = __position.base() - _Base::begin();
_Base::insert(__position.base(), __n, __x);
if (__realloc)
this->_M_invalidate_all();
else
- this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+ this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity();
}
@@ -463,15 +463,15 @@ namespace __debug
/* Hard to guess if invalidation will occur, because __last
- __first can't be calculated in all cases, so we just
punt here by checking if it did occur. */
- typename _Base::iterator __old_begin = _M_base().begin();
- difference_type __offset = __position - begin();
+ _Base_iterator __old_begin = _M_base().begin();
+ difference_type __offset = __position.base() - _Base::begin();
_Base::insert(__position.base(), __gnu_debug::__base(__first),
__gnu_debug::__base(__last));
if (_M_base().begin() != __old_begin)
this->_M_invalidate_all();
else
- this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+ this->_M_invalidate_after_nth(__offset);
_M_update_guaranteed_capacity();
}
@@ -479,9 +479,9 @@ namespace __debug
erase(iterator __position)
{
__glibcxx_check_erase(__position);
- difference_type __offset = __position - begin();
- typename _Base::iterator __res = _Base::erase(__position.base());
- this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+ difference_type __offset = __position.base() - _Base::begin();
+ _Base_iterator __res = _Base::erase(__position.base());
+ this->_M_invalidate_after_nth(__offset);
return iterator(__res, this);
}
@@ -492,10 +492,10 @@ namespace __debug
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
- difference_type __offset = __first - begin();
- typename _Base::iterator __res = _Base::erase(__first.base(),
- __last.base());
- this->_M_invalidate_if(_After_nth(__offset, _M_base().begin()));
+ difference_type __offset = __first.base() - _Base::begin();
+ _Base_iterator __res = _Base::erase(__first.base(),
+ __last.base());
+ this->_M_invalidate_after_nth(__offset);
return iterator(__res, this);
}
@@ -534,6 +534,13 @@ namespace __debug
if (this->size() > _M_guaranteed_capacity)
_M_guaranteed_capacity = this->size();
}
+
+ void
+ _M_invalidate_after_nth(difference_type __n)
+ {
+ typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
+ this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
+ }
};
template<typename _Tp, typename _Alloc>