type_traits: is_equality_comparable, support for standard containers
This commit is contained in:
@@ -12,6 +12,32 @@
|
||||
namespace entt {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Utility class to disambiguate overloaded functions.
|
||||
* @tparam N Number of choices available.
|
||||
*/
|
||||
template<std::size_t N>
|
||||
struct choice_t
|
||||
// Unfortunately, doxygen cannot parse such a construct.
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
: choice_t<N-1>
|
||||
/*! @endcond */
|
||||
{};
|
||||
|
||||
|
||||
/*! @copybrief choice_t */
|
||||
template<>
|
||||
struct choice_t<0> {};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Variable template for the choice trick.
|
||||
* @tparam N Number of choices available.
|
||||
*/
|
||||
template<std::size_t N>
|
||||
inline constexpr choice_t<N> choice{};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Identity type trait.
|
||||
*
|
||||
@@ -93,32 +119,6 @@ template<id_type Value>
|
||||
using tag = integral_constant<Value>;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Utility class to disambiguate overloaded functions.
|
||||
* @tparam N Number of choices available.
|
||||
*/
|
||||
template<std::size_t N>
|
||||
struct choice_t
|
||||
// Unfortunately, doxygen cannot parse such a construct.
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
: choice_t<N-1>
|
||||
/*! @endcond */
|
||||
{};
|
||||
|
||||
|
||||
/*! @copybrief choice_t */
|
||||
template<>
|
||||
struct choice_t<0> {};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Variable template for the choice trick.
|
||||
* @tparam N Number of choices available.
|
||||
*/
|
||||
template<std::size_t N>
|
||||
inline constexpr choice_t<N> 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<typename... List>
|
||||
using value_list_cat_t = typename value_list_cat<List...>::type;
|
||||
|
||||
|
||||
/**
|
||||
* @cond TURN_OFF_DOXYGEN
|
||||
* Internal details not to be documented.
|
||||
*/
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
template<typename Type>
|
||||
constexpr auto is_equality_comparable()
|
||||
-> decltype(is_equality_comparable<Type>(choice<2>));
|
||||
|
||||
|
||||
template<typename Type>
|
||||
constexpr auto is_equality_comparable(choice_t<2>)
|
||||
-> decltype(
|
||||
std::declval<typename Type::mapped_type>(),
|
||||
std::declval<Type>() == std::declval<Type>(),
|
||||
std::conjunction<decltype(is_equality_comparable<typename Type::key_type>()), decltype(is_equality_comparable<typename Type::mapped_type>())>{}
|
||||
);
|
||||
|
||||
|
||||
template<typename Type>
|
||||
constexpr auto is_equality_comparable(choice_t<1>)
|
||||
-> decltype(
|
||||
std::declval<typename Type::value_type>(),
|
||||
std::declval<Type>() == std::declval<Type>(),
|
||||
is_equality_comparable<typename Type::value_type>()
|
||||
);
|
||||
|
||||
|
||||
template<typename Type>
|
||||
constexpr auto is_equality_comparable(choice_t<0>)
|
||||
-> decltype(std::declval<Type>() == std::declval<Type>(), std::true_type{});
|
||||
|
||||
|
||||
template<typename>
|
||||
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<typename Type, typename = void>
|
||||
struct is_equality_comparable: std::false_type {};
|
||||
|
||||
|
||||
/*! @copydoc is_equality_comparable */
|
||||
template<typename Type>
|
||||
struct is_equality_comparable<Type, std::void_t<decltype(std::declval<Type>() == std::declval<Type>())>>
|
||||
: std::true_type
|
||||
{};
|
||||
struct is_equality_comparable: decltype(internal::is_equality_comparable<Type>()) {};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/any.hpp>
|
||||
|
||||
@@ -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<int, not_comparable>{});
|
||||
test(std::vector<not_comparable>{});
|
||||
}
|
||||
|
||||
TEST(Any, CompareVoid) {
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/config/config.h>
|
||||
#include <entt/core/hashed_string.hpp>
|
||||
#include <entt/core/type_traits.hpp>
|
||||
|
||||
struct not_comparable {
|
||||
bool operator==(const not_comparable &) const = delete;
|
||||
};
|
||||
|
||||
TEST(TypeTraits, SizeOf) {
|
||||
static_assert(entt::size_of_v<void> == 0u);
|
||||
static_assert(entt::size_of_v<char> == sizeof(char));
|
||||
@@ -79,6 +85,13 @@ TEST(TypeTraits, ValueList) {
|
||||
|
||||
TEST(TypeTraits, IsEqualityComparable) {
|
||||
static_assert(entt::is_equality_comparable_v<int>);
|
||||
static_assert(entt::is_equality_comparable_v<std::vector<int>>);
|
||||
static_assert(entt::is_equality_comparable_v<std::unordered_map<int, int>>);
|
||||
|
||||
static_assert(!entt::is_equality_comparable_v<not_comparable>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::vector<not_comparable>>);
|
||||
static_assert(!entt::is_equality_comparable_v<std::unordered_map<int, not_comparable>>);
|
||||
|
||||
static_assert(!entt::is_equality_comparable_v<void>);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user