diff --git a/src/entt/core/type_traits.hpp b/src/entt/core/type_traits.hpp index 635a93354..b81ce3026 100644 --- a/src/entt/core/type_traits.hpp +++ b/src/entt/core/type_traits.hpp @@ -12,6 +12,32 @@ namespace entt { +/** + * @brief Utility class to disambiguate overloaded functions. + * @tparam N Number of choices available. + */ +template +struct choice_t + // Unfortunately, doxygen cannot parse such a construct. + /*! @cond TURN_OFF_DOXYGEN */ + : choice_t + /*! @endcond */ +{}; + + +/*! @copybrief choice_t */ +template<> +struct choice_t<0> {}; + + +/** + * @brief Variable template for the choice trick. + * @tparam N Number of choices available. + */ +template +inline constexpr choice_t choice{}; + + /** * @brief Identity type trait. * @@ -93,32 +119,6 @@ template using tag = integral_constant; -/** - * @brief Utility class to disambiguate overloaded functions. - * @tparam N Number of choices available. - */ -template -struct choice_t - // Unfortunately, doxygen cannot parse such a construct. - /*! @cond TURN_OFF_DOXYGEN */ - : choice_t - /*! @endcond */ -{}; - - -/*! @copybrief choice_t */ -template<> -struct choice_t<0> {}; - - -/** - * @brief Variable template for the choice trick. - * @tparam N Number of choices available. - */ -template -inline constexpr choice_t choice{}; - - /** * @brief A class to use to push around lists of types, nothing more. * @tparam Type Types provided by the type list. @@ -396,20 +396,63 @@ template using value_list_cat_t = typename value_list_cat::type; +/** + * @cond TURN_OFF_DOXYGEN + * Internal details not to be documented. + */ + + +namespace internal { + + +template +constexpr auto is_equality_comparable() +-> decltype(is_equality_comparable(choice<2>)); + + +template +constexpr auto is_equality_comparable(choice_t<2>) +-> decltype( + std::declval(), + std::declval() == std::declval(), + std::conjunction()), decltype(is_equality_comparable())>{} +); + + +template +constexpr auto is_equality_comparable(choice_t<1>) +-> decltype( + std::declval(), + std::declval() == std::declval(), + is_equality_comparable() +); + + +template +constexpr auto is_equality_comparable(choice_t<0>) +-> decltype(std::declval() == std::declval(), std::true_type{}); + + +template +constexpr std::false_type is_equality_comparable(...); + + +} + + +/** + * Internal details not to be documented. + * @endcond + */ + + /** * @brief Provides the member constant `value` to true if a given type is * equality comparable, false otherwise. * @tparam Type Potentially equality comparable type. */ template -struct is_equality_comparable: std::false_type {}; - - -/*! @copydoc is_equality_comparable */ -template -struct is_equality_comparable() == std::declval())>> - : std::true_type -{}; +struct is_equality_comparable: decltype(internal::is_equality_comparable()) {}; /** diff --git a/test/entt/core/any.cpp b/test/entt/core/any.cpp index 494536603..ba9534338 100644 --- a/test/entt/core/any.cpp +++ b/test/entt/core/any.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include @@ -736,15 +738,21 @@ TEST(Any, Comparable) { } TEST(Any, NotComparable) { - entt::any any{not_comparable{}}; + auto test = [](const auto &instance) { + entt::any any{std::cref(instance)}; - ASSERT_EQ(any, any); - ASSERT_NE(any, entt::any{not_comparable{}}); - ASSERT_NE(entt::any{}, any); + ASSERT_EQ(any, any); + ASSERT_NE(any, entt::any{instance}); + ASSERT_NE(entt::any{}, any); - ASSERT_TRUE(any == any); - ASSERT_FALSE(any == entt::any{not_comparable{}}); - ASSERT_TRUE(entt::any{} != any); + ASSERT_TRUE(any == any); + ASSERT_FALSE(any == entt::any{instance}); + ASSERT_TRUE(entt::any{} != any); + }; + + test(not_comparable{}); + test(std::unordered_map{}); + test(std::vector{}); } TEST(Any, CompareVoid) { diff --git a/test/entt/core/type_traits.cpp b/test/entt/core/type_traits.cpp index fdf69adeb..bbaabcd57 100644 --- a/test/entt/core/type_traits.cpp +++ b/test/entt/core/type_traits.cpp @@ -1,10 +1,16 @@ #include #include +#include +#include #include #include #include #include +struct not_comparable { + bool operator==(const not_comparable &) const = delete; +}; + TEST(TypeTraits, SizeOf) { static_assert(entt::size_of_v == 0u); static_assert(entt::size_of_v == sizeof(char)); @@ -79,6 +85,13 @@ TEST(TypeTraits, ValueList) { TEST(TypeTraits, IsEqualityComparable) { static_assert(entt::is_equality_comparable_v); + static_assert(entt::is_equality_comparable_v>); + static_assert(entt::is_equality_comparable_v>); + + static_assert(!entt::is_equality_comparable_v); + static_assert(!entt::is_equality_comparable_v>); + static_assert(!entt::is_equality_comparable_v>); + static_assert(!entt::is_equality_comparable_v); }