Following:

https://gcc.gnu.org/pipermail/libstdc++/2021-March/052158.html

Here is the patch to complete __gnu_debug::basic_string support. Contrarily to what I thought code in std::basic_string to generate a basic_string_view works just fine for __gnu_debug::basic_string.

    libstdc++: [_GLIBCXX_DEBUG] Add __gnu_debug u8string/u16string/u32string

    Complete __gnu_debug::basic_string support so that it can be used as a
    transparent replacement of std::basic_string.

    libstdc++-v3/ChangeLog:

            * include/debug/string
            (basic_string(const _CharT*, const _Allocator&)): Remove assign call.             (basic_string<>::insert(const_iterator, _InputIte, _InputIte)): Try to
            remove iterator debug layer even if !_GLIBCXX_USE_CXX11_ABI.
            [_GLIBCXX_USE_CHAR8_T] (__gnu_debug::u8string): New.
            (__gnu_debug::u16string, __gnu_debug::u32string): New.
[!_GLIBCXX_COMPATIBILITY_CXX0X](std::hash<__gnu_debug::string>): New.
[!_GLIBCXX_COMPATIBILITY_CXX0X][_GLIBCXX_USE_WCHAR_T](std::hash<__gnu_debug::wstring>): New.
[_GLIBCXX_USE_CHAR8_T](std::hash<__gnu_debug::u8string>): New.
            (std::hash<__gnu_debug::u16string>): New.
            (std::hash<__gnu_debug::u32string>): New.
            * testsuite/21_strings/basic_string/hash/hash_char8_t.cc: Adapt for
            __gnu_debug basic_string.

Tested under Linux x86_64.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index d6eb5280ade..dec23f6277b 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -41,6 +41,14 @@
     __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)		\
       ._M_message(#_Cond)._M_error()
 
+#if _GLIBCXX_USE_CXX11_ABI && __cplusplus >= 201103
+# define _GLIBCXX_CPP11_AND_CXX11_ABI 1
+# define _GLIBCXX_CPP11_AND_CXX11_ABI_ONLY(Statement) Statement
+#else
+# define _GLIBCXX_CPP11_AND_CXX11_ABI 0
+# define _GLIBCXX_CPP11_AND_CXX11_ABI_ONLY(Statement)
+#endif
+
 namespace __gnu_debug
 {
   /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
@@ -180,7 +188,7 @@ namespace __gnu_debug
 
       basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
       : _Base(__glibcxx_check_string_constructor(__s), __a)
-      { this->assign(__s); }
+      { }
 
       basic_string(size_type __n, _CharT __c,
 		   const _Allocator& __a = _Allocator())
@@ -637,15 +645,22 @@ namespace __gnu_debug
 	  __glibcxx_check_insert_range(__p, __first, __last, __dist);
 
 	  typename _Base::iterator __res;
-#if _GLIBCXX_USE_CXX11_ABI && __cplusplus >= 201103
+#if ! _GLIBCXX_CPP11_AND_CXX11_ABI
+	  const size_type __offset = __p.base() - _Base::begin();
+#endif
 	  if (__dist.second >= __dp_sign)
-	    __res = _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
-				  __gnu_debug::__unsafe(__last));
+	    {
+	      _GLIBCXX_CPP11_AND_CXX11_ABI_ONLY(__res =)
+		_Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
+			      __gnu_debug::__unsafe(__last));
+	    }
 	  else
-	    __res = _Base::insert(__p.base(), __first, __last);
-#else
-	  const size_type __offset = __p.base() - _Base::begin();
-	  _Base::insert(__p.base(), __first, __last);
+	    {
+	      _GLIBCXX_CPP11_AND_CXX11_ABI_ONLY(__res =)
+		_Base::insert(__p.base(), __first, __last);
+	    }
+
+#if ! _GLIBCXX_CPP11_AND_CXX11_ABI
 	  __res = _Base::begin() + __offset;
 #endif
 	  this->_M_invalidate_all();
@@ -1287,6 +1302,19 @@ namespace __gnu_debug
   typedef basic_string<wchar_t> wstring;
 #endif
 
+#ifdef _GLIBCXX_USE_CHAR8_T
+  /// A string of @c char8_t
+  typedef basic_string<char8_t> u8string;
+#endif
+
+#if __cplusplus >= 201103L
+  /// A string of @c char16_t
+  typedef basic_string<char16_t> u16string;
+
+  /// A string of @c char32_t
+  typedef basic_string<char32_t> u32string;
+#endif
+
   template<typename _CharT, typename _Traits, typename _Allocator>
     struct _Insert_range_from_self_is_safe<
       __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
@@ -1294,4 +1322,96 @@ namespace __gnu_debug
 
 } // namespace __gnu_debug
 
+#if __cplusplus >= 201103L
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // DR 1182.
+
+#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
+  /// std::hash specialization for string.
+  template<>
+    struct hash<__gnu_debug::string>
+    : public __hash_base<size_t, __gnu_debug::string>
+    {
+      size_t
+      operator()(const __gnu_debug::string& __s) const noexcept
+      { return std::hash<std::string>()(__s); }
+    };
+
+  template<>
+    struct __is_fast_hash<hash<__gnu_debug::string>> : std::false_type
+    { };
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  /// std::hash specialization for wstring.
+  template<>
+    struct hash<__gnu_debug::wstring>
+    : public __hash_base<size_t, __gnu_debug::wstring>
+    {
+      size_t
+      operator()(const __gnu_debug::wstring& __s) const noexcept
+      { return std::hash<__gnu_debug::wstring>()(__s); }
+    };
+
+  template<>
+    struct __is_fast_hash<hash<__gnu_debug::wstring>> : std::false_type
+    { };
+#endif
+#endif /* _GLIBCXX_COMPATIBILITY_CXX0X */
+
+#ifdef _GLIBCXX_USE_CHAR8_T
+  /// std::hash specialization for u8string.
+  template<>
+    struct hash<__gnu_debug::u8string>
+    : public __hash_base<size_t, __gnu_debug::u8string>
+    {
+      size_t
+      operator()(const __gnu_debug::u8string& __s) const noexcept
+      { return std::hash<std::u8string>()(__s); }
+    };
+
+  template<>
+    struct __is_fast_hash<hash<__gnu_debug::u8string>> : std::false_type
+    { };
+#endif
+
+  /// std::hash specialization for u16string.
+  template<>
+    struct hash<__gnu_debug::u16string>
+    : public __hash_base<size_t, __gnu_debug::u16string>
+    {
+      size_t
+      operator()(const __gnu_debug::u16string& __s) const noexcept
+      { return std::hash<std::u16string>()(__s); }
+    };
+
+  template<>
+    struct __is_fast_hash<hash<__gnu_debug::u16string>> : std::false_type
+    { };
+
+  /// std::hash specialization for u32string.
+  template<>
+    struct hash<__gnu_debug::u32string>
+    : public __hash_base<size_t, __gnu_debug::u32string>
+    {
+      size_t
+      operator()(const __gnu_debug::u32string& __s) const noexcept
+      { return std::hash<std::u32string>()(__s); }
+    };
+
+  template<>
+    struct __is_fast_hash<hash<__gnu_debug::u32string>> : std::false_type
+    { };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+  } // namespace std
+
+#endif /* C++11 */
+
+#undef _GLIBCXX_CPP11_AND_CXX11_ABI
+#undef _GLIBCXX_CPP11_AND_CXX11_ABI_ONLY
+
 #endif
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash_char8_t.cc b/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash_char8_t.cc
index c0e8975ce4a..7f8792bbd76 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash_char8_t.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash_char8_t.cc
@@ -18,10 +18,19 @@
 // { dg-options "-std=gnu++2a" }
 // { dg-do run { target c++2a } }
 
-#include <string>
 #include <memory_resource>
 #include <testsuite_hooks.h>
 
+#ifdef _GLIBCXX_DEBUG
+# include <debug/string>
+
+using namespace __gnu_debug;
+#else
+# include <string>
+
+using namespace std;
+#endif
+
 // C++2a N4810 21.3.5 [basic.string.hash]
 // If S is one of these string types, SV is the corresponding string view type,
 // and s is an object of type S, then hash<S>()(s) == hash<SV>()(SV(s)).
@@ -38,8 +47,8 @@ template<typename S>
 void
 test01()
 {
-  VERIFY( test(std::string("a narrow string")) );
-  VERIFY( test(std::u8string(u8"a utf-8 string")) );
+  VERIFY( test(string("a narrow string")) );
+  VERIFY( test(u8string(u8"a utf-8 string")) );
 #if _GLIBCXX_USE_CXX11_ABI
   VERIFY( test(std::pmr::string("a narrow string, but with PMR!")) );
   VERIFY( test(std::pmr::u8string(u8"a utf-8 string, but with PMR!")) );
@@ -50,9 +59,9 @@ void
 test02()
 {
   using std::hash;
-  std::string native("a string, a string, my stringdom for a string");
-  std::u8string utf8(u8"a string, a string, my stringdom for a string");
-  VERIFY( hash<std::string>()(native) == hash<std::u8string>()(utf8) );
+  string native("a string, a string, my stringdom for a string");
+  u8string utf8(u8"a string, a string, my stringdom for a string");
+  VERIFY( hash<string>()(native) == hash<u8string>()(utf8) );
 }
 
 int

Reply via email to