Commit c4127a72 by Abseil Team Committed by Copybara-Service

Add heterogeneous lookup support for wstring/u16string/u32string.

PiperOrigin-RevId: 521556211
Change-Id: I1e1812eb11bfc5772abbf38ce348580c3afa5612
parent 88f0473a
......@@ -56,6 +56,10 @@
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#ifdef ABSL_HAVE_STD_STRING_VIEW
#include <string_view>
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
......@@ -107,6 +111,48 @@ struct HashEq<absl::string_view> : StringHashEq {};
template <>
struct HashEq<absl::Cord> : StringHashEq {};
#ifdef ABSL_HAVE_STD_STRING_VIEW
template <typename TChar>
struct BasicStringHash {
using is_transparent = void;
size_t operator()(std::basic_string_view<TChar> v) const {
return absl::Hash<std::basic_string_view<TChar>>{}(v);
}
};
template <typename TChar>
struct BasicStringEq {
using is_transparent = void;
bool operator()(std::basic_string_view<TChar> lhs,
std::basic_string_view<TChar> rhs) const {
return lhs == rhs;
}
};
// Supports heterogeneous lookup for w/u16/u32 string + string_view + char*.
template <typename TChar>
struct BasicStringHashEq {
using Hash = BasicStringHash<TChar>;
using Eq = BasicStringEq<TChar>;
};
template <>
struct HashEq<std::wstring> : BasicStringHashEq<wchar_t> {};
template <>
struct HashEq<std::wstring_view> : BasicStringHashEq<wchar_t> {};
template <>
struct HashEq<std::u16string> : BasicStringHashEq<char16_t> {};
template <>
struct HashEq<std::u16string_view> : BasicStringHashEq<char16_t> {};
template <>
struct HashEq<std::u32string> : BasicStringHashEq<char32_t> {};
template <>
struct HashEq<std::u32string_view> : BasicStringHashEq<char32_t> {};
#endif // ABSL_HAVE_STD_STRING_VIEW
// Supports heterogeneous lookup for pointers and smart pointers.
template <class T>
struct HashEq<T*> {
......
......@@ -24,6 +24,10 @@
#include "absl/strings/cord_test_helpers.h"
#include "absl/strings/string_view.h"
#ifdef ABSL_HAVE_STD_STRING_VIEW
#include <string_view>
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
......@@ -109,6 +113,168 @@ TYPED_TEST(HashString, Works) {
EXPECT_NE(h, hash(std::string("b")));
}
TEST(BasicStringViewTest, WStringEqWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_eq<std::wstring> eq;
EXPECT_TRUE(eq(L"a", L"a"));
EXPECT_TRUE(eq(L"a", std::wstring_view(L"a")));
EXPECT_TRUE(eq(L"a", std::wstring(L"a")));
EXPECT_FALSE(eq(L"a", L"b"));
EXPECT_FALSE(eq(L"a", std::wstring_view(L"b")));
EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
#endif
}
TEST(BasicStringViewTest, WStringViewEqWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_eq<std::wstring_view> eq;
EXPECT_TRUE(eq(L"a", L"a"));
EXPECT_TRUE(eq(L"a", std::wstring_view(L"a")));
EXPECT_TRUE(eq(L"a", std::wstring(L"a")));
EXPECT_FALSE(eq(L"a", L"b"));
EXPECT_FALSE(eq(L"a", std::wstring_view(L"b")));
EXPECT_FALSE(eq(L"a", std::wstring(L"b")));
#endif
}
TEST(BasicStringViewTest, U16StringEqWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_eq<std::u16string> eq;
EXPECT_TRUE(eq(u"a", u"a"));
EXPECT_TRUE(eq(u"a", std::u16string_view(u"a")));
EXPECT_TRUE(eq(u"a", std::u16string(u"a")));
EXPECT_FALSE(eq(u"a", u"b"));
EXPECT_FALSE(eq(u"a", std::u16string_view(u"b")));
EXPECT_FALSE(eq(u"a", std::u16string(u"b")));
#endif
}
TEST(BasicStringViewTest, U16StringViewEqWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_eq<std::u16string_view> eq;
EXPECT_TRUE(eq(u"a", u"a"));
EXPECT_TRUE(eq(u"a", std::u16string_view(u"a")));
EXPECT_TRUE(eq(u"a", std::u16string(u"a")));
EXPECT_FALSE(eq(u"a", u"b"));
EXPECT_FALSE(eq(u"a", std::u16string_view(u"b")));
EXPECT_FALSE(eq(u"a", std::u16string(u"b")));
#endif
}
TEST(BasicStringViewTest, U32StringEqWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_eq<std::u32string> eq;
EXPECT_TRUE(eq(U"a", U"a"));
EXPECT_TRUE(eq(U"a", std::u32string_view(U"a")));
EXPECT_TRUE(eq(U"a", std::u32string(U"a")));
EXPECT_FALSE(eq(U"a", U"b"));
EXPECT_FALSE(eq(U"a", std::u32string_view(U"b")));
EXPECT_FALSE(eq(U"a", std::u32string(U"b")));
#endif
}
TEST(BasicStringViewTest, U32StringViewEqWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_eq<std::u32string_view> eq;
EXPECT_TRUE(eq(U"a", U"a"));
EXPECT_TRUE(eq(U"a", std::u32string_view(U"a")));
EXPECT_TRUE(eq(U"a", std::u32string(U"a")));
EXPECT_FALSE(eq(U"a", U"b"));
EXPECT_FALSE(eq(U"a", std::u32string_view(U"b")));
EXPECT_FALSE(eq(U"a", std::u32string(U"b")));
#endif
}
TEST(BasicStringViewTest, WStringHashWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_hash<std::wstring> hash;
auto h = hash(L"a");
EXPECT_EQ(h, hash(std::wstring_view(L"a")));
EXPECT_EQ(h, hash(std::wstring(L"a")));
EXPECT_NE(h, hash(std::wstring_view(L"b")));
EXPECT_NE(h, hash(std::wstring(L"b")));
#endif
}
TEST(BasicStringViewTest, WStringViewHashWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_hash<std::wstring_view> hash;
auto h = hash(L"a");
EXPECT_EQ(h, hash(std::wstring_view(L"a")));
EXPECT_EQ(h, hash(std::wstring(L"a")));
EXPECT_NE(h, hash(std::wstring_view(L"b")));
EXPECT_NE(h, hash(std::wstring(L"b")));
#endif
}
TEST(BasicStringViewTest, U16StringHashWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_hash<std::u16string> hash;
auto h = hash(u"a");
EXPECT_EQ(h, hash(std::u16string_view(u"a")));
EXPECT_EQ(h, hash(std::u16string(u"a")));
EXPECT_NE(h, hash(std::u16string_view(u"b")));
EXPECT_NE(h, hash(std::u16string(u"b")));
#endif
}
TEST(BasicStringViewTest, U16StringViewHashWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_hash<std::u16string_view> hash;
auto h = hash(u"a");
EXPECT_EQ(h, hash(std::u16string_view(u"a")));
EXPECT_EQ(h, hash(std::u16string(u"a")));
EXPECT_NE(h, hash(std::u16string_view(u"b")));
EXPECT_NE(h, hash(std::u16string(u"b")));
#endif
}
TEST(BasicStringViewTest, U32StringHashWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_hash<std::u32string> hash;
auto h = hash(U"a");
EXPECT_EQ(h, hash(std::u32string_view(U"a")));
EXPECT_EQ(h, hash(std::u32string(U"a")));
EXPECT_NE(h, hash(std::u32string_view(U"b")));
EXPECT_NE(h, hash(std::u32string(U"b")));
#endif
}
TEST(BasicStringViewTest, U32StringViewHashWorks) {
#ifndef ABSL_HAVE_STD_STRING_VIEW
GTEST_SKIP();
#else
hash_default_hash<std::u32string_view> hash;
auto h = hash(U"a");
EXPECT_EQ(h, hash(std::u32string_view(U"a")));
EXPECT_EQ(h, hash(std::u32string(U"a")));
EXPECT_NE(h, hash(std::u32string_view(U"b")));
EXPECT_NE(h, hash(std::u32string(U"b")));
#endif
}
struct NoDeleter {
template <class T>
void operator()(const T* ptr) const {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment