TypeList

// TypeList


#ifndef TYPE_LIST_HPP
#define TYPE_LIST_HPP #include <tuple> #include <type_traits> /* size -> get size of type list empty -> whether the list is empty push_front -> remove first type from type list front -> get first type from type list pop_front -> remove first element from list max_type -> return max type min_type -> return min type reverse -> reverse elements of list push_back -> add a new type to the last of type list pop_back -> remove last element from list back -> get last type from type list find_first_index_of -> ...... */ namespace my::type { using empty_list = std::tuple<>; // -------------to_type_list-------------- template <typename... Types> struct to_type_list : std::enable_if<true, std::tuple<Types...>> {}; template <template <typename...> typename TemplateClass, typename... Types> struct to_type_list<TemplateClass<Types...>> : std::enable_if<true, std::tuple<Types...>> {}; template <template <typename...> typename T, typename...> struct accept_parameters_from_type_list; template <template <typename...> typename TemplateClass, typename... Types> struct accept_parameters_from_type_list<TemplateClass, std::tuple<Types...>> { using type = TemplateClass<Types...>; }; // --------------type_size----------------- template <typename T> struct size; template <typename... Types> struct size<std::tuple<Types...>> : std::integral_constant<size_t, sizeof...(Types)> {}; // ------------------front--------------------------- template <typename T> struct front; template <typename T, typename... Types> struct front<std::tuple<T, Types...>> : std::enable_if<true, T> {}; // ------------------type_empty------------------------------ template <typename T> struct empty; template <typename... Types> struct empty<std::tuple<Types...>> : std::conditional_t<(sizeof...(Types) == 0), std::true_type, std::false_type> {}; // push T at the head of list template <typename T, typename... List> struct push_front; template <typename T, typename... Types> struct push_front<T, std::tuple<Types...>> : std::enable_if<true, std::tuple<T, Types...>> {}; // pop the first type of list template <typename List> struct pop_front; template <typename T, typename... Types> struct pop_front<std::tuple<T, Types...>> : std::enable_if<true, std::tuple<Types...>> {}; // max type template <typename List> struct max_type; template <typename T> struct max_type<std::tuple<T>> : std::enable_if<true, T> {}; template <typename T1, typename T2, typename... Types> struct max_type<std::tuple<T1, T2, Types...>> : std::conditional_t<(sizeof(T1) > sizeof(T2)), max_type<std::tuple<T1, Types...>>, max_type<std::tuple<T2, Types...>>> {}; // min type template <typename List> struct min_type; template <typename T> struct min_type<std::tuple<T>> : std::enable_if<true, T> {}; template <typename T1, typename T2, typename... Types> struct min_type<std::tuple<T1, T2, Types...>> : std::conditional_t<(sizeof(T1) < sizeof(T2)), min_type<std::tuple<T1, Types...>>, min_type<std::tuple<T2, Types...>>> {}; template <size_t Index, typename List> struct index_of; template <typename T, typename... Types> struct index_of<0, std::tuple<T, Types...>> : std::enable_if<true, T> {}; template <size_t Index, typename T1, typename T2, typename... Types> struct index_of<Index, std::tuple<T1, T2, Types...>> : index_of<Index - 1, std::tuple<T2, Types...>> {}; namespace hide { template <typename List1, typename List2> struct reverse_helper; template <typename T, typename... Types1, typename... Types2> struct reverse_helper<std::tuple<T, Types1...>, std::tuple<Types2...>> : reverse_helper<std::tuple<Types1...>, std::tuple<T, Types2...>> {}; template <typename... Types> struct reverse_helper<std::tuple<>, std::tuple<Types...>> : std::enable_if<true, std::tuple<Types...>> {}; } // namespace hide template <typename List> struct reverse; template <typename T> struct reverse<std::tuple<T>> : std::enable_if<true, std::tuple<T>> {}; template <typename T1, typename T2, typename... Types> struct reverse<std::tuple<T1, T2, Types...>> : hide::reverse_helper<std::tuple<T2, Types...>, std::tuple<T1>> {}; template <typename List> struct back; template <typename T> struct back<std::tuple<T>> : std::enable_if<true, T> {}; template <typename T, typename... Types> struct back<std::tuple<T, Types...>> : back<std::tuple<Types...>> {}; namespace hide { // another way in c++17 to implement back with O(1) instantiation depth template <typename... Types> struct select_last { using type = typename decltype((std::enable_if<true, Types>{}, ...))::type; }; } // namespace hide template <typename T, typename List> struct push_back; template <typename T, typename... Types> struct push_back<T, std::tuple<Types...>> : std::enable_if<true, std::tuple<Types..., T>> {}; template <typename List> struct pop_back; // template <typename T> // struct pop_back<std::tuple<T>> : std::enable_if<true, std::tuple<>> {}; // template <typename T, typename... Types> // struct pop_back<std::tuple<T, Types...>> // : reverse<typename pop_front< // typename reverse<std::tuple<T, Types...>>::type>::type> {}; namespace hide { template <typename List1, typename List2> struct pop_back_helper; template <typename... Types1, typename... Types2, typename T1, typename T2> struct pop_back_helper<std::tuple<Types1...>, std::tuple<T1, T2, Types2...>> : pop_back_helper<std::tuple<Types1..., T1>, std::tuple<T2, Types2...>> {}; template <typename... Types, typename T> struct pop_back_helper<std::tuple<Types...>, std::tuple<T>> : std::enable_if<true, std::tuple<Types...>> {}; } // namespace hide template <typename... Types> struct pop_back<std::tuple<Types...>> : hide::pop_back_helper<std::tuple<>, std::tuple<Types...>> {}; // find the first type in Typeist template <typename List, typename TargetType> struct find_first_index_of; namespace hide { template <size_t Index, typename List, typename TargetType> struct find_first_index_of_helper; template <size_t Index, typename T1, typename...Types, typename TargetType> struct find_first_index_of_helper<Index, std::tuple<T1, Types...>, TargetType> : std::conditional_t<std::is_same_v<T1, TargetType>, std::integral_constant<size_t, Index>, find_first_index_of_helper<Index + 1, std::tuple<Types...>, TargetType> > { }; constexpr size_t npos = static_cast<size_t>(-1); template <size_t Index, typename TargetType> struct find_first_index_of_helper<Index, std::tuple<>, TargetType> : std::integral_constant<size_t, npos> { }; } template <typename... Types, typename TargetType> struct find_first_index_of<std::tuple<Types...>, TargetType> : hide::find_first_index_of_helper<0, std::tuple<Types...>, TargetType> { }; // constexpr auto a = find_first_index_of<std::tuple<int, double, bool>, int>::value; // constexpr auto b = find_first_index_of<std::tuple<int, double, bool>, double>::value; // constexpr auto c = find_first_index_of<std::tuple<int, double, bool>, bool>::value; // constexpr auto d = find_first_index_of<std::tuple<int, double, bool>, char>::value; } // namespace my::type #endif
原文地址:https://www.cnblogs.com/MasterYan576356467/p/13256556.html