[libcxx-commits] [libcxx] 98f6a56 - [libc++] Enable hash only for the correct types
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 26 08:40:34 PDT 2022
Author: Nikolas Klauser
Date: 2022-08-26T17:40:23+02:00
New Revision: 98f6a56f5ea2fc4ae7f4283b97073667a9e32cde
URL: https://github.com/llvm/llvm-project/commit/98f6a56f5ea2fc4ae7f4283b97073667a9e32cde
DIFF: https://github.com/llvm/llvm-project/commit/98f6a56f5ea2fc4ae7f4283b97073667a9e32cde.diff
LOG: [libc++] Enable hash only for the correct types
Also implement LWG3705.
Fixes https://github.com/llvm/llvm-project/issues/55823
Reviewed By: ldionne, #libc
Spies: libcxx-commits
Differential Revision: https://reviews.llvm.org/D132338
Added:
Modified:
libcxx/docs/Status/Cxx2bIssues.csv
libcxx/include/string
libcxx/include/string_view
libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index ab3c680e8a8dd..0541ef241ddf0 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -173,7 +173,7 @@
"`3702 <https://wg21.link/LWG3702>`__","Should ``zip_transform_view::iterator`` remove ``operator<``","July 2022","",""
"`3703 <https://wg21.link/LWG3703>`__","Missing requirements for ``expected<T, E>`` requires ``is_void<T>``","July 2022","",""
"`3704 <https://wg21.link/LWG3704>`__","LWG 2059 added overloads that might be ill-formed for sets","July 2022","",""
-"`3705 <https://wg21.link/LWG3705>`__","Hashability shouldn't depend on basic_string's allocator","July 2022","",""
+"`3705 <https://wg21.link/LWG3705>`__","Hashability shouldn't depend on basic_string's allocator","July 2022","|Complete|","16.0"
"`3707 <https://wg21.link/LWG3707>`__","chunk_view::outer-iterator::value_type::size should return unsigned type","July 2022","","","|ranges|"
"`3708 <https://wg21.link/LWG3708>`__","``take_while_view::sentinel``'s conversion constructor should move","July 2022","","","|ranges|"
"`3709 <https://wg21.link/LWG3709>`__","LWG-3703 was underly ambitious","July 2022","",""
diff --git a/libcxx/include/string b/libcxx/include/string
index 07bf333579b25..2180f86f0e0b5 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -4597,15 +4597,32 @@ const typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::npos;
template <class _CharT, class _Allocator>
-struct _LIBCPP_TEMPLATE_VIS
- hash<basic_string<_CharT, char_traits<_CharT>, _Allocator> >
- : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
+struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t>
{
size_t
operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT
{ return __do_string_hash(__val.data(), __val.data() + __val.size()); }
};
+template <class _Allocator>
+struct hash<basic_string<char, char_traits<char>, _Allocator> > : __string_hash<char, _Allocator> {};
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+template <class _Allocator>
+struct hash<basic_string<char8_t, char_traits<char8_t>, _Allocator> > : __string_hash<char8_t, _Allocator> {};
+#endif
+
+template <class _Allocator>
+struct hash<basic_string<char16_t, char_traits<char16_t>, _Allocator> > : __string_hash<char16_t, _Allocator> {};
+
+template <class _Allocator>
+struct hash<basic_string<char32_t, char_traits<char32_t>, _Allocator> > : __string_hash<char32_t, _Allocator> {};
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <class _Allocator>
+struct hash<basic_string<wchar_t, char_traits<wchar_t>, _Allocator> > : __string_hash<wchar_t, _Allocator> {};
+#endif
+
template<class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index f15531ef8b395..d0c70a20fb38d 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -962,8 +962,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os,
// [string.view.hash]
template<class _CharT>
-struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > >
- : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
+struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
@@ -971,6 +970,25 @@ struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> >
}
};
+template <>
+struct hash<basic_string_view<char, char_traits<char> > > : __string_view_hash<char> {};
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
+template <>
+struct hash<basic_string_view<char8_t, char_traits<char8_t> > > : __string_view_hash<char8_t> {};
+#endif
+
+template <>
+struct hash<basic_string_view<char16_t, char_traits<char16_t> > > : __string_view_hash<char16_t> {};
+
+template <>
+struct hash<basic_string_view<char32_t, char_traits<char32_t> > > : __string_view_hash<char32_t> {};
+
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+template <>
+struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};
+#endif
+
#if _LIBCPP_STD_VER > 11
inline namespace literals
{
diff --git a/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp b/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
index 7e620b3fb189d..f82735862ecd2 100644
--- a/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
+++ b/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
@@ -15,10 +15,15 @@
#include <string>
+#include "constexpr_char_traits.h"
#include "poisoned_hash_helper.h"
-
+#include "test_allocator.h"
#include "test_macros.h"
+struct MyChar {
+ char c;
+};
+
int main(int, char**) {
test_library_hash_specializations_available();
{
@@ -31,6 +36,9 @@ int main(int, char**) {
#endif
test_hash_enabled_for_type<std::u16string>();
test_hash_enabled_for_type<std::u32string>();
+ test_hash_enabled_for_type<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>();
+ test_hash_disabled_for_type<std::basic_string<MyChar, std::char_traits<MyChar>, std::allocator<MyChar>>>();
+ test_hash_disabled_for_type<std::basic_string<char, constexpr_char_traits<char>, std::allocator<char>>>();
}
return 0;
diff --git a/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp b/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
index 5bea72e5b7a9f..c214ac1363bc0 100644
--- a/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.hash/enabled_hashes.pass.cpp
@@ -16,10 +16,14 @@
#include <string_view>
+#include "constexpr_char_traits.h"
#include "poisoned_hash_helper.h"
-
#include "test_macros.h"
+struct MyChar {
+ char c;
+};
+
int main(int, char**) {
test_library_hash_specializations_available();
{
@@ -32,6 +36,8 @@ int main(int, char**) {
#endif
test_hash_enabled_for_type<std::u16string_view>();
test_hash_enabled_for_type<std::u32string_view>();
+ test_hash_disabled_for_type<std::basic_string_view<MyChar, std::char_traits<MyChar>>>();
+ test_hash_disabled_for_type<std::basic_string_view<char, constexpr_char_traits<char>>>();
}
return 0;
More information about the libcxx-commits
mailing list