Просмотр исходного кода

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

Michele Caini 6 лет назад
Родитель
Сommit
b8dd6822ac
3 измененных файлов с 97 добавлено и 2 удалено
  1. 82 2
      src/entt/core/type_traits.hpp
  2. 1 0
      test/CMakeLists.txt
  3. 14 0
      test/entt/core/type_traits.cpp

+ 82 - 2
src/entt/core/type_traits.hpp

@@ -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. */

+ 1 - 0
test/CMakeLists.txt

@@ -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

+ 14 - 0
test/entt/core/type_traits.cpp

@@ -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>>));
+}