type_list_cat[_t]/type_list_unique[_t] (close #238)

This commit is contained in:
Michele Caini
2019-05-02 22:54:34 +02:00
parent 8c47b85b9b
commit b8dd6822ac
3 changed files with 97 additions and 2 deletions

View File

@@ -9,9 +9,89 @@
namespace entt {
/*! @brief A class to use to push around lists of types, nothing more. */
/**
* @brief A class to use to push around lists of types, nothing more.
* @tparam Type Types provided by the given type list.
*/
template<typename... Type>
struct type_list {};
struct type_list {
/*! @brief Unsigned integer type. */
static constexpr auto size = sizeof...(Type);
};
/*! @brief Primary template isn't defined on purpose. */
template<typename...>
struct type_list_cat;
/**
* @brief Concatenates multiple type lists.
* @tparam Type Types provided by the first type list.
* @tparam Other Types provided by the second type list.
* @tparam List Other type lists, if any.
*/
template<typename... Type, typename... Other, typename... List>
struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
/*! @brief A type list composed by the types of all the type lists. */
using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
};
/**
* @brief Concatenates multiple type lists.
* @tparam Type Types provided by the type list.
*/
template<typename... Type>
struct type_list_cat<type_list<Type...>> {
/*! @brief A type list composed by the types of all the type lists. */
using type = type_list<Type...>;
};
/**
* @brief Helper type.
* @tparam List Type lists to concatenate.
*/
template<typename... List>
using type_list_cat_t = typename type_list_cat<List...>::type;
/*! @brief Primary template isn't defined on purpose. */
template<typename>
struct type_list_unique;
/**
* @brief Removes duplicates types from a type list.
* @tparam Type One of the types provided by the given type list.
* @tparam Other The other types provided by the given type list.
*/
template<typename Type, typename... Other>
struct type_list_unique<type_list<Type, Other...>> {
/*! @brief A type list without duplicate types. */
using type = std::conditional_t<
std::disjunction_v<std::is_same<Type, Other>...>,
typename type_list_unique<type_list<Other...>>::type,
type_list_cat_t<type_list<Type>, typename type_list_unique<type_list<Other...>>::type>
>;
};
/*! @brief Removes duplicates types from a type list. */
template<>
struct type_list_unique<type_list<>> {
/*! @brief A type list without duplicate types. */
using type = type_list<>;
};
/**
* @brief Helper type.
* @tparam Type A type list.
*/
template<typename Type>
using type_list_unique_t = typename type_list_unique<Type>::type;
/*! @brief Traits class used mainly to push things across boundaries. */

View File

@@ -87,6 +87,7 @@ SETUP_AND_ADD_TEST(family entt/core/family.cpp)
SETUP_AND_ADD_TEST(hashed_string entt/core/hashed_string.cpp)
SETUP_AND_ADD_TEST(ident entt/core/ident.cpp)
SETUP_AND_ADD_TEST(monostate entt/core/monostate.cpp)
SETUP_AND_ADD_TEST(type_traits entt/core/type_traits.cpp)
SETUP_AND_ADD_TEST(utility entt/core/utility.cpp)
# Test entity

View File

@@ -0,0 +1,14 @@
#include <gtest/gtest.h>
#include <entt/core/type_traits.hpp>
TEST(TypeList, Functionalities) {
using type = entt::type_list<int, char>;
using other = entt::type_list<double>;
ASSERT_EQ((type::size), (decltype(type::size){2}));
ASSERT_EQ((other::size), (decltype(other::size){1}));
ASSERT_TRUE((std::is_same_v<entt::type_list_cat_t<type, other, type, other>, entt::type_list<int, char, double, int, char, double>>));
ASSERT_TRUE((std::is_same_v<entt::type_list_cat_t<type, other>, entt::type_list<int, char, double>>));
ASSERT_TRUE((std::is_same_v<entt::type_list_cat_t<type, type>, entt::type_list<int, char, int, char>>));
ASSERT_TRUE((std::is_same_v<entt::type_list_unique_t<entt::type_list_cat_t<type, type>>, entt::type_list<int, char>>));
}