#pragma once #include #include namespace kel { template constexpr bool is_always_false = false; template struct unit_component; template class unit; namespace impl { template class unit_matching; template class unit_redux_list { static_assert(sizeof...(T) == 0, "Template type not supported"); using reduced_typed = unit_redux_list<>; }; template struct unit_redux_list, unit_component...> { using reduced_type = typename unit_matching, unit_component...>, unit_redux_list<>>::type; }; template class unit_matching_reduce { public: static_assert(is_always_false, "Template type not supported"); }; template class unit_matching_reduce, unit_redux_list,unit_component...>, unit_redux_list...>> { public: static constexpr bool is_same = std::is_same_v; using match_reduce_type = typename std::conditional, unit_component>::type; using match_reduce_unit_redux_list = typename std::conditional...>, unit_redux_list..., unit_component>>::type; using value_type = typename unit_matching_reduce...>, match_reduce_unit_redux_list>::value_type; using unit_redux_list_type = typename unit_matching_reduce...>, match_reduce_unit_redux_list>::unit_redux_list_type; static constexpr int64_t value_num = unit_matching_reduce...>, match_reduce_unit_redux_list>::value_num; }; template class unit_matching_reduce, unit_redux_list<>, unit_redux_list...>> { public: using value_type = unit_component; using unit_redux_list_type = unit_redux_list...>; static constexpr int64_t value_num = E; }; template class unit_matching { static_assert(is_always_false, "Template type not supported"); }; template class unit_matching,unit_redux_list...>> { public: using type = unit_redux_list...>; }; template class unit_matching,unit_component...>, unit_redux_list...>> { public: using reduced_value_type = typename unit_matching_reduce, unit_redux_list...>, unit_redux_list<>>::value_type; using reduced_unit_redux_list_type = typename unit_matching_reduce, unit_redux_list...>, unit_redux_list<>>::unit_redux_list_type; static constexpr int64_t reduced_value_num = unit_matching_reduce, unit_redux_list...>, unit_redux_list<>>::value_num; using reduced_result_unit_redux_list = typename std::conditional...>, unit_redux_list...,reduced_value_type>>::type; using type = typename unit_matching::type; }; template class unit_matching_add_storage { public: static_assert(is_always_false, "Template type not supported"); }; template class unit_matching_add_storage...>, StorageT> { public: using type = unit...>; }; } template class unit_reduction { static_assert(is_always_false, "Template type not supported"); }; template class unit_reduction...> { public: using list_type = typename impl::unit_matching...>, impl::unit_redux_list<>>::type; using type = typename impl::unit_matching_add_storage::type; }; template class unit_invert { static_assert(is_always_false, "Template type not supported"); }; template class unit_invert...> { public: using type = unit...>; }; template class unit_multiplication{ static_assert(is_always_false, "Template type not supported"); }; template class unit_multiplication...>, unit...>> { public: using type = typename unit_reduction..., unit_component...>::type; }; }