Here is the cleanup version.

    * include/bits/stl_tree.h
    (_Rb_tree_iterator<>::operator==): Make inline friend.
    (_Rb_tree_iterator<>::operator!=): Likewise.
    (_Rb_tree_const_iterator<>::operator==): Likewise.
    (_Rb_tree_const_iterator<>::operator!=): Likewise.
    (operator==(const _Rb_tree_iterator<>&,
    const _Rb_tree_const_iterator&)): Remove.
    (operator!=(const _Rb_tree_iterator<>&,
    const _Rb_tree_const_iterator&)): Remove.
    (operator==(const _Rb_tree<>&, const _Rb_tree<>&)): Make inline friend.
    (operator<(const _Rb_tree<>&, const _Rb_tree<>&)): Likewise.
    (operator!=(const _Rb_tree<>&, const _Rb_tree<>&)): Likewise and deprecate.
    (operator>(const _Rb_tree<>&, const _Rb_tree<>&)): Likewise.
    (operator<=(const _Rb_tree<>&, const _Rb_tree<>&)): Likewise.
    (operator>=(const _Rb_tree<>&, const _Rb_tree<>&)): Likewise.
    * include/debug/map.h (map<>::erase(const_iterator, const_iterator)):
    Compare __victim with _Base::cend().
    * include/debug/multimap.h (multimap<>::erase(const_iterator, const_iterator)):
    Likewise.
    * include/debug/set.h (set<>::erase(const_iterator, const_iterator)):
    Compare __victim with _Base::cend().
    * include/debug/multiset.h (multiset<>::erase(const_iterator, const_iterator)):
    Likewise.

Tested under Linux x86_64.

Ok to commit ?

François

On 10/03/2018 12:08 PM, Jonathan Wakely wrote:
I consider the Table 83 - Container requirements where it is only saying that a == b should be well defined without namespace consideration. But I won't argue on Standard details with you, I'll revert that part.

The table says what they mean, but the synopses for <map> and <set>
also show declarations for those operators at namespace scope.

As far as I can tell, we only every use __x._M_t < __y._M_t and
__x._M_t == __y._M_t, so don't need anything else.

For sure we don't use those for associative containers operators. I guess they have been added for consistency with Standard containers. There are here for a long time, do you want to remove them now ? I can add this cleanup in my patch if you want.

Maybe we should deprecate them first. So please make them inline
friends (as for == and <) and add __attribute__((__deprecated__)).
I'll add something to the release notes for gcc-9 saying they're
deprecated. If nobody complains we can remove them for gcc-10 or
gcc-11.




diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 70d7483c7b1..87e57108deb 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -311,13 +311,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return __tmp;
       }
 
-      bool
-      operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
-      { return _M_node == __x._M_node; }
+      friend bool
+      operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
+      { return __x._M_node == __y._M_node; }
 
-      bool
-      operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
-      { return _M_node != __x._M_node; }
+      friend bool
+      operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
+      { return __x._M_node != __y._M_node; }
 
       _Base_ptr _M_node;
   };
@@ -390,29 +390,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return __tmp;
       }
 
-      bool
-      operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
-      { return _M_node == __x._M_node; }
+      friend bool
+      operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
+      { return __x._M_node == __y._M_node; }
 
-      bool
-      operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
-      { return _M_node != __x._M_node; }
+      friend bool
+      operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPT
+      { return __x._M_node != __y._M_node; }
 
       _Base_ptr _M_node;
     };
 
-  template<typename _Val>
-    inline bool
-    operator==(const _Rb_tree_iterator<_Val>& __x,
-	       const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
-    { return __x._M_node == __y._M_node; }
-
-  template<typename _Val>
-    inline bool
-    operator!=(const _Rb_tree_iterator<_Val>& __x,
-	       const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
-    { return __x._M_node != __y._M_node; }
-
   void
   _Rb_tree_insert_and_rebalance(const bool __insert_left,
 				_Rb_tree_node_base* __x,
@@ -1616,55 +1604,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    }
 	}
 #endif // C++17
-    };
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-	   typename _Compare, typename _Alloc>
-    inline bool
-    operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
-	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
+      friend bool
+      operator==(const _Rb_tree& __x, const _Rb_tree& __y)
       {
 	return __x.size() == __y.size()
 	  && std::equal(__x.begin(), __x.end(), __y.begin());
       }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-	   typename _Compare, typename _Alloc>
-    inline bool
-    operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
-	      const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
+      friend bool
+      operator<(const _Rb_tree& __x, const _Rb_tree& __y)
       {
 	return std::lexicographical_compare(__x.begin(), __x.end(),
 					    __y.begin(), __y.end());
       }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-	   typename _Compare, typename _Alloc>
-    inline bool
-    operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
-	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
+      friend bool _GLIBCXX_DEPRECATED
+      operator!=(const _Rb_tree& __x, const _Rb_tree& __y)
       { return !(__x == __y); }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-	   typename _Compare, typename _Alloc>
-    inline bool
-    operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
-	      const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
+      friend bool _GLIBCXX_DEPRECATED
+      operator>(const _Rb_tree& __x, const _Rb_tree& __y)
       { return __y < __x; }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-	   typename _Compare, typename _Alloc>
-    inline bool
-    operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
-	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
+      friend bool _GLIBCXX_DEPRECATED
+      operator<=(const _Rb_tree& __x, const _Rb_tree& __y)
       { return !(__y < __x); }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-	   typename _Compare, typename _Alloc>
-    inline bool
-    operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
-	       const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
+      friend bool _GLIBCXX_DEPRECATED
+      operator>=(const _Rb_tree& __x, const _Rb_tree& __y)
       { return !(__x < __y); }
+    };
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
 	   typename _Compare, typename _Alloc>
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index a885859592b..6821fc561e4 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -519,7 +519,7 @@ namespace __debug
 	for (_Base_const_iterator __victim = __first.base();
 	     __victim != __last.base(); ++__victim)
 	  {
-	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
 				  _M_message(__gnu_debug::__msg_valid_range)
 				  ._M_iterator(__first, "first")
 				  ._M_iterator(__last, "last"));
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 50500d66f70..d16ed47ab74 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -400,7 +400,7 @@ namespace __debug
 	for (_Base_const_iterator __victim = __first.base();
 	     __victim != __last.base(); ++__victim)
 	  {
-	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
 				  _M_message(__gnu_debug::__msg_valid_range)
 				  ._M_iterator(__first, "first")
 				  ._M_iterator(__last, "last"));
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index d292a14ca8c..bf154ecad6e 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -367,7 +367,7 @@ namespace __debug
 	for (_Base_const_iterator __victim = __first.base();
 	     __victim != __last.base(); ++__victim)
 	  {
-	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
 				  _M_message(__gnu_debug::__msg_valid_range)
 				  ._M_iterator(__first, "first")
 				  ._M_iterator(__last, "last"));
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index ed75f0f174f..c406fb424f4 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -379,7 +379,7 @@ namespace __debug
 	for (_Base_const_iterator __victim = __first.base();
 	     __victim != __last.base(); ++__victim)
 	  {
-	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
+	    _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
 				  _M_message(__gnu_debug::__msg_valid_range)
 				  ._M_iterator(__first, "first")
 				  ._M_iterator(__last, "last"));

Reply via email to