#include <bits/stl_pair.h>
#include <ext/type_traits.h>
+#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \
+ _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \
+ _M_message(_BadMsgId) \
+ ._M_iterator(_Lhs, #_Lhs) \
+ ._M_iterator(_Rhs, #_Rhs)); \
+ _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
+ _M_message(_DiffMsgId) \
+ ._M_iterator(_Lhs, #_Lhs) \
+ ._M_iterator(_Rhs, #_Rhs))
+
+#define _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(_Lhs, _Rhs) \
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_compare_bad, \
+ __msg_compare_different)
+
+#define _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(_Lhs, _Rhs) \
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_iter_order_bad, \
+ __msg_order_different)
+
+#define _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(_Lhs, _Rhs) \
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \
+ __msg_distance_different)
+
namespace __gnu_debug
{
/** Helper struct to deal with sequence offering a before_begin
template<typename _MutableIterator>
_Safe_iterator(
const _Safe_iterator<_MutableIterator, _Sequence,
- typename __gnu_cxx::__enable_if<_IsConstant::__value &&
- std::__are_same<_MutableIterator, _OtherIterator>::__value,
- _Category>::__type>& __x)
+ typename __gnu_cxx::__enable_if<_IsConstant::__value &&
+ std::__are_same<_MutableIterator, _OtherIterator>::__value,
+ _Category>::__type>& __x)
_GLIBCXX_NOEXCEPT
: _Iter_base(__x.base())
{
// Can we advance the iterator @p __n steps (@p __n may be negative)
bool
- _M_can_advance(const difference_type& __n) const;
+ _M_can_advance(difference_type __n) const;
// Is the iterator range [*this, __rhs) valid?
bool
bool
_M_is_beginnest() const
{ return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
+
+ // ------ Operators ------
+
+ typedef _Safe_iterator<_Iterator, _Sequence, iterator_category> _Self;
+
+ friend bool
+ operator==(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
+ return __lhs.base() == __rhs.base();
+ }
+
+ template<typename _IteR>
+ friend bool
+ operator==(const _Self& __lhs,
+ const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
+ _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
+ return __lhs.base() == __rhs.base();
+ }
+
+ friend bool
+ operator!=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
+ return __lhs.base() != __rhs.base();
+ }
+
+ template<typename _IteR>
+ friend bool
+ operator!=(const _Self& __lhs,
+ const _Safe_iterator<_IteR, _Sequence, iterator_category>& __rhs)
+ _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS(__lhs, __rhs);
+ return __lhs.base() != __rhs.base();
+ }
};
template<typename _Iterator, typename _Sequence>
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,
+ 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)
std::bidirectional_iterator_tag> _Safe_base;
typedef typename _Safe_base::_OtherIterator _OtherIterator;
+ typedef typename _Safe_base::_Self _Self;
+ typedef _Safe_iterator<_OtherIterator, _Sequence,
+ std::random_access_iterator_tag> _OtherSelf;
+
typedef typename _Safe_base::_Attach_single _Attach_single;
_Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
// ------ Random access iterator requirements ------
reference
- operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
+ operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
{
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
&& this->_M_can_advance(__n + 1),
}
_Safe_iterator&
- operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
+ operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
{
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
_M_message(__msg_advance_oob)
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
+ operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
{
_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
_M_message(__msg_retreat_oob)
return *this;
}
- _Safe_iterator
- operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
+ friend bool
+ operator<(const _Self& __lhs, const _Self& __rhs) _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);
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() < __rhs.base();
}
- };
-
- 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(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() == __rhs.base();
- }
-
- template<typename _Iterator, typename _Sequence>
- inline bool
- operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
- _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() == __rhs.base();
- }
-
- 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(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() != __rhs.base();
- }
- template<typename _Iterator, typename _Sequence>
- inline bool
- operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_iterator<_Iterator, _Sequence>& __rhs)
- _GLIBCXX_NOEXCEPT
- {
- _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() != __rhs.base();
- }
+ friend bool
+ operator<(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() < __rhs.base();
+ }
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline bool
- 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(),
- _M_message(__msg_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() < __rhs.base();
- }
+ friend bool
+ operator<=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() <= __rhs.base();
+ }
- template<typename _Iterator, typename _Sequence>
- inline bool
- 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_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() < __rhs.base();
- }
+ friend bool
+ operator<=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() <= __rhs.base();
+ }
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline bool
- 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(),
- _M_message(__msg_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() <= __rhs.base();
- }
+ friend bool
+ operator>(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() > __rhs.base();
+ }
- template<typename _Iterator, typename _Sequence>
- inline bool
- 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_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() <= __rhs.base();
- }
+ friend bool
+ operator>(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() > __rhs.base();
+ }
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline bool
- 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(),
- _M_message(__msg_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() > __rhs.base();
- }
+ friend bool
+ operator>=(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() >= __rhs.base();
+ }
- template<typename _Iterator, typename _Sequence>
- inline bool
- 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_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() > __rhs.base();
- }
+ friend bool
+ operator>=(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS(__lhs, __rhs);
+ return __lhs.base() >= __rhs.base();
+ }
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline bool
- 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(),
- _M_message(__msg_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() >= __rhs.base();
- }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // According to the resolution of DR179 not only the various comparison
+ // operators but also operator- must accept mixed iterator/const_iterator
+ // parameters.
+ friend difference_type
+ operator-(const _Self& __lhs, const _OtherSelf& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
+ return __lhs.base() - __rhs.base();
+ }
- template<typename _Iterator, typename _Sequence>
- inline bool
- 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_iter_order_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_order_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() >= __rhs.base();
- }
+ friend difference_type
+ operator-(const _Self& __lhs, const _Self& __rhs) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS(__lhs, __rhs);
+ return __lhs.base() - __rhs.base();
+ }
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // According to the resolution of DR179 not only the various comparison
- // operators but also operator- must accept mixed iterator/const_iterator
- // parameters.
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- 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(),
- _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();
- }
+ friend _Self
+ operator+(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
+ _M_message(__msg_advance_oob)
+ ._M_iterator(__x)._M_integer(__n));
+ return _Safe_iterator(__x.base() + __n, __x._M_sequence);
+ }
- 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();
- }
+ friend _Self
+ operator+(difference_type __n, const _Self& __x) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(__n),
+ _M_message(__msg_advance_oob)
+ ._M_iterator(__x)._M_integer(__n));
+ return _Safe_iterator(__n + __x.base(), __x._M_sequence);
+ }
- template<typename _Iterator, typename _Sequence>
- 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; }
+ friend _Self
+ operator-(const _Self& __x, difference_type __n) _GLIBCXX_NOEXCEPT
+ {
+ _GLIBCXX_DEBUG_VERIFY(__x._M_can_advance(-__n),
+ _M_message(__msg_retreat_oob)
+ ._M_iterator(__x)._M_integer(__n));
+ return _Safe_iterator(__x.base() - __n, __x._M_sequence);
+ }
+ };
/** Safe iterators know how to check if they form a valid range. */
template<typename _Iterator, typename _Sequence, typename _Category>
} // namespace __gnu_debug
+#undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS
+#undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS
+#undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS
+#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
+
#include <debug/safe_iterator.tcc>
#endif
#include <debug/safe_unordered_base.h>
+#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \
+ _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \
+ _M_message(__msg_iter_compare_bad) \
+ ._M_iterator(_Lhs, "lhs") \
+ ._M_iterator(_Rhs, "rhs")); \
+ _GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
+ _M_message(__msg_compare_different) \
+ ._M_iterator(_Lhs, "lhs") \
+ ._M_iterator(_Rhs, "rhs")); \
+ _GLIBCXX_DEBUG_VERIFY(_Lhs._M_in_same_bucket(_Rhs), \
+ _M_message(__msg_local_iter_compare_bad) \
+ ._M_iterator(_Lhs, "lhs") \
+ ._M_iterator(_Rhs, "rhs"))
+
namespace __gnu_debug
{
/** \brief Safe iterator wrapper.
typename _Sequence::_Base::const_local_iterator>::__type
_OtherIterator;
+ typedef _Safe_local_iterator _Self;
+ typedef _Safe_local_iterator<_OtherIterator, _Sequence> _OtherSelf;
+
struct _Attach_single
{ };
_M_in_same_bucket(const _Safe_local_iterator<_Other,
_Sequence>& __other) const
{ return bucket() == __other.bucket(); }
- };
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline bool
- operator==(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
- {
- _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
- _M_message(__msg_local_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() == __rhs.base();
- }
+ friend inline bool
+ operator==(const _Self& __lhs, const _OtherSelf& __rhs) noexcept
+ {
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
+ return __lhs.base() == __rhs.base();
+ }
- template<typename _Iterator, typename _Sequence>
- inline bool
- operator==(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
- {
- _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
- _M_message(__msg_local_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() == __rhs.base();
- }
+ friend inline bool
+ operator==(const _Self& __lhs, const _Self& __rhs) noexcept
+ {
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
+ return __lhs.base() == __rhs.base();
+ }
- template<typename _IteratorL, typename _IteratorR, typename _Sequence>
- inline bool
- operator!=(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
- const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
- {
- _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
- _M_message(__msg_local_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() != __rhs.base();
- }
+ friend inline bool
+ operator!=(const _Self& __lhs, const _OtherSelf& __rhs) noexcept
+ {
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
+ return __lhs.base() != __rhs.base();
+ }
- template<typename _Iterator, typename _Sequence>
- inline bool
- operator!=(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
- const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
- {
- _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
- _M_message(__msg_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
- _M_message(__msg_local_iter_compare_bad)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
- return __lhs.base() != __rhs.base();
- }
+ friend inline bool
+ operator!=(const _Self& __lhs, const _Self& __rhs) noexcept
+ {
+ _GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
+ return __lhs.base() != __rhs.base();
+ }
+ };
/** Safe local iterators know how to check if they form a valid range. */
template<typename _Iterator, typename _Sequence>
} // namespace __gnu_debug
+#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
+
#include <debug/safe_local_iterator.tcc>
#endif
#include <bits/boost_concept_check.h>
#include <cassert>
#include <testsuite_container_traits.h>
+#include <utility> // for rel_ops.
// Container requirement testing.
namespace __gnu_test
reverse_members(_Tp& container) { }
};
+ template<typename _Iterator,
+ bool _Mutable,
+ typename = typename std::iterator_traits<_Iterator>::iterator_category>
+ struct iterator_concept_checks;
+
// DR 691.
- template<typename _Tp, bool = traits<_Tp>::is_unordered::value>
+ template<typename _Tp>
struct forward_members_unordered
{
forward_members_unordered(typename _Tp::value_type& v)
{
+ // Make sure that even if rel_ops is injected there is no ambiguity
+ // when comparing iterators.
+ using namespace std::rel_ops;
+
typedef _Tp test_type;
test_type container;
container.insert(v);
+
+ iterator_concept_checks<typename _Tp::local_iterator, false> cc;
+ iterator_concept_checks<typename _Tp::const_local_iterator,
+ false> ccc;
+
assert( container.cbegin(0) == container.begin(0) );
assert( container.cend(0) == container.end(0) );
const typename test_type::size_type bn = container.bucket(1);
assert( container.cbegin(bn) != container.cend(bn) );
+ assert( container.cbegin(bn) != container.end(bn) );
+ assert( container.begin(bn) != container.cend(bn) );
}
};
- template<typename _Tp>
- struct forward_members_unordered<_Tp, false>
- {
- forward_members_unordered(_Tp& container) { }
- };
-
- template<typename _Iterator,
- bool _Mutable,
- typename = typename std::iterator_traits<_Iterator>::iterator_category>
- struct iterator_concept_checks;
-
template<typename _Iterator>
struct iterator_concept_checks<_Iterator, false,
std::forward_iterator_tag>
}
};
+ template<typename _Tp>
+ struct forward_members
+ {
+ forward_members(_Tp& container)
+ {
+ // Make sure that even if rel_ops is injected there is no ambiguity
+ // when comparing iterators.
+ using namespace std::rel_ops;
+
+ typedef traits<_Tp> traits_type;
+ iterator_concept_checks<typename _Tp::iterator,
+ !(traits_type::is_associative::value
+ || traits_type::is_unordered::value)> cc;
+ iterator_concept_checks<typename _Tp::const_iterator, false> ccc;
+
+ assert( container.cbegin() == container.begin() );
+ assert( container.end() == container.cend() );
+ assert( container.cbegin() != container.cend() );
+ assert( container.cbegin() != container.end() );
+ assert( container.begin() != container.cend() );
+ }
+ };
+
+ template<typename _Tp,
+ typename
+ = typename std::iterator_traits<typename _Tp::iterator>::iterator_category>
+ struct category_members : forward_members<_Tp>
+ {
+ category_members(_Tp& container)
+ : forward_members<_Tp>(container)
+ { };
+ };
+
+ template<typename _Tp>
+ struct category_members<_Tp, std::random_access_iterator_tag>
+ : forward_members<_Tp>
+ {
+ category_members(_Tp& container)
+ : forward_members<_Tp>(container)
+ {
+ // Make sure that even if rel_ops is injected there is no ambiguity
+ // when comparing iterators.
+ using namespace std::rel_ops;
+
+ assert( !(container.begin() < container.begin()) );
+ assert( !(container.cbegin() < container.cbegin()) );
+ assert( !(container.cbegin() < container.begin()) );
+ assert( !(container.begin() < container.cbegin()) );
+ assert( container.begin() <= container.begin() );
+ assert( container.cbegin() <= container.cbegin() );
+ assert( container.cbegin() <= container.begin() );
+ assert( container.begin() <= container.cbegin() );
+
+ assert( !(container.begin() > container.begin()) );
+ assert( !(container.cbegin() > container.cbegin()) );
+ assert( !(container.cbegin() > container.begin()) );
+ assert( !(container.begin() > container.cbegin()) );
+ assert( container.begin() >= container.begin() );
+ assert( container.cbegin() >= container.cbegin() );
+ assert( container.cbegin() >= container.begin() );
+ assert( container.begin() >= container.cbegin() );
+
+ assert( container.begin() - container.begin() == 0 );
+ assert( container.cbegin() - container.cbegin() == 0 );
+ assert( container.cbegin() - container.begin() == 0 );
+ assert( container.begin() - container.cbegin() == 0 );
+
+ assert( container.begin() + 0 == container.begin() );
+ assert( container.cbegin() + 0 == container.cbegin() );
+ assert( 0 + container.begin() == container.begin() );
+ assert( 0 + container.cbegin() == container.cbegin() );
+ assert( container.begin() - 0 == container.begin() );
+ assert( container.cbegin() - 0 == container.cbegin() );
+ }
+ };
+
template<typename _Tp>
struct citerator
{
static test_type _S_container;
// Unconditional.
- struct forward_members
+ struct members : category_members<_Tp>
{
- forward_members()
- {
- assert( _S_container.cbegin() == _S_container.begin() );
- assert( _S_container.cend() == _S_container.end() );
- assert( _S_container.cbegin() != _S_container.cend() );
- }
+ members() : category_members<_Tp>(_S_container)
+ { }
};
// Run test.
citerator()
{
populate<test_type> p(_S_container);
- forward_members m1;
+ members m1;
reverse_members<test_type> m2(_S_container);
}
};