+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.
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
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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();
+}