about summary refs log tree commit diff
path: root/absl/types
diff options
context:
space:
mode:
Diffstat (limited to 'absl/types')
-rw-r--r--absl/types/internal/variant.h3
-rw-r--r--absl/types/optional.h1
-rw-r--r--absl/types/optional_test.cc21
-rw-r--r--absl/types/variant_test.cc35
4 files changed, 25 insertions, 35 deletions
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h
index 477e5895ed73..a0ab1e8fdb26 100644
--- a/absl/types/internal/variant.h
+++ b/absl/types/internal/variant.h
@@ -1605,11 +1605,12 @@ struct VariantHashVisitor {
 template <typename Variant, typename... Ts>
 struct VariantHashBase<Variant,
                        absl::enable_if_t<absl::conjunction<
-                           type_traits_internal::IsHashEnabled<Ts>...>::value>,
+                           type_traits_internal::IsHashable<Ts>...>::value>,
                        Ts...> {
   using argument_type = Variant;
   using result_type = size_t;
   size_t operator()(const Variant& var) const {
+    type_traits_internal::AssertHashEnabled<Ts...>();
     if (var.valueless_by_exception()) {
       return 239799884;
     }
diff --git a/absl/types/optional.h b/absl/types/optional.h
index 7677fe52c0e5..fd185f353f3e 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -467,6 +467,7 @@ struct optional_hash_base<T, decltype(std::hash<absl::remove_const_t<T> >()(
   using argument_type = absl::optional<T>;
   using result_type = size_t;
   size_t operator()(const absl::optional<T>& opt) const {
+    absl::type_traits_internal::AssertHashEnabled<absl::remove_const_t<T>>();
     if (opt) {
       return std::hash<absl::remove_const_t<T> >()(*opt);
     } else {
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
index fc4f00a4f52f..bedf5b0e043e 100644
--- a/absl/types/optional_test.cc
+++ b/absl/types/optional_test.cc
@@ -1504,18 +1504,19 @@ TEST(optionalTest, Hash) {
 
   static_assert(is_hash_enabled_for<absl::optional<int>>::value, "");
   static_assert(is_hash_enabled_for<absl::optional<Hashable>>::value, "");
+  static_assert(
+      absl::type_traits_internal::IsHashable<absl::optional<int>>::value, "");
+  static_assert(
+      absl::type_traits_internal::IsHashable<absl::optional<Hashable>>::value,
+      "");
+  absl::type_traits_internal::AssertHashEnabled<absl::optional<int>>();
+  absl::type_traits_internal::AssertHashEnabled<absl::optional<Hashable>>();
 
-#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \
-                          _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11)
-  // For MSVC and libc++ (< 4.0 and c++14), std::hash primary template has a
-  // static_assert to catch any user-defined type that doesn't provide a hash
-  // specialization. So instantiating std::hash<absl::optional<T>> will result
-  // in a hard error which is not SFINAE friendly.
-#define ABSL_STD_HASH_NOT_SFINAE_FRIENDLY 1
-#endif
-
-#ifndef ABSL_STD_HASH_NOT_SFINAE_FRIENDLY
+#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
   static_assert(!is_hash_enabled_for<absl::optional<NonHashable>>::value, "");
+  static_assert(!absl::type_traits_internal::IsHashable<
+                    absl::optional<NonHashable>>::value,
+                "");
 #endif
 
   // libstdc++ std::optional is missing remove_const_t, i.e. it's using
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc
index 80e8467e1f14..463d775a85fe 100644
--- a/absl/types/variant_test.cc
+++ b/absl/types/variant_test.cc
@@ -1977,29 +1977,17 @@ TEST(VariantTest, MonostateHash) {
 }
 
 TEST(VariantTest, Hash) {
-  static_assert(type_traits_internal::IsHashEnabled<variant<int>>::value, "");
-  static_assert(type_traits_internal::IsHashEnabled<variant<Hashable>>::value,
+  static_assert(type_traits_internal::IsHashable<variant<int>>::value, "");
+  static_assert(type_traits_internal::IsHashable<variant<Hashable>>::value, "");
+  static_assert(type_traits_internal::IsHashable<variant<int, Hashable>>::value,
                 "");
-  static_assert(
-      type_traits_internal::IsHashEnabled<variant<int, Hashable>>::value, "");
-
-#if defined(_MSC_VER) ||                                   \
-    (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 4000 && \
-     _LIBCPP_STD_VER > 11) ||                              \
-    defined(__APPLE__)
-  // For MSVC and libc++ (< 4.0 and c++14), std::hash primary template has a
-  // static_assert to catch any user-defined type T that doesn't provide a hash
-  // specialization. So instantiating std::hash<variant<T>> will result
-  // in a hard error which is not SFINAE friendly.
-#define ABSL_STD_HASH_NOT_SFINAE_FRIENDLY 1
-#endif
 
-#ifndef ABSL_STD_HASH_NOT_SFINAE_FRIENDLY
-  static_assert(
-      !type_traits_internal::IsHashEnabled<variant<NonHashable>>::value, "");
-  static_assert(!type_traits_internal::IsHashEnabled<
-                    variant<Hashable, NonHashable>>::value,
+#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
+  static_assert(!type_traits_internal::IsHashable<variant<NonHashable>>::value,
                 "");
+  static_assert(
+      !type_traits_internal::IsHashable<variant<Hashable, NonHashable>>::value,
+      "");
 #endif
 
 // MSVC std::hash<std::variant> does not use the index, thus produce the same
@@ -2023,11 +2011,10 @@ TEST(VariantTest, Hash) {
     EXPECT_GT(hashcodes.size(), 90);
 
     // test const-qualified
+    static_assert(type_traits_internal::IsHashable<variant<const int>>::value,
+                  "");
     static_assert(
-        type_traits_internal::IsHashEnabled<variant<const int>>::value, "");
-    static_assert(
-        type_traits_internal::IsHashEnabled<variant<const Hashable>>::value,
-        "");
+        type_traits_internal::IsHashable<variant<const Hashable>>::value, "");
     std::hash<absl::variant<const int>> c_hash;
     for (int i = 0; i < 100; ++i) {
       EXPECT_EQ(hash(i), c_hash(i));