From 88a152ae747c3c42dc9167d46c590929b048d436 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 8 Mar 2019 14:06:50 -0800 Subject: Export of internal Abseil changes. -- 5dc8d7504b7c11710b19365a6582c288c8992366 by Derek Mauro : Fix constexpr Span::last under MSVC and add Span constexpr tests. PiperOrigin-RevId: 237515952 -- 5ea8c146e653bbc49ff7e698699478242df7de35 by Derek Mauro : Implement Span::first and Span::last from C++20. https://github.com/abseil/abseil-cpp/pull/274 PiperOrigin-RevId: 237494399 -- 08db3417f1d8fe4556255d57a2f0df51b09bdd9a by Derek Mauro : HTTPS in more URLs. PiperOrigin-RevId: 237486823 -- 83ec63a7f8e47b62af619546f9f7b3bf72e74e86 by Derek Mauro : Changed HTTP URLs to HTTPS where possible. https://github.com/abseil/abseil-cpp/pull/270 PiperOrigin-RevId: 237445310 -- 220bf279c14cb31efa239500d1a70e0ac0c32e3c by Abseil Team : Support parsing decltype(nullptr) as a type. PiperOrigin-RevId: 237336739 -- ced234bbe78f5d495c3f6f6a9c2e0a95f7c080a5 by Gennadiy Rozental : Introduce internal interface for setting environment variable value in scope PiperOrigin-RevId: 237275806 -- 1f1acb4e294af24d9f7598e85163d5e1d9958ae9 by Samuel Benzaquen : Avoid using aliases in the SFINAE expressions to make it more compatible with MSVC. Turn on the tests in MSVC. PiperOrigin-RevId: 237261456 -- 06cf7de6250a0572ef90fa1176f742ca0451ce71 by Derek Mauro : Fix unused variable warning. PiperOrigin-RevId: 237108006 GitOrigin-RevId: 5dc8d7504b7c11710b19365a6582c288c8992366 Change-Id: Ife5182c80942945c4e8700844c8febb482d6ad82 --- absl/hash/hash_test.cc | 22 +++---- absl/hash/internal/hash.h | 161 ++++++++++++++++++---------------------------- 2 files changed, 72 insertions(+), 111 deletions(-) (limited to 'absl/hash') diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index d9ebd30f69c4..a2430e7a653d 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -165,9 +165,6 @@ TEST(HashValueTest, PointerAlignment) { } } -// TODO(EricWF): MSVC 15 has a bug that causes it to incorrectly evaluate the -// SFINAE in internal/hash.h, causing this test to fail. -#if !defined(_MSC_VER) TEST(HashValueTest, PairAndTuple) { EXPECT_TRUE((is_hashable>::value)); EXPECT_TRUE((is_hashable>::value)); @@ -196,7 +193,6 @@ TEST(HashValueTest, PairAndTuple) { std::forward_as_tuple(42, 0, 0), std::forward_as_tuple(3, 9, 9), std::forward_as_tuple(0, 0, -42)))); } -#endif // !defined(_MSC_VER) TEST(HashValueTest, CombineContiguousWorks) { std::vector> v1 = {std::make_tuple(1), std::make_tuple(3)}; @@ -304,16 +300,12 @@ TEST(HashValueTest, Strings) { SpyHash(absl::string_view("ABC"))); } -// TODO(EricWF): MSVC 15 has a bug that causes it to incorrectly evaluate the -// SFINAE in internal/hash.h, causing this test to fail. -#if !defined(_MSC_VER) TEST(HashValueTest, StdArray) { EXPECT_TRUE((is_hashable>::value)); EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( std::make_tuple(std::array{}, std::array{{0, 23, 42}}))); } -#endif // !defined(_MSC_VER) TEST(HashValueTest, StdBitset) { EXPECT_TRUE((is_hashable>::value)); @@ -414,9 +406,6 @@ TEST(HashValueTest, Variant) { #endif } -// TODO(EricWF): MSVC 15 has a bug that causes it to incorrectly evaluate the -// SFINAE in internal/hash.h, causing this test to fail. -#if !defined(_MSC_VER) TEST(HashValueTest, Maps) { EXPECT_TRUE((is_hashable>::value)); @@ -433,7 +422,6 @@ TEST(HashValueTest, Maps) { MM{{0, "foo"}, {42, "bar"}}, MM{{1, "foo"}, {42, "bar"}}, MM{{1, "foo"}, {1, "foo"}, {43, "bar"}}, MM{{1, "foo"}, {43, "baz"}}))); } -#endif // !defined(_MSC_VER) template struct IsHashCallble : std::false_type {}; @@ -511,8 +499,16 @@ struct CombineVariadic { Int(4)); } }; +enum class InvokeTag { + kUniquelyRepresented, + kHashValue, +#if ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ + kLegacyHash, +#endif // ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ + kStdHash, + kNone +}; -using InvokeTag = absl::hash_internal::InvokeHashTag; template using InvokeTagConstant = std::integral_constant; diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 2a45bc84ab18..9ab9890143dd 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -535,20 +535,6 @@ hash_range_or_bytes(H hash_state, const T* data, size_t size) { return hash_state; } -// InvokeHashTag -// -// InvokeHash(H, const T&) invokes the appropriate hash implementation for a -// hasher of type `H` and a value of type `T`. If `T` is not hashable, there -// will be no matching overload of InvokeHash(). -// Note: Some platforms (eg MSVC) do not support the detect idiom on -// std::hash. In those platforms the last fallback will be std::hash and -// InvokeHash() will always have a valid overload even if std::hash is not -// valid. -// -// We try the following options in order: -// * If is_uniquely_represented, hash bytes directly. -// * ADL AbslHashValue(H, const T&) call. -// * std::hash #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \ ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1 @@ -556,23 +542,15 @@ hash_range_or_bytes(H hash_state, const T* data, size_t size) { #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0 #endif -enum class InvokeHashTag { - kUniquelyRepresented, - kHashValue, -#if ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ - kLegacyHash, -#endif // ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ - kStdHash, - kNone -}; - // HashSelect // // Type trait to select the appropriate hash implementation to use. -// HashSelect::value is an instance of InvokeHashTag that indicates the best -// available hashing mechanism. -// See `Note` above about MSVC. -template +// HashSelect::type will give the proper hash implementation, to be invoked +// as: +// HashSelect::type::Invoke(state, value) +// Also, HashSelect::type::value is a boolean equal to `true` if there is a +// valid `Invoke` function. Types that are not hashable will have a ::value of +// `false`. struct HashSelect { private: struct State : HashStateBase { @@ -581,89 +559,75 @@ struct HashSelect { using State::HashStateBase::combine_contiguous; }; - // `Probe::value` evaluates to `V::value` if it is a valid - // expression, and `false` otherwise. - // `Probe::tag` always evaluates to `Tag`. - template