This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] libstdc++/32907


Hi,

the below is the minimal patch which I prepared and tested for this performance PR. Per the standard, in general the equality operator is required to simply return string::compare. However, as always, for non-user defined types we have leeway, because the user cannot provide is own specialization anyway (we are already exploiting that in many other places, of course). As regards the implementation details, Iknow we don't have many enable_ifs in user-visible code (we have some in cmath, for example, but here I can definitely do without, if people care), but I think this is an appropriate case, which also scales well if we want to extend the implementation to additional character types on the path to C++0x.

Tested x86-linux.

Paolo.

///////////////////
2007-07-27  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/32907
	* include/bits/basic_string.h (operator==(const basic_string<_CharT>&,
	const basic_string<_CharT>&)): Add.
	(operator!=): Forward to operator==.
	* include/ext/vstring.h(operator==(const __versa_string<_CharT,
	std::char_traits<_CharT>, std::allocator<_CharT>, _Base>&,
	const __versa_string<_CharT, std::char_traits<_CharT>,
	std::allocator<_CharT>, _Base>&)): Add.
	(operator!=): Forward to operator==.

	* include/ext/sso_string_base.h (_M_compare): Remove.
Index: include/ext/vstring.h
===================================================================
--- include/ext/vstring.h	(revision 126958)
+++ include/ext/vstring.h	(working copy)
@@ -1867,6 +1867,17 @@
 	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
     { return __lhs.compare(__rhs) == 0; }
 
+  template<typename _CharT,
+	   template <typename, typename, typename> class _Base>
+    inline typename __enable_if<std::__is_char<_CharT>::__value, bool>::__type
+    operator==(const __versa_string<_CharT, std::char_traits<_CharT>,
+	       std::allocator<_CharT>, _Base>& __lhs,
+	       const __versa_string<_CharT, std::char_traits<_CharT>,
+	       std::allocator<_CharT>, _Base>& __rhs)
+    { return (__lhs.size() == __rhs.size()
+	      && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
+						    __lhs.size())); }
+
   /**
    *  @brief  Test equivalence of C string and string.
    *  @param lhs  C string.
@@ -1905,7 +1916,7 @@
     inline bool
     operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
 	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
-    { return __rhs.compare(__lhs) != 0; }
+    { return !(__lhs == __rhs); }
 
   /**
    *  @brief  Test difference of C string and string.
@@ -1918,7 +1929,7 @@
     inline bool
     operator!=(const _CharT* __lhs,
 	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
-    { return __rhs.compare(__lhs) != 0; }
+    { return !(__lhs == __rhs); }
 
   /**
    *  @brief  Test difference of string and C string.
@@ -1931,7 +1942,7 @@
     inline bool
     operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
 	       const _CharT* __rhs)
-    { return __lhs.compare(__rhs) != 0; }
+    { return !(__lhs == __rhs); }
 
   // operator <
   /**
Index: include/ext/sso_string_base.h
===================================================================
--- include/ext/sso_string_base.h	(revision 126963)
+++ include/ext/sso_string_base.h	(working copy)
@@ -540,30 +540,6 @@
       _M_set_length(_M_length() - __n);
     }
 
-  template<>
-    inline bool
-    __sso_string_base<char, std::char_traits<char>,
-		      std::allocator<char> >::
-    _M_compare(const __sso_string_base& __rcs) const
-    {
-      if (this == &__rcs)
-	return true;
-      return false;
-    }
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  template<>
-    inline bool
-    __sso_string_base<wchar_t, std::char_traits<wchar_t>,
-		      std::allocator<wchar_t> >::
-    _M_compare(const __sso_string_base& __rcs) const
-    {
-      if (this == &__rcs)
-	return true;
-      return false;
-    }
-#endif
-
 _GLIBCXX_END_NAMESPACE
 
 #endif /* _SSO_STRING_BASE_H */
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 126958)
+++ include/bits/basic_string.h	(working copy)
@@ -2157,6 +2157,15 @@
 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
     { return __lhs.compare(__rhs) == 0; }
 
+  template<typename _CharT>
+    inline
+    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
+    operator==(const basic_string<_CharT>& __lhs,
+	       const basic_string<_CharT>& __rhs)
+    { return (__lhs.size() == __rhs.size()
+	      && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
+						    __lhs.size())); }
+
   /**
    *  @brief  Test equivalence of C string and string.
    *  @param lhs  C string.
@@ -2192,7 +2201,7 @@
     inline bool
     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
-    { return __rhs.compare(__lhs) != 0; }
+    { return !(__lhs == __rhs); }
 
   /**
    *  @brief  Test difference of C string and string.
@@ -2204,7 +2213,7 @@
     inline bool
     operator!=(const _CharT* __lhs,
 	       const basic_string<_CharT, _Traits, _Alloc>& __rhs)
-    { return __rhs.compare(__lhs) != 0; }
+    { return !(__lhs == __rhs); }
 
   /**
    *  @brief  Test difference of string and C string.
@@ -2216,7 +2225,7 @@
     inline bool
     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
 	       const _CharT* __rhs)
-    { return __lhs.compare(__rhs) != 0; }
+    { return !(__lhs == __rhs); }
 
   // operator <
   /**

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]