13 #include <hipipe/core/stream/template_arguments.hpp>
14 #include <hipipe/core/stream/transform.hpp>
15 #include <hipipe/core/utility/tuple.hpp>
17 #include <range/v3/view/filter.hpp>
18 #include <range/v3/view/move.hpp>
19 #include <range/v3/view/zip.hpp>
24 namespace hipipe::stream {
26 namespace rgv = ranges::views;
34 template<
typename Fun,
typename From,
typename ByIdxs>
35 struct wrap_filter_fun_for_transform;
36 template<
typename Fun,
typename... FromTypes, std::size_t... ByIdxs>
37 struct wrap_filter_fun_for_transform<Fun, from_t<FromTypes...>, std::index_sequence<ByIdxs...>>
42 utility::maybe_tuple<FromTypes...> operator()(FromTypes&... cols)
46 auto range_of_tuples =
49 [
this](
const auto& tuple) ->
bool {
50 return std::invoke(this->fun, std::get<ByIdxs>(tuple)...);
59 std::vector<ranges::range_value_t<decltype(range_of_tuples)>> ts;
60 for (
auto&& t : rgv::move(range_of_tuples)) ts.push_back(std::move(t));
69 template<
typename Fun,
typename... ByColumns>
70 struct apply_filter_fun_to_columns
74 bool operator()(
const batch_t& source)
76 std::tuple<
const typename ByColumns::data_type&...> slice_view{
77 source.extract<ByColumns>()...
79 static_assert(std::is_invocable_r_v<
80 bool, Fun&,
const typename ByColumns::data_type&...>,
81 "hipipe::stream::filter: "
82 "The function has to accept the selected `by<>` columns (specifically "
83 "const ByColumns::data_type&) and return a bool.");
84 return std::apply(fun, std::move(slice_view));
94 template<
typename... FromColumns,
typename... ByColumns,
typename Fun>
95 static auto impl(from_t<FromColumns...> f, by_t<ByColumns...> b, Fun fun)
97 static_assert(
sizeof...(ByColumns) <=
sizeof...(FromColumns),
98 "Cannot have more ByColumns than FromColumns.");
100 ((utility::ndims<typename FromColumns::data_type>::value >= Dim) && ...) &&
101 ((utility::ndims<typename ByColumns::data_type>::value >= Dim) && ...),
102 "hipipe::stream::filter: The dimension in which to apply the operation needs"
103 " to be at most the lowest dimension of all the from<> and by<> columns.");
105 detail::wrap_filter_fun_for_transform<
106 Fun, from_t<utility::ndim_type_t<
typename FromColumns::data_type, Dim-1>...>,
107 std::index_sequence<utility::variadic_find<ByColumns, FromColumns...>::value...>>
108 fun_wrapper{std::move(fun)};
110 return stream::transform(f, to<FromColumns...>, std::move(fun_wrapper), dim<Dim-1>);
116 struct filter_impl<0>
118 template<
typename From,
typename... ByColumns,
typename Fun>
119 static auto impl(From, by_t<ByColumns...>, Fun fun)
121 apply_filter_fun_to_columns<Fun, ByColumns...> fun_wrapper{std::move(fun)};
147 template<
typename... FromColumns,
typename... ByColumns,
typename Fun,
int Dim = 1>
148 auto filter(from_t<FromColumns...> f,
149 by_t<ByColumns...> b,
151 dim_t<Dim> d = dim_t<1>{})
156 "hipipe::stream::filter: The dimension in which to apply the operation "
157 " needs to be at most the lowest dimension of all the from<> and by<> columns.");
159 using FunT = std::function<
160 bool(
const utility::ndim_type_t<typename ByColumns::data_type, Dim>&...)>;
161 return detail::filter_impl<Dim>::impl(f, b, FunT{std::move(fun)});