aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/debug/safe_iterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/debug/safe_iterator.h')
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.h761
1 files changed, 465 insertions, 296 deletions
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index b8256fc3a22..86211b9ca3d 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -44,14 +44,14 @@ namespace __gnu_debug
template<typename _Sequence>
struct _BeforeBeginHelper
{
- template<typename _Iterator>
+ template<typename _Iterator, typename _Category>
static bool
- _S_Is(const _Safe_iterator<_Iterator, _Sequence>&)
+ _S_Is(const _Safe_iterator<_Iterator, _Sequence, _Category>&)
{ return false; }
- template<typename _Iterator>
+ template<typename _Iterator, typename _Category>
static bool
- _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it)
+ _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it)
{ return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
};
@@ -82,22 +82,30 @@ namespace __gnu_debug
* of iterators and it is being detached before _Iterator get
* destroyed. Otherwise it would result in a data race.
*/
- template<typename _Iterator, typename _Sequence>
+ template<typename _Iterator, typename _Sequence, typename _Category
+ = typename std::iterator_traits<_Iterator>::iterator_category>
class _Safe_iterator
: private _Iterator,
public _Safe_iterator_base
{
typedef _Iterator _Iter_base;
typedef _Safe_iterator_base _Safe_base;
- typedef typename _Sequence::const_iterator _Const_iterator;
typedef std::iterator_traits<_Iterator> _Traits;
+ protected:
+ typedef std::__are_same<typename _Sequence::_Base::const_iterator,
+ _Iterator> _IsConstant;
+
+ typedef typename __gnu_cxx::__conditional_type<
+ _IsConstant::__value,
+ typename _Sequence::_Base::iterator,
+ typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
+
struct _Attach_single
{ };
- _Safe_iterator(const _Iterator& __i, _Safe_sequence_base* __seq,
- _Attach_single)
+ _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
_GLIBCXX_NOEXCEPT
: _Iter_base(__i)
{ _M_attach_single(__seq); }
@@ -120,7 +128,7 @@ namespace __gnu_debug
* @pre @p seq is not NULL
* @post this is not singular
*/
- _Safe_iterator(const _Iterator& __i, const _Safe_sequence_base* __seq)
+ _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
_GLIBCXX_NOEXCEPT
: _Iter_base(__i), _Safe_base(__seq, _S_constant())
{
@@ -171,10 +179,11 @@ namespace __gnu_debug
*/
template<typename _MutableIterator>
_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
+ const _Safe_iterator<_MutableIterator, _Sequence,
+ typename __gnu_cxx::__enable_if<_IsConstant::__value &&
+ std::__are_same<_MutableIterator, _OtherIterator>::__value,
+ _Category>::__type>& __x)
+ _GLIBCXX_NOEXCEPT
: _Iter_base(__x.base())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -309,93 +318,12 @@ namespace __gnu_debug
return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
}
- // ------ Bidirectional iterator requirements ------
- /**
- * @brief Iterator predecrement
- * @pre iterator is decrementable
- */
- _Safe_iterator&
- operator--() _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
- _M_message(__msg_bad_dec)
- ._M_iterator(*this, "this"));
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
- --base();
- return *this;
- }
-
- /**
- * @brief Iterator postdecrement
- * @pre iterator is decrementable
- */
- _Safe_iterator
- operator--(int) _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
- _M_message(__msg_bad_dec)
- ._M_iterator(*this, "this"));
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
- return _Safe_iterator(base()--, this->_M_sequence, _Attach_single());
- }
-
- // ------ Random access iterator requirements ------
- reference
- operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
- && this->_M_can_advance(__n+1),
- _M_message(__msg_iter_subscript_oob)
- ._M_iterator(*this)._M_integer(__n));
- return base()[__n];
- }
-
- _Safe_iterator&
- operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
- _M_message(__msg_advance_oob)
- ._M_iterator(*this)._M_integer(__n));
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
- base() += __n;
- return *this;
- }
-
- _Safe_iterator
- operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
- _M_message(__msg_advance_oob)
- ._M_iterator(*this)._M_integer(__n));
- return _Safe_iterator(base() + __n, this->_M_sequence);
- }
-
- _Safe_iterator&
- operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
- _M_message(__msg_retreat_oob)
- ._M_iterator(*this)._M_integer(__n));
- __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
- base() -= __n;
- return *this;
- }
-
- _Safe_iterator
- operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
- _M_message(__msg_retreat_oob)
- ._M_iterator(*this)._M_integer(__n));
- return _Safe_iterator(base() - __n, this->_M_sequence);
- }
-
// ------ Utilities ------
/// Determine if this is a constant iterator.
- static bool
+ static _GLIBCXX_CONSTEXPR bool
_S_constant()
- { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; }
+ { return _IsConstant::__value; }
/**
* @brief Return the underlying iterator
@@ -444,10 +372,6 @@ namespace __gnu_debug
_M_incrementable() const
{ return !this->_M_singular() && !_M_is_end(); }
- // Is the iterator decrementable?
- bool
- _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
-
// Can we advance the iterator @p __n steps (@p __n may be negative)
bool
_M_can_advance(const difference_type& __n) const;
@@ -459,14 +383,23 @@ namespace __gnu_debug
bool __check_dereferenceable = true) const;
// The sequence this iterator references.
- typename
- __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
- _Safe_iterator>::__value,
- const _Sequence*,
- _Sequence*>::__type
+ typename __gnu_cxx::__conditional_type<
+ _IsConstant::__value, const _Sequence*, _Sequence*>::__type
_M_get_sequence() const
{ return static_cast<_Sequence*>(_M_sequence); }
+ // Get distance to __rhs.
+ typename _Distance_traits<_Iterator>::__type
+ _M_get_distance_to(const _Safe_iterator& __rhs) const;
+
+ // Get distance from sequence begin up to *this.
+ typename _Distance_traits<_Iterator>::__type
+ _M_get_distance_from_begin() const;
+
+ // Get distance from *this to sequence end.
+ typename _Distance_traits<_Iterator>::__type
+ _M_get_distance_to_end() const;
+
/// Is this iterator equal to the sequence's begin() iterator?
bool
_M_is_begin() const
@@ -490,13 +423,346 @@ namespace __gnu_debug
{ return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
};
+ template<typename _Iterator, typename _Sequence>
+ class _Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>
+ : public _Safe_iterator<_Iterator, _Sequence, std::forward_iterator_tag>
+ {
+ typedef _Safe_iterator<_Iterator, _Sequence,
+ std::forward_iterator_tag> _Safe_base;
+
+ protected:
+ typedef typename _Safe_base::_OtherIterator _OtherIterator;
+ typedef typename _Safe_base::_Attach_single _Attach_single;
+
+ _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
+ _GLIBCXX_NOEXCEPT
+ : _Safe_base(__i, __seq, _Attach_single())
+ { }
+
+ public:
+ /// @post the iterator is singular and unattached
+ _Safe_iterator() _GLIBCXX_NOEXCEPT { }
+
+ /**
+ * @brief Safe iterator construction from an unsafe iterator and
+ * its sequence.
+ *
+ * @pre @p seq is not NULL
+ * @post this is not singular
+ */
+ _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
+ _GLIBCXX_NOEXCEPT
+ : _Safe_base(__i, __seq)
+ { }
+
+ /**
+ * @brief Copy construction.
+ */
+ _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
+ : _Safe_base(__x)
+ { }
+
+#if __cplusplus >= 201103L
+ /** @brief Move construction. */
+ _Safe_iterator(_Safe_iterator&&) = default;
+#endif
+
+ /**
+ * @brief Converting constructor from a mutable iterator to a
+ * constant iterator.
+ */
+ template<typename _MutableIterator>
+ _Safe_iterator(
+ const _Safe_iterator<_MutableIterator, _Sequence,
+ typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
+ std::__are_same<_MutableIterator, _OtherIterator>::__value,
+ std::bidirectional_iterator_tag>::__type>& __x)
+ _GLIBCXX_NOEXCEPT
+ : _Safe_base(__x)
+ { }
+
+#if __cplusplus >= 201103L
+ /** @brief Copy assignment. */
+ _Safe_iterator&
+ operator=(const _Safe_iterator&) = default;
+
+ /** @brief Move assignment. */
+ _Safe_iterator&
+ operator=(_Safe_iterator&&) = default;
+#else
+ /** @brief Copy assignment. */
+ _Safe_iterator&
+ operator=(const _Safe_iterator& __x)
+ {
+ _Safe_base::operator=(__x);
+ return *this;
+ }
+#endif
+
+ // ------ Input iterator requirements ------
+ /**
+ * @brief Iterator preincrement
+ * @pre iterator is incrementable
+ */
+ _Safe_iterator&
+ operator++() _GLIBCXX_NOEXCEPT
+ {
+ _Safe_base::operator++();
+ return *this;
+ }
+
+ /**
+ * @brief Iterator postincrement
+ * @pre iterator is incrementable
+ */
+ _Safe_iterator
+ operator++(int) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+ _M_message(__msg_bad_inc)
+ ._M_iterator(*this, "this"));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ return _Safe_iterator(this->base()++, this->_M_sequence,
+ _Attach_single());
+ }
+
+ // ------ Bidirectional iterator requirements ------
+ /**
+ * @brief Iterator predecrement
+ * @pre iterator is decrementable
+ */
+ _Safe_iterator&
+ operator--() _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+ _M_message(__msg_bad_dec)
+ ._M_iterator(*this, "this"));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ --this->base();
+ return *this;
+ }
+
+ /**
+ * @brief Iterator postdecrement
+ * @pre iterator is decrementable
+ */
+ _Safe_iterator
+ operator--(int) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+ _M_message(__msg_bad_dec)
+ ._M_iterator(*this, "this"));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ return _Safe_iterator(this->base()--, this->_M_sequence,
+ _Attach_single());
+ }
+
+ // ------ Utilities ------
+
+ // Is the iterator decrementable?
+ bool
+ _M_decrementable() const
+ { return !this->_M_singular() && !this->_M_is_begin(); }
+ };
+
+ template<typename _Iterator, typename _Sequence>
+ class _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>
+ : public _Safe_iterator<_Iterator, _Sequence,
+ std::bidirectional_iterator_tag>
+ {
+ typedef _Safe_iterator<_Iterator, _Sequence,
+ std::bidirectional_iterator_tag> _Safe_base;
+ typedef typename _Safe_base::_OtherIterator _OtherIterator;
+
+ typedef typename _Safe_base::_Attach_single _Attach_single;
+
+ _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
+ _GLIBCXX_NOEXCEPT
+ : _Safe_base(__i, __seq, _Attach_single())
+ { }
+
+ public:
+ typedef typename _Safe_base::difference_type difference_type;
+ typedef typename _Safe_base::reference reference;
+
+ /// @post the iterator is singular and unattached
+ _Safe_iterator() _GLIBCXX_NOEXCEPT { }
+
+ /**
+ * @brief Safe iterator construction from an unsafe iterator and
+ * its sequence.
+ *
+ * @pre @p seq is not NULL
+ * @post this is not singular
+ */
+ _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
+ _GLIBCXX_NOEXCEPT
+ : _Safe_base(__i, __seq)
+ { }
+
+ /**
+ * @brief Copy construction.
+ */
+ _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
+ : _Safe_base(__x)
+ { }
+
+#if __cplusplus >= 201103L
+ /** @brief Move construction. */
+ _Safe_iterator(_Safe_iterator&&) = default;
+#endif
+
+ /**
+ * @brief Converting constructor from a mutable iterator to a
+ * constant iterator.
+ */
+ template<typename _MutableIterator>
+ _Safe_iterator(
+ const _Safe_iterator<_MutableIterator, _Sequence,
+ typename __gnu_cxx::__enable_if<_Safe_base::_IsConstant::__value &&
+ std::__are_same<_MutableIterator, _OtherIterator>::__value,
+ std::random_access_iterator_tag>::__type>& __x)
+ _GLIBCXX_NOEXCEPT
+ : _Safe_base(__x)
+ { }
+
+#if __cplusplus >= 201103L
+ /** @brief Copy assignment. */
+ _Safe_iterator&
+ operator=(const _Safe_iterator&) = default;
+
+ /** @brief Move assignment. */
+ _Safe_iterator&
+ operator=(_Safe_iterator&&) = default;
+#else
+ /** @brief Copy assignment. */
+ _Safe_iterator&
+ operator=(const _Safe_iterator& __x)
+ {
+ _Safe_base::operator=(__x);
+ return *this;
+ }
+#endif
+
+ // Is the iterator range [*this, __rhs) valid?
+ bool
+ _M_valid_range(const _Safe_iterator& __rhs,
+ std::pair<difference_type,
+ _Distance_precision>& __dist) const;
+
+ // ------ Input iterator requirements ------
+ /**
+ * @brief Iterator preincrement
+ * @pre iterator is incrementable
+ */
+ _Safe_iterator&
+ operator++() _GLIBCXX_NOEXCEPT
+ {
+ _Safe_base::operator++();
+ return *this;
+ }
+
+ /**
+ * @brief Iterator postincrement
+ * @pre iterator is incrementable
+ */
+ _Safe_iterator
+ operator++(int) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
+ _M_message(__msg_bad_inc)
+ ._M_iterator(*this, "this"));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ return _Safe_iterator(this->base()++, this->_M_sequence,
+ _Attach_single());
+ }
+
+ // ------ Bidirectional iterator requirements ------
+ /**
+ * @brief Iterator predecrement
+ * @pre iterator is decrementable
+ */
+ _Safe_iterator&
+ operator--() _GLIBCXX_NOEXCEPT
+ {
+ _Safe_base::operator--();
+ return *this;
+ }
+
+ /**
+ * @brief Iterator postdecrement
+ * @pre iterator is decrementable
+ */
+ _Safe_iterator
+ operator--(int) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
+ _M_message(__msg_bad_dec)
+ ._M_iterator(*this, "this"));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ return _Safe_iterator(this->base()--, this->_M_sequence,
+ _Attach_single());
+ }
+
+ // ------ Random access iterator requirements ------
+ reference
+ operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
+ && this->_M_can_advance(__n + 1),
+ _M_message(__msg_iter_subscript_oob)
+ ._M_iterator(*this)._M_integer(__n));
+ return this->base()[__n];
+ }
+
+ _Safe_iterator&
+ operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
+ _M_message(__msg_advance_oob)
+ ._M_iterator(*this)._M_integer(__n));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ this->base() += __n;
+ return *this;
+ }
+
+ _Safe_iterator
+ operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
+ _M_message(__msg_advance_oob)
+ ._M_iterator(*this)._M_integer(__n));
+ return _Safe_iterator(this->base() + __n, this->_M_sequence);
+ }
+
+ _Safe_iterator&
+ operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
+ _M_message(__msg_retreat_oob)
+ ._M_iterator(*this)._M_integer(__n));
+ __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+ this->base() -= __n;
+ return *this;
+ }
+
+ _Safe_iterator
+ operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
+ _M_message(__msg_retreat_oob)
+ ._M_iterator(*this)._M_integer(__n));
+ return _Safe_iterator(this->base() - __n, this->_M_sequence);
+ }
+ };
+
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -513,7 +779,7 @@ namespace __gnu_debug
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -530,7 +796,7 @@ namespace __gnu_debug
const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -547,7 +813,7 @@ namespace __gnu_debug
const _Safe_iterator<_Iterator, _Sequence>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -560,11 +826,13 @@ namespace __gnu_debug
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
- operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+ operator<(const _Safe_iterator<_IteratorL, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_IteratorR, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -577,11 +845,13 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
inline bool
- operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+ operator<(const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -594,11 +864,13 @@ namespace __gnu_debug
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
- operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+ operator<=(const _Safe_iterator<_IteratorL, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_IteratorR, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -611,11 +883,13 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
inline bool
- operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+ operator<=(const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -628,11 +902,13 @@ namespace __gnu_debug
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
- operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+ operator>(const _Safe_iterator<_IteratorL, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_IteratorR, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -645,11 +921,13 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
inline bool
- operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+ operator>(const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -662,11 +940,13 @@ namespace __gnu_debug
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
- operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+ operator>=(const _Safe_iterator<_IteratorL, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_IteratorR, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -679,11 +959,13 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
inline bool
- operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+ operator>=(const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_order_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -699,12 +981,15 @@ namespace __gnu_debug
// operators but also operator- must accept mixed iterator/const_iterator
// parameters.
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
- operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
+ inline typename _Safe_iterator<_IteratorL, _Sequence,
+ std::random_access_iterator_tag>::difference_type
+ operator-(const _Safe_iterator<_IteratorL, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_IteratorR, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_distance_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
@@ -715,185 +1000,69 @@ namespace __gnu_debug
return __lhs.base() - __rhs.base();
}
- template<typename _Iterator, typename _Sequence>
- inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
- operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
+ template<typename _Iterator, typename _Sequence>
+ inline typename _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>::difference_type
+ operator-(const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __lhs,
+ const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __rhs)
_GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
- _M_message(__msg_distance_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_distance_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() - __rhs.base();
- }
+ {
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
+ _M_message(__msg_distance_bad)
+ ._M_iterator(__lhs, "lhs")
+ ._M_iterator(__rhs, "rhs"));
+ _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
+ _M_message(__msg_distance_different)
+ ._M_iterator(__lhs, "lhs")
+ ._M_iterator(__rhs, "rhs"));
+ return __lhs.base() - __rhs.base();
+ }
template<typename _Iterator, typename _Sequence>
- inline _Safe_iterator<_Iterator, _Sequence>
- operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
- const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
+ inline _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>
+ operator+(typename _Safe_iterator<_Iterator,_Sequence,
+ std::random_access_iterator_tag>::difference_type __n,
+ const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __i)
+ _GLIBCXX_NOEXCEPT
{ return __i + __n; }
- /** Safe iterators know if they are dereferenceable. */
- template<typename _Iterator, typename _Sequence>
- inline bool
- __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
- { return __x._M_dereferenceable(); }
-
/** Safe iterators know how to check if they form a valid range. */
- template<typename _Iterator, typename _Sequence>
+ template<typename _Iterator, typename _Sequence, typename _Category>
inline bool
- __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
+ __valid_range(const _Safe_iterator<_Iterator, _Sequence,
+ _Category>& __first,
+ const _Safe_iterator<_Iterator, _Sequence,
+ _Category>& __last,
typename _Distance_traits<_Iterator>::__type& __dist)
{ return __first._M_valid_range(__last, __dist); }
- /** Safe iterators can help to get better distance knowledge. */
- template<typename _Iterator, typename _Sequence>
- inline typename _Distance_traits<_Iterator>::__type
- __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- std::random_access_iterator_tag)
- { return std::make_pair(__last.base() - __first.base(), __dp_exact); }
-
- template<typename _Iterator, typename _Sequence>
- inline typename _Distance_traits<_Iterator>::__type
- __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- std::input_iterator_tag)
- {
- typedef typename _Distance_traits<_Iterator>::__type _Diff;
- typedef _Sequence_traits<_Sequence> _SeqTraits;
-
- if (__first.base() == __last.base())
- return std::make_pair(0, __dp_exact);
-
- if (__first._M_is_before_begin())
- {
- if (__last._M_is_begin())
- return std::make_pair(1, __dp_exact);
-
- return std::make_pair(1, __dp_sign);
- }
-
- if (__first._M_is_begin())
- {
- if (__last._M_is_before_begin())
- return std::make_pair(-1, __dp_exact);
-
- if (__last._M_is_end())
- return _SeqTraits::_S_size(*__first._M_get_sequence());
-
- return std::make_pair(1, __dp_sign);
- }
-
- if (__first._M_is_end())
- {
- if (__last._M_is_before_begin())
- return std::make_pair(-1, __dp_exact);
-
- if (__last._M_is_begin())
- {
- _Diff __diff = _SeqTraits::_S_size(*__first._M_get_sequence());
- return std::make_pair(-__diff.first, __diff.second);
- }
-
- return std::make_pair(-1, __dp_sign);
- }
-
- if (__last._M_is_before_begin() || __last._M_is_begin())
- return std::make_pair(-1, __dp_sign);
-
- if (__last._M_is_end())
- return std::make_pair(1, __dp_sign);
-
- return std::make_pair(1, __dp_equality);
- }
-
- // Get distance from sequence begin to specified iterator.
- template<typename _Iterator, typename _Sequence>
- inline typename _Distance_traits<_Iterator>::__type
- __get_distance_from_begin(const _Safe_iterator<_Iterator, _Sequence>& __it)
- {
- typedef _Sequence_traits<_Sequence> _SeqTraits;
-
- // No need to consider before_begin as this function is only used in
- // _M_can_advance which won't be used for forward_list iterators.
- if (__it._M_is_begin())
- return std::make_pair(0, __dp_exact);
-
- if (__it._M_is_end())
- return _SeqTraits::_S_size(*__it._M_get_sequence());
-
- typename _Distance_traits<_Iterator>::__type __res
- = __get_distance(__it._M_get_sequence()->_M_base().begin(), __it.base());
-
- if (__res.second == __dp_equality)
- return std::make_pair(1, __dp_sign);
-
- return __res;
- }
-
- // Get distance from specified iterator to sequence end.
- template<typename _Iterator, typename _Sequence>
- inline typename _Distance_traits<_Iterator>::__type
- __get_distance_to_end(const _Safe_iterator<_Iterator, _Sequence>& __it)
+ template<typename _Iterator, typename _Sequence, typename _Category>
+ inline bool
+ __valid_range(const _Safe_iterator<_Iterator, _Sequence,
+ _Category>& __first,
+ const _Safe_iterator<_Iterator, _Sequence,
+ _Category>& __last)
{
- typedef _Sequence_traits<_Sequence> _SeqTraits;
-
- // No need to consider before_begin as this function is only used in
- // _M_can_advance which won't be used for forward_list iterators.
- if (__it._M_is_begin())
- return _SeqTraits::_S_size(*__it._M_get_sequence());
-
- if (__it._M_is_end())
- return std::make_pair(0, __dp_exact);
-
- typename _Distance_traits<_Iterator>::__type __res
- = __get_distance(__it.base(), __it._M_get_sequence()->_M_base().end());
-
- if (__res.second == __dp_equality)
- return std::make_pair(1, __dp_sign);
-
- return __res;
+ typename _Distance_traits<_Iterator>::__type __dist;
+ return __first._M_valid_range(__last, __dist);
}
- template<typename _Iterator, typename _Sequence, typename _Size>
+ template<typename _Iterator, typename _Sequence, typename _Category,
+ typename _Size>
inline bool
- __can_advance(const _Safe_iterator<_Iterator, _Sequence>& __it, _Size __n)
+ __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>& __it,
+ _Size __n)
{ return __it._M_can_advance(__n); }
-#if __cplusplus < 201103L
- template<typename _Iterator, typename _Sequence>
- struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
- : std::__are_same<std::random_access_iterator_tag,
- typename std::iterator_traits<_Iterator>::
- iterator_category>
- { };
-#else
template<typename _Iterator, typename _Sequence>
_Iterator
- __base(const _Safe_iterator<_Iterator, _Sequence>& __it,
- std::random_access_iterator_tag)
+ __base(const _Safe_iterator<_Iterator, _Sequence,
+ std::random_access_iterator_tag>& __it)
{ return __it.base(); }
- template<typename _Iterator, typename _Sequence>
- const _Safe_iterator<_Iterator, _Sequence>&
- __base(const _Safe_iterator<_Iterator, _Sequence>& __it,
- std::input_iterator_tag)
- { return __it; }
-
- template<typename _Iterator, typename _Sequence>
- auto
- __base(const _Safe_iterator<_Iterator, _Sequence>& __it)
- -> decltype(__base(__it, std::__iterator_category(__it)))
- { return __base(__it, std::__iterator_category(__it)); }
-#endif
-
#if __cplusplus < 201103L
template<typename _Iterator, typename _Sequence>
struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >