2018-09-02 François Dumont <fdumont@gcc.gnu.org>
authorFrançois Dumont <fdumont@gcc.gnu.org>
Sun, 2 Sep 2018 10:20:57 +0000 (10:20 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Sun, 2 Sep 2018 10:20:57 +0000 (10:20 +0000)
* include/debug/safe_iterator.h
(_Safe_iterator<_It, _Seq, _Cat>::_Self): New.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>::_Self):
New.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
::_OtherSelf): New.
(_GLIBCXX_DEBUG_VERIFY_OPERANDS, _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS)
(_GLIBCXX_DEBUG_VERIFY_REL_OPERANDS)
(_GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS): Define macros.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
::operator+(difference_type)): Use latters, inline as friend.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
::operator-(difference_type)): Likewise.
(operator==(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator!=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator<(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
(operator<=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator>(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
(operator>=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator-(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
(operator+(difference_type, const _Safe_iterator<>&)): Likewise.
(operator-(const _Safe_iterator<>&, difference_type)): Likewise.
* include/debug/safe_iterator.tcc
(_Safe_iterator<>::_M_can_advance(difference_type)): Take parameter by
copy.
* include/debug/safe_local_iterator.h
(_Safe_local_iterator<_It, _Seq>::_Self): New.
(_Safe_local_iterator<_It, _Seq>::_OtherSelf): New.
(_GLIBCXX_DEBUG_VERIFY_OPERANDS): Define macro.
(operator==(const _Safe_local_iterator<>&,
const _Safe_local_iterator<>&)): Use latter, inline as friend.
(operator!=(const _Safe_local_iterator<>&,
const _Safe_local_iterator<>&)): Likewise.
* testsuite/util/testsuite_containers.h: Include utility.
(struct forward_members_unordered<_Tp, bool>): Remove 2nd template
parameter.
(forward_members_unordered<>::forward_members_unordered(value_type&)):
Add using namespace std::rel_ops.
Add iterator_concept_checks on local_iterator and const_local_iterator.
Add asserts on comparison between const_local_iterator and
local_iterator.
(struct forward_members_unordered<_Tp, false>): Remove partial
specialization.
* testsuite/23_containers/forward_list/types/1.cc: New.
* testsuite/23_containers/list/types/1.cc: New.

From-SVN: r264039

libstdc++-v3/ChangeLog
libstdc++-v3/include/debug/safe_iterator.h
libstdc++-v3/include/debug/safe_iterator.tcc
libstdc++-v3/include/debug/safe_local_iterator.h
libstdc++-v3/testsuite/23_containers/forward_list/types/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/list/types/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/util/testsuite_containers.h

index d45e4342978424f2d6479c413a430c0b277261f3..0c6f4084ee3bee43b8e1b0b4e7ec321e4471e28b 100644 (file)
@@ -1,3 +1,55 @@
+2018-09-02  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/debug/safe_iterator.h
+       (_Safe_iterator<_It, _Seq, _Cat>::_Self): New.
+       (_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>::_Self):
+       New.
+       (_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
+       ::_OtherSelf): New.
+       (_GLIBCXX_DEBUG_VERIFY_OPERANDS, _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS)
+       (_GLIBCXX_DEBUG_VERIFY_REL_OPERANDS)
+       (_GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS): Define macros.
+       (_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
+       ::operator+(difference_type)): Use latters, inline as friend.
+       (_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
+       ::operator-(difference_type)): Likewise.
+       (operator==(const _Safe_iterator<>&, const _Safe_iterator<>&)):
+       Likewise.
+       (operator!=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
+       Likewise.
+       (operator<(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
+       (operator<=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
+       Likewise.
+       (operator>(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
+       (operator>=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
+       Likewise.
+       (operator-(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
+       (operator+(difference_type, const _Safe_iterator<>&)): Likewise.
+       (operator-(const _Safe_iterator<>&, difference_type)): Likewise.
+       * include/debug/safe_iterator.tcc
+       (_Safe_iterator<>::_M_can_advance(difference_type)): Take parameter by
+       copy.
+       * include/debug/safe_local_iterator.h
+       (_Safe_local_iterator<_It, _Seq>::_Self): New.
+       (_Safe_local_iterator<_It, _Seq>::_OtherSelf): New.
+       (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Define macro.
+       (operator==(const _Safe_local_iterator<>&,
+       const _Safe_local_iterator<>&)): Use latter, inline as friend.
+       (operator!=(const _Safe_local_iterator<>&,
+       const _Safe_local_iterator<>&)): Likewise.
+       * testsuite/util/testsuite_containers.h: Include utility.
+       (struct forward_members_unordered<_Tp, bool>): Remove 2nd template
+       parameter.
+       (forward_members_unordered<>::forward_members_unordered(value_type&)):
+       Add using namespace std::rel_ops.
+       Add iterator_concept_checks on local_iterator and const_local_iterator.
+       Add asserts on comparison between const_local_iterator and
+       local_iterator.
+       (struct forward_members_unordered<_Tp, false>): Remove partial
+       specialization.
+       * testsuite/23_containers/forward_list/types/1.cc: New.
+       * testsuite/23_containers/list/types/1.cc: New.
+
 2018-09-01  Gerald Pfeifer  <gerald@pfeifer.com>
 
        * doc/xml/manual/profile_mode.xml: Update three ieeexplore.ieee.org
index 86211b9ca3d654cbc5c7ab034f668c92cf8cfc20..f0c2c204523b94eedefd9e61d6da7594b4e0e05f 100644 (file)
 #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
@@ -180,9 +202,9 @@ namespace __gnu_debug
       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())
        {
@@ -374,7 +396,7 @@ namespace __gnu_debug
 
       // 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
@@ -421,6 +443,44 @@ namespace __gnu_debug
       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>
@@ -474,8 +534,8 @@ namespace __gnu_debug
       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)
@@ -574,6 +634,10 @@ namespace __gnu_debug
                             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)
@@ -706,7 +770,7 @@ namespace __gnu_debug
 
       // ------ 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),
@@ -716,7 +780,7 @@ namespace __gnu_debug
       }
 
       _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)
@@ -726,17 +790,8 @@ namespace __gnu_debug
        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)
@@ -746,288 +801,107 @@ namespace __gnu_debug
        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>
@@ -1076,6 +950,11 @@ namespace __gnu_debug
 
 } // 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
index 2841583667fdc6e5a15adaaac45240f86bd0ff35..2bfe134a3a45cdb76dc2c68c668dcc4047b77541 100644 (file)
@@ -82,7 +82,7 @@ namespace __gnu_debug
   template<typename _Iterator, typename _Sequence, typename _Category>
     bool
     _Safe_iterator<_Iterator, _Sequence, _Category>::
-    _M_can_advance(const difference_type& __n) const
+    _M_can_advance(difference_type __n) const
     {
       if (this->_M_singular())
        return false;
index 854518848f9207dced99b3d2e38ee5b0f92d40aa..8e3ae443e9c8dc463be40194b69a98be7d6a8c30 100644 (file)
 
 #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.
@@ -65,6 +79,9 @@ namespace __gnu_debug
        typename _Sequence::_Base::const_local_iterator>::__type
       _OtherIterator;
 
+      typedef _Safe_local_iterator _Self;
+      typedef _Safe_local_iterator<_OtherIterator, _Sequence> _OtherSelf;
+
       struct _Attach_single
       { };
 
@@ -354,87 +371,35 @@ namespace __gnu_debug
        _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>
@@ -466,6 +431,8 @@ namespace __gnu_debug
 
 } // namespace __gnu_debug
 
+#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
+
 #include <debug/safe_local_iterator.tcc>
 
 #endif
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/types/1.cc b/libstdc++-v3/testsuite/23_containers/forward_list/types/1.cc
new file mode 100644 (file)
index 0000000..164b9c4
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <forward_list>
+#include <testsuite_greedy_ops.h>
+
+int main()
+{
+  std::forward_list<greedy_ops::X> fl;
+  const std::forward_list<greedy_ops::X> cfl;
+
+  fl.insert_after(fl.before_begin(), greedy_ops::X());
+  fl.insert_after(fl.before_begin(), 1, greedy_ops::X());
+  fl.insert_after(fl.before_begin(), cfl.begin(), cfl.end());
+  fl = cfl;
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/types/1.cc b/libstdc++-v3/testsuite/23_containers/list/types/1.cc
new file mode 100644 (file)
index 0000000..a7bb217
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile }
+
+#include <list>
+#include <testsuite_greedy_ops.h>
+
+int main()
+{
+  std::list<greedy_ops::X> l;
+  const std::list<greedy_ops::X> cl;
+
+  l.size();
+  l.insert(l.begin(), greedy_ops::X());
+  l.insert(l.begin(), 1, greedy_ops::X());
+  l.insert(l.begin(), cl.begin(), cl.end());
+  l = cl;
+
+  return 0;
+}
index 759f4d6b79fdb339e8115fa87179b32119634f9c..eadd43768d2b3887303dcc2ecec53c04e3640576 100644 (file)
@@ -23,6 +23,7 @@
 #include <bits/boost_concept_check.h>
 #include <cassert>
 #include <testsuite_container_traits.h>
+#include <utility> // for rel_ops.
 
 // Container requirement testing.
 namespace __gnu_test
@@ -170,33 +171,38 @@ 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>
@@ -263,6 +269,82 @@ namespace __gnu_test
       }
     };
 
+  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
     {
@@ -273,21 +355,17 @@ namespace __gnu_test
       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);
       }
   };