From b8e47b67200adb18a3485bb6da17a21676053a1f Mon Sep 17 00:00:00 2001 From: Zifeng Deng Date: Tue, 24 Oct 2023 20:43:33 +0800 Subject: [PATCH 1/2] feat(mpl): more functors for `type_list` last, drop_last, find_if, set, split --- include/co_context/mpl/type_list.hpp | 152 +++++++++++++++++++++++++++ test/mpl_type_list.cpp | 44 +++++++- 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/include/co_context/mpl/type_list.hpp b/include/co_context/mpl/type_list.hpp index 56a9b2a..35c4fb8 100644 --- a/include/co_context/mpl/type_list.hpp +++ b/include/co_context/mpl/type_list.hpp @@ -83,6 +83,36 @@ struct tails> { template using tails_t = typename tails::type; +template + requires(in::size > 0) +struct last; + +template +struct last> { + using type = H; +}; + +template +struct last> : last> {}; + +template +using last_t = typename last::type; + +template> +struct drop_last; + +template +struct drop_last, out> { + using type = out; +}; + +template +struct drop_last, out> + : drop_last, typename out::template append> {}; + +template +using drop_last_t = typename drop_last::type; + template class F> struct map; @@ -194,6 +224,25 @@ namespace detail { std::is_same_v, std::integral_constant, find_impl, E, offset + 1>> {}; + + template typename P, size_t offset> + struct find_if_impl; + + template typename P, size_t offset> + struct find_if_impl, P, offset> + : std::integral_constant {}; + + template< + template + typename P, + typename H, + typename... Ts, + size_t offset> + struct find_if_impl, P, offset> + : std::conditional_t< + P::value, + std::integral_constant, + find_if_impl, P, offset + 1>> {}; } // namespace detail template @@ -205,6 +254,15 @@ using find_t = typename find::type; template constexpr size_t find_v = find::value; +template typename P> +struct find_if : detail::find_if_impl {}; + +template typename P> +using find_if_t = typename find_if::type; + +template typename P> +constexpr size_t find_if_v = find_if::value; + template class unique { template @@ -283,6 +341,100 @@ struct replace { template using replace_t = typename replace::type; +template +struct union_set { + using type = unique_t>; +}; + +template +using union_set_t = typename union_set::type; + +template +class intersection_set { + template + using in1_contain = contain; + + public: + using type = filter_t; +}; + +template +using intersection_set_t = typename intersection_set::type; + +template +class difference_set { + template + struct in2_contain : contain {}; + + public: + using type = remove_if_t; +}; + +template +using difference_set_t = typename difference_set::type; + +template +struct symmetric_difference_set { + using type = + concat_t, difference_set_t>; +}; + +template +using symmetric_difference_set_t = + typename symmetric_difference_set::type; + +template< + TL in, + template + typename P, + typename out = type_list>> +struct split_if; + +template typename P, typename out> +struct split_if, P, out> { + private: + using no_empty_t = remove_t>; + using reverse_outer_t = reverse_t; + + public: + using type = reverse_outer_t; +}; + +template< + template + typename P, + typename H, + typename... Ts, + typename head_list, + typename... lists> +struct split_if, P, type_list> + : std::conditional_t< + P::value, + split_if< + type_list, + P, + type_list, head_list, lists...>>, + split_if< + type_list, + P, + type_list, lists...>>> {}; + +template typename P> +using split_if_t = typename split_if::type; + +template +struct split { + private: + template + struct is_delimiter : std::is_same {}; + + public: + using type = split_if_t; +}; + +template +using split_t = typename split::type; + } // namespace co_context::mpl namespace co_context::mpl::detail { diff --git a/test/mpl_type_list.cpp b/test/mpl_type_list.cpp index 9dcfbf6..7c716f2 100644 --- a/test/mpl_type_list.cpp +++ b/test/mpl_type_list.cpp @@ -8,10 +8,16 @@ struct s {}; using list = mpl::type_list; using empty = mpl::type_list<>; -void head_tails() { +void head_tails_last() { static_assert(std::is_same_v, char>); static_assert(std::is_same_v< mpl::tails_t, mpl::type_list>); + static_assert(std::is_same_v, double>); +} + +void drop_last() { + using no_last = mpl::type_list; + static_assert(std::is_same_v, no_last>); } void from_to() { @@ -81,6 +87,9 @@ void find() { static_assert(mpl::find_v == 2); static_assert(mpl::find_v == 3); static_assert(mpl::find_v == mpl::npos); + + static_assert(mpl::find_if_v == 2); + static_assert(mpl::find_if_v == mpl::npos); } void reverse() { @@ -122,5 +131,38 @@ void replace() { mpl::replace_t, int_to_void_list>); } +void set() { + using a = mpl::type_list; + using b = mpl::type_list; + + static_assert(std::is_same_v< + mpl::union_set_t, + mpl::type_list>); + + static_assert(std::is_same_v< + mpl::intersection_set_t, mpl::type_list>); + + static_assert(std::is_same_v< + mpl::difference_set_t, mpl::type_list>); + + static_assert(std::is_same_v< + mpl::difference_set_t, mpl::type_list>); + + static_assert(std::is_same_v< + mpl::symmetric_difference_set_t, + mpl::type_list>); +} + +void split() { + using sp_list = + mpl::type_list, mpl::type_list>; + static_assert(std::is_same_v, sp_list>); + + using no_floating_list = mpl::type_list>; + static_assert(std::is_same_v< + mpl::split_if_t, + no_floating_list>); +} + int main() { } From df45410994a27373221714df177d1e0cc1f5caf8 Mon Sep 17 00:00:00 2001 From: Zifeng Deng Date: Tue, 24 Oct 2023 20:48:50 +0800 Subject: [PATCH 2/2] feat(mpl): add typename for portability --- include/co_context/mpl/type_list.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/co_context/mpl/type_list.hpp b/include/co_context/mpl/type_list.hpp index 35c4fb8..404d044 100644 --- a/include/co_context/mpl/type_list.hpp +++ b/include/co_context/mpl/type_list.hpp @@ -152,7 +152,7 @@ template typename P> struct remove_if { private: template - using not_P = detail::negate

::template type; + using not_P = typename detail::negate

::template type; public: using type = filter_t; @@ -452,14 +452,14 @@ struct reverse_sequence> { template struct reverse_sequence> { template - using append = reverse_sequence< + using append = typename reverse_sequence< std::integer_sequence>::template append; - using type = reverse_sequence< + using type = typename reverse_sequence< std::integer_sequence>::template append; }; template -using reverse_sequence_t = reverse_sequence::type; +using reverse_sequence_t = typename reverse_sequence::type; static_assert(std::is_same_v< reverse_sequence_t>,