Skip to content

Commit 783500d

Browse files
Abseil Teamcopybara-github
authored andcommitted
Add support for u8string and and u8string_view to absl/hash
PiperOrigin-RevId: 947095930 Change-Id: Ia62d5ccb0a28fef109abd6d2127116f8fc2c734b
1 parent bd22fa3 commit 783500d

5 files changed

Lines changed: 93 additions & 12 deletions

File tree

absl/container/internal/hash_function_defaults.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct BasicStringEq {
140140
}
141141
};
142142

143-
// Supports heterogeneous lookup for w/u16/u32 string + string_view + char*.
143+
// Supports heterogeneous lookup for w/u8/u16/u32 string + string_view + char*.
144144
template <typename TChar>
145145
struct BasicStringHashEq {
146146
using Hash = BasicStringHash<TChar>;
@@ -151,6 +151,12 @@ template <>
151151
struct HashEq<std::wstring> : BasicStringHashEq<wchar_t> {};
152152
template <>
153153
struct HashEq<std::wstring_view> : BasicStringHashEq<wchar_t> {};
154+
#ifdef __cpp_char8_t
155+
template <>
156+
struct HashEq<std::u8string> : BasicStringHashEq<char8_t> {};
157+
template <>
158+
struct HashEq<std::u8string_view> : BasicStringHashEq<char8_t> {};
159+
#endif
154160
template <>
155161
struct HashEq<std::u16string> : BasicStringHashEq<char16_t> {};
156162
template <>

absl/container/internal/hash_function_defaults_test.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <cstddef>
1818
#include <functional>
19+
#include <string>
1920
#include <string_view>
2021
#include <type_traits>
2122
#include <utility>
@@ -134,6 +135,28 @@ TEST(BasicStringViewTest, WStringViewEqWorks) {
134135
EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
135136
}
136137

138+
#ifdef __cpp_char8_t
139+
TEST(BasicStringViewTest, U8StringEqWorks) {
140+
hash_default_eq<std::u8string> eq;
141+
EXPECT_TRUE(eq(u8"a", u8"a"));
142+
EXPECT_TRUE(eq(u8"a", std::u8string_view(u8"a")));
143+
EXPECT_TRUE(eq(u8"a", std::u8string(u8"a")));
144+
EXPECT_FALSE(eq(u8"a", u8"b"));
145+
EXPECT_FALSE(eq(u8"a", std::u8string_view(u8"b")));
146+
EXPECT_FALSE(eq(u8"a", std::u8string(u8"b")));
147+
}
148+
149+
TEST(BasicStringViewTest, U8StringViewEqWorks) {
150+
hash_default_eq<std::u8string_view> eq;
151+
EXPECT_TRUE(eq(u8"a", u8"a"));
152+
EXPECT_TRUE(eq(u8"a", std::u8string_view(u8"a")));
153+
EXPECT_TRUE(eq(u8"a", std::u8string(u8"a")));
154+
EXPECT_FALSE(eq(u8"a", u8"b"));
155+
EXPECT_FALSE(eq(u8"a", std::u8string_view(u8"b")));
156+
EXPECT_FALSE(eq(u8"a", std::u8string(u8"b")));
157+
}
158+
#endif
159+
137160
TEST(BasicStringViewTest, U16StringEqWorks) {
138161
hash_default_eq<std::u16string> eq;
139162
EXPECT_TRUE(eq(u"a", u"a"));
@@ -192,6 +215,26 @@ TEST(BasicStringViewTest, WStringViewHashWorks) {
192215
EXPECT_NE(h, hash(std::wstring(L"b")));
193216
}
194217

218+
#ifdef __cpp_char8_t
219+
TEST(BasicStringViewTest, U8StringHashWorks) {
220+
hash_default_hash<std::u8string> hash;
221+
auto h = hash(u8"a");
222+
EXPECT_EQ(h, hash(std::u8string_view(u8"a")));
223+
EXPECT_EQ(h, hash(std::u8string(u8"a")));
224+
EXPECT_NE(h, hash(std::u8string_view(u8"b")));
225+
EXPECT_NE(h, hash(std::u8string(u8"b")));
226+
}
227+
228+
TEST(BasicStringViewTest, U8StringViewHashWorks) {
229+
hash_default_hash<std::u8string_view> hash;
230+
auto h = hash(u8"a");
231+
EXPECT_EQ(h, hash(std::u8string_view(u8"a")));
232+
EXPECT_EQ(h, hash(std::u8string(u8"a")));
233+
EXPECT_NE(h, hash(std::u8string_view(u8"b")));
234+
EXPECT_NE(h, hash(std::u8string(u8"b")));
235+
}
236+
#endif
237+
195238
TEST(BasicStringViewTest, U16StringHashWorks) {
196239
hash_default_hash<std::u16string> hash;
197240
auto h = hash(u"a");

absl/hash/hash.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ ABSL_NAMESPACE_BEGIN
117117
// * All string-like types including:
118118
// * absl::Cord
119119
// * std::string (as well as any instance of std::basic_string that
120-
// uses one of {char, wchar_t, char16_t, char32_t} and its associated
121-
// std::char_traits)
120+
// uses one of {char, wchar_t, char8_t, char16_t, char32_t} and its
121+
// associated std::char_traits)
122122
// * std::string_view (as well as any instance of std::basic_string_view
123-
// that uses one of {char, wchar_t, char16_t, char32_t} and its associated
124-
// std::char_traits)
123+
// that uses one of {char, wchar_t, char8_t, char16_t, char32_t} and its
124+
// associated std::char_traits)
125125
// * All the standard sequence containers (provided the elements are hashable)
126126
// * All the standard associative containers (provided the elements are
127127
// hashable)

absl/hash/hash_test.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,17 @@ TEST(HashValueTest, WString) {
484484
std::wstring(L"Iñtërnâtiônàlizætiøn"))));
485485
}
486486

487+
#ifdef __cpp_char8_t
488+
TEST(HashValueTest, U8String) {
489+
EXPECT_TRUE((is_hashable<std::u8string>::value));
490+
491+
EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
492+
std::u8string(), std::u8string(u8"ABC"), std::u8string(u8"ABC"),
493+
std::u8string(u8"Some other different string"),
494+
std::u8string(u8"Iñtërnâtiônàlizætiøn"))));
495+
}
496+
#endif
497+
487498
TEST(HashValueTest, U16String) {
488499
EXPECT_TRUE((is_hashable<std::u16string>::value));
489500

@@ -511,6 +522,18 @@ TEST(HashValueTest, WStringView) {
511522
std::wstring_view(L"Iñtërnâtiônàlizætiøn"))));
512523
}
513524

525+
#ifdef __cpp_char8_t
526+
TEST(HashValueTest, U8StringView) {
527+
EXPECT_TRUE((is_hashable<std::u8string_view>::value));
528+
529+
EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
530+
std::make_tuple(std::u8string_view(), std::u8string_view(u8"ABC"),
531+
std::u8string_view(u8"ABC"),
532+
std::u8string_view(u8"Some other different string_view"),
533+
std::u8string_view(u8"Iñtërnâtiônàlizætiøn"))));
534+
}
535+
#endif
536+
514537
TEST(HashValueTest, U16StringView) {
515538
EXPECT_TRUE((is_hashable<std::u16string_view>::value));
516539

absl/hash/internal/hash.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -645,22 +645,27 @@ H AbslHashValue(H hash_state, const std::shared_ptr<T>& ptr) {
645645
//
646646
// - `absl::Cord`
647647
// - `std::string` (and std::basic_string<T, std::char_traits<T>, A> for
648-
// any allocator A and any T in {char, wchar_t, char16_t, char32_t})
648+
// any allocator A and any T in {char, wchar_t, char8_t, char16_t,
649+
// char32_t})
649650
// - `absl::string_view`, `std::string_view`, `std::wstring_view`,
650-
// `std::u16string_view`, and `std::u32_string_view`.
651+
// `std::u8string_view`, `std::u16string_view`, and `std::u32_string_view`.
651652
//
652653
// For simplicity, we currently support only strings built on `char`, `wchar_t`,
653-
// `char16_t`, or `char32_t`. This support may be broadened, if necessary, but
654-
// with some caution - this overload would misbehave in cases where the traits'
655-
// `eq()` member isn't equivalent to `==` on the underlying character type.
654+
// `char8_t`, `char16_t`, or `char32_t`. This support may be broadened, if
655+
// necessary, but with some caution - this overload would misbehave in cases
656+
// where the traits' `eq()` member isn't equivalent to `==` on the underlying
657+
// character type.
656658
template <typename H>
657659
H AbslHashValue(H hash_state, absl::string_view str) {
658660
return H::combine_contiguous(std::move(hash_state), str.data(), str.size());
659661
}
660662

661-
// Support std::wstring, std::u16string and std::u32string.
663+
// Support std::wstring, std::u8string, std::u16string and std::u32string.
662664
template <typename Char, typename Alloc, typename H,
663665
typename = std::enable_if_t<std::is_same_v<Char, wchar_t> ||
666+
#ifdef __cpp_char8_t
667+
std::is_same_v<Char, char8_t> ||
668+
#endif
664669
std::is_same_v<Char, char16_t> ||
665670
std::is_same_v<Char, char32_t>>>
666671
H AbslHashValue(
@@ -669,9 +674,13 @@ H AbslHashValue(
669674
return H::combine_contiguous(std::move(hash_state), str.data(), str.size());
670675
}
671676

672-
// Support std::wstring_view, std::u16string_view and std::u32string_view.
677+
// Support std::wstring_view, std::u8string_view, std::u16string_view and
678+
// std::u32string_view.
673679
template <typename Char, typename H,
674680
typename = std::enable_if_t<std::is_same_v<Char, wchar_t> ||
681+
#ifdef __cpp_char8_t
682+
std::is_same_v<Char, char8_t> ||
683+
#endif
675684
std::is_same_v<Char, char16_t> ||
676685
std::is_same_v<Char, char32_t>>>
677686
H AbslHashValue(H hash_state, std::basic_string_view<Char> str) {

0 commit comments

Comments
 (0)