diff --git a/include/eve/detail/kumi.hpp b/include/eve/detail/kumi.hpp index bb62b61408..c1b67296e2 100644 --- a/include/eve/detail/kumi.hpp +++ b/include/eve/detail/kumi.hpp @@ -1374,6 +1374,16 @@ namespace kumi (std::make_index_sequence::value>()); } } + template Tuple> + [[nodiscard]] constexpr auto fold_left(Function f, Tuple&& t) + { + if constexpr(sized_product_type) return get<0>(t); + else + { + auto&&[heads, tail] = split(KUMI_FWD(t), index<2>); + return fold_left(f, tail, kumi::apply(f,heads)); + } + } template [[nodiscard]] constexpr auto fold_right(Function f, Tuple&& t, Value init) { @@ -1387,9 +1397,19 @@ namespace kumi (std::make_index_sequence::value>()); } } + template Tuple> + [[nodiscard]] constexpr auto fold_right(Function f, Tuple&& t) + { + if constexpr(sized_product_type) return get<0>(t); + else + { + auto&&[head, tails] = split(KUMI_FWD(t), index-2>); + return fold_left(f, head, kumi::apply(f,tails)); + } + } namespace result { - template + template struct fold_right { using type = decltype ( kumi::fold_right( std::declval() @@ -1398,7 +1418,15 @@ namespace kumi ) ); }; - template + template + struct fold_right + { + using type = decltype ( kumi::fold_right( std::declval() + , std::declval() + ) + ); + }; + template struct fold_left { using type = decltype ( kumi::fold_left ( std::declval() @@ -1407,9 +1435,17 @@ namespace kumi ) ); }; - template + template + struct fold_left + { + using type = decltype ( kumi::fold_left ( std::declval() + , std::declval() + ) + ); + }; + template using fold_right_t = typename fold_right::type; - template + template using fold_left_t = typename fold_left::type; } } @@ -1537,30 +1573,59 @@ namespace kumi namespace kumi { template - [[nodiscard]] constexpr bool all_of( T const& ts, Pred p) noexcept + [[nodiscard]] constexpr auto all_of(T const& ts, Pred p) noexcept { if constexpr( !product_type ) return p(ts); else { - if constexpr(size_v == 0) return true; - else return kumi::apply( [&](auto const&... m) { return (p(m) && ... && true); }, ts ); + if constexpr(size_v == 0) return true; + else if constexpr(size_v == 1) return p(get<0>(ts)); + else return kumi::apply( [&](auto const&... m) { return (p(m) && ... && p(get<0>(ts))); }, extract(ts,index<1>)); + } + } + template + [[nodiscard]] constexpr auto all_of(T const& ts) noexcept + { + if constexpr( !product_type ) return !!ts; + else + { + if constexpr(size_v == 0) return true; + else if constexpr(size_v == 1) return !!get<0>(ts); + else return kumi::apply( [&](auto const&... m) { return (m && ... && get<0>(ts)); }, extract(ts,index<1>) ); } } template - [[nodiscard]] constexpr bool any_of( T const& ts, Pred p) noexcept + [[nodiscard]] constexpr auto any_of(T const& ts, Pred p) noexcept { if constexpr( !product_type ) return p(ts); else { - if constexpr(size_v == 0) return false; - else return kumi::apply( [&](auto const&... m) { return (p(m) || ... || false); }, ts ); + if constexpr(size_v == 0) return true; + else if constexpr(size_v == 1) return p(get<0>(ts)); + else return kumi::apply( [&](auto const&... m) { return (p(m) || ... || p(get<0>(ts))); }, extract(ts,index<1>)); + } + } + template + [[nodiscard]] constexpr auto any_of(T const& ts) noexcept + { + if constexpr( !product_type ) return !!ts; + else + { + if constexpr(size_v == 0) return false; + else if constexpr(size_v == 1) return !!get<0>(ts); + else return kumi::apply( [&](auto const&... m) { return (m || ... || get<0>(ts)); }, extract(ts,index<1>) ); } } template - [[nodiscard]] constexpr bool none_of( Tuple const& ts, Pred p) noexcept + KUMI_TRIVIAL_NODISCARD constexpr bool none_of( Tuple const& ts, Pred p) noexcept { return !any_of(ts,p); } + template + KUMI_TRIVIAL_NODISCARD constexpr bool none_of(Tuple const& ts) noexcept + { + return !any_of(ts); + } template [[nodiscard]] constexpr std::size_t count_if( T const& ts, Pred p) noexcept { @@ -1606,53 +1671,92 @@ namespace kumi if constexpr(_::empty_tuple) return init; else return kumi::apply( [init](auto const&... m) { return (m + ... + init); }, KUMI_FWD(t) ); } + template + [[nodiscard]] constexpr auto sum(Tuple&& t) + { + return sum(kumi::extract(t,index<1>),get<0>(t)); + } template [[nodiscard]] constexpr auto prod(Tuple&& t, Value init) { if constexpr(_::empty_tuple) return init; else return kumi::apply( [init](auto const&... m) { return (m * ... * init); }, KUMI_FWD(t) ); } + template + [[nodiscard]] constexpr auto prod(Tuple&& t) + { + return prod(kumi::extract(t,index<1>),get<0>(t)); + } template [[nodiscard]] constexpr auto bit_and(Tuple&& t, Value init) { if constexpr(_::empty_tuple) return init; else return kumi::apply( [init](auto const&... m) { return (m & ... & init); }, KUMI_FWD(t) ); } + template + [[nodiscard]] constexpr auto bit_and(Tuple&& t) + { + return bit_and(kumi::extract(t,index<1>),get<0>(t)); + } template [[nodiscard]] constexpr auto bit_or(Tuple&& t, Value init) { if constexpr(_::empty_tuple) return init; else return kumi::apply( [init](auto const&... m) { return (m | ... | init); }, KUMI_FWD(t) ); } + template + [[nodiscard]] constexpr auto bit_or(Tuple&& t) + { + return bit_or(kumi::extract(t,index<1>),get<0>(t)); + } namespace result { - template + template struct sum { using type = decltype(kumi::sum(std::declval(), std::declval())); }; - template + template struct sum + { + using type = decltype(kumi::sum(std::declval())); + }; + template struct prod { using type = decltype(kumi::prod(std::declval(), std::declval())); }; - template + template + struct prod + { + using type = decltype(kumi::prod(std::declval())); + }; + template struct bit_and { using type = decltype(kumi::bit_and(std::declval(), std::declval())); }; - template + template + struct bit_and + { + using type = decltype(kumi::bit_and(std::declval())); + }; + template struct bit_or { using type = decltype(kumi::bit_or(std::declval(), std::declval())); }; - template + template + struct bit_or + { + using type = decltype(kumi::bit_or(std::declval())); + }; + template using sum_t = typename sum::type; - template + template using prod_t = typename prod::type; - template + template using bit_and_t = typename bit_and::type; - template + template using bit_or_t = typename bit_or::type; } }