aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-04-03 10:47:47 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-04-03 10:47:47 +0100
commit0cb78ef4bcd216413199f9f27eed0ea0a56dd8da (patch)
treec4d7fd4a00fd3526c53a1055a9e91973a4a0fd1e
parent3a3976b14e329421e51a2aa43e516a6871cb5e6b (diff)
downloadgcc-0cb78ef4bcd216413199f9f27eed0ea0a56dd8da.zip
gcc-0cb78ef4bcd216413199f9f27eed0ea0a56dd8da.tar.gz
gcc-0cb78ef4bcd216413199f9f27eed0ea0a56dd8da.tar.bz2
Define std::hash specializations for C++17 PMR strings
These hash specializations should have been added when the pmr::string and related typedefs were added. * include/std/string (__hash_string_base): New class template defining operator() for hashing strings. (hash<pmr::string>, hash<pmr::u8string>, hash<pmr::u16string>) (hash<pmr::u32string>, hash<pmr::wstring>): Define for C++17. * testsuite/21_strings/basic_string/hash/hash.cc: New test. * testsuite/21_strings/basic_string/hash/hash_char8_t.cc: New test. From-SVN: r270116
-rw-r--r--libstdc++-v3/ChangeLog9
-rw-r--r--libstdc++-v3/include/std/string35
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/hash/hash.cc57
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/hash/hash_char8_t.cc61
4 files changed, 162 insertions, 0 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0b3d0c2..422ec850 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,12 @@
+2019-04-03 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/string (__hash_string_base): New class template defining
+ operator() for hashing strings.
+ (hash<pmr::string>, hash<pmr::u8string>, hash<pmr::u16string>)
+ (hash<pmr::u32string>, hash<pmr::wstring>): Define for C++17.
+ * testsuite/21_strings/basic_string/hash/hash.cc: New test.
+ * testsuite/21_strings/basic_string/hash/hash_char8_t.cc: New test.
+
2019-04-01 Ville Voutilainen <ville.voutilainen@gmail.com>
Use single-visitation in variant assignment and swap and relops.
diff --git a/libstdc++-v3/include/std/string b/libstdc++-v3/include/std/string
index 100c6c8..6ccc06f 100644
--- a/libstdc++-v3/include/std/string
+++ b/libstdc++-v3/include/std/string
@@ -74,6 +74,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using wstring = basic_string<wchar_t>;
#endif
} // namespace pmr
+
+ template<typename _Str>
+ struct __hash_string_base
+ : public __hash_base<size_t, _Str>
+ {
+ size_t
+ operator()(const _Str& __s) const noexcept
+ { return hash<basic_string_view<typename _Str::value_type>>{}(__s); }
+ };
+
+ template<>
+ struct hash<pmr::string>
+ : public __hash_string_base<pmr::string>
+ { };
+#ifdef _GLIBCXX_USE_CHAR8_T
+ template<>
+ struct hash<pmr::u8string>
+ : public __hash_string_base<pmr::u8string>
+ { };
+#endif
+ template<>
+ struct hash<pmr::u16string>
+ : public __hash_string_base<pmr::u16string>
+ { };
+ template<>
+ struct hash<pmr::u32string>
+ : public __hash_string_base<pmr::u32string>
+ { };
+#ifdef _GLIBCXX_USE_WCHAR_T
+ template<>
+ struct hash<pmr::wstring>
+ : public __hash_string_base<pmr::wstring>
+ { };
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash.cc b/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash.cc
new file mode 100644
index 0000000..9bdf9bd
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2019 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-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+#include <string>
+#include <memory_resource>
+#include <testsuite_hooks.h>
+
+// C++17 24.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)).
+
+template<typename S>
+ bool
+ test(const S& s)
+ {
+ using std::hash;
+ using SV = std::basic_string_view<typename S::value_type>;
+ return hash<S>()(s) == hash<SV>()(SV(s));
+ }
+
+void
+test01()
+{
+ VERIFY( test(std::string("a narrow string")) );
+ VERIFY( test(std::pmr::string("a narrow string, but with PMR!")) );
+ VERIFY( test(std::u16string(u"a utf-16 string")) );
+ VERIFY( test(std::pmr::u16string(u"a utf-16 string, but with PMR!")) );
+ VERIFY( test(std::u32string(U"a utf-32 string")) );
+ VERIFY( test(std::pmr::u32string(U"a utf-32 string, but with PMR!")) );
+#if _GLIBCXX_USE_WCHAR_T
+ VERIFY( test(std::wstring(L"a wide string")) );
+ VERIFY( test(std::pmr::wstring(L"a wide string, but with PMR!")) );
+#endif
+}
+
+int
+main()
+{
+ test01();
+}
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
new file mode 100644
index 0000000..0e4cfae
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/hash/hash_char8_t.cc
@@ -0,0 +1,61 @@
+// Copyright (C) 2019 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-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <string>
+#include <memory_resource>
+#include <testsuite_hooks.h>
+
+// 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)).
+
+template<typename S>
+ bool
+ test(const S& s)
+ {
+ using std::hash;
+ using SV = std::basic_string_view<typename S::value_type>;
+ return hash<S>()(s) == hash<SV>()(SV(s));
+ }
+
+void
+test01()
+{
+ VERIFY( test(std::string("a narrow string")) );
+ VERIFY( test(std::pmr::string("a narrow string, but with PMR!")) );
+ VERIFY( test(std::u8string(u8"a utf-8 string")) );
+ VERIFY( test(std::pmr::u8string(u8"a utf-8 string, but with PMR!")) );
+}
+
+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) );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}