From: "François Dumont" <frs.dumont@gmail.com>
To: "libstdc++@gcc.gnu.org" <libstdc++@gcc.gnu.org>,
gcc-patches <gcc-patches@gcc.gnu.org>
Subject: [PATCH] Complete __gnu_debug::basic_string
Date: Tue, 16 Mar 2021 21:55:15 +0100 [thread overview]
Message-ID: <53722923-e31e-4311-27cb-c66d60b52b19@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1565 bytes --]
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
[-- Attachment #2: debug_string.patch --]
[-- Type: text/x-patch, Size: 6946 bytes --]
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
next reply other threads:[~2021-03-16 20:55 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-16 20:55 François Dumont [this message]
2021-03-19 19:41 ` Jonathan Wakely
2021-03-20 21:32 ` François Dumont
2021-03-23 15:42 ` Jonathan Wakely
2021-03-24 21:48 ` François Dumont
2021-03-25 13:05 ` Jonathan Wakely
2021-03-25 14:48 ` Jonathan Wakely
2021-03-25 15:29 ` Jonathan Wakely
2021-03-25 17:45 ` François Dumont
2021-03-25 18:22 ` Jonathan Wakely
2021-03-29 20:25 ` François Dumont
2021-04-01 13:55 ` Jonathan Wakely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53722923-e31e-4311-27cb-c66d60b52b19@gmail.com \
--to=frs.dumont@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).