[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