Browse Source

type_traits: further refine is_equality_comparable[_v] to avoid specializations

Michele Caini 2 years ago
parent
commit
206d2f623d
1 changed files with 12 additions and 11 deletions
  1. 12 11
      src/entt/core/type_traits.hpp

+ 12 - 11
src/entt/core/type_traits.hpp

@@ -3,7 +3,6 @@
 
 
 #include <cstddef>
 #include <cstddef>
 #include <iterator>
 #include <iterator>
-#include <optional>
 #include <tuple>
 #include <tuple>
 #include <type_traits>
 #include <type_traits>
 #include <utility>
 #include <utility>
@@ -786,23 +785,30 @@ template<typename>
 
 
 template<typename Type>
 template<typename Type>
 [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
 [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
+    return true;
+}
+
+template<typename Type>
+[[nodiscard]] constexpr auto dispatch_is_equality_comparable() {
     if constexpr(has_tuple_size_value<Type>::value) {
     if constexpr(has_tuple_size_value<Type>::value) {
-        return unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
+        return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
     } else if constexpr(has_value_type<Type>::value) {
     } else if constexpr(has_value_type<Type>::value) {
         if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type>) {
         if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type>) {
-            return true;
+            return maybe_equality_comparable<Type>(0);
+        } else if constexpr(is_equality_comparable<typename Type::value_type>::value) {
+            return maybe_equality_comparable<Type>(0);
         } else {
         } else {
-            return is_equality_comparable<typename Type::value_type>::value;
+            return false;
         }
         }
     } else {
     } else {
-        return true;
+        return maybe_equality_comparable<Type>(0);
     }
     }
 }
 }
 
 
 } // namespace internal
 } // namespace internal
 
 
 template<typename Type>
 template<typename Type>
-struct is_equality_comparable: std::bool_constant<internal::maybe_equality_comparable<Type>(0)> {};
+struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
 
 
 /**
 /**
  * Internal details not to be documented.
  * Internal details not to be documented.
@@ -813,11 +819,6 @@ struct is_equality_comparable: std::bool_constant<internal::maybe_equality_compa
 template<typename Type, auto N>
 template<typename Type, auto N>
 struct is_equality_comparable<Type[N]>: std::false_type {};
 struct is_equality_comparable<Type[N]>: std::false_type {};
 
 
-/*! @copydoc is_equality_comparable */
-template<typename Type>
-// std::optional has a non sfinae-friendly comparison operator :(
-struct is_equality_comparable<std::optional<Type>>: is_equality_comparable<typename std::optional<Type>::value_type> {};
-
 /**
 /**
  * @brief Helper variable template.
  * @brief Helper variable template.
  * @tparam Type The type to test.
  * @tparam Type The type to test.