30namespace CartesianProduct
39template<
class Tuple,
class F, std::size_t...
I>
42 return (
void)std::initializer_list<int>{ (std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))), 0)... }, f;
49template<
class F,
class Tuple>
50constexpr decltype(
auto)
for_each(Tuple&& t, F&& f)
52 return for_each_impl(std::forward<Tuple>(t), std::forward<F>(f),
53 std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
60template<
class Tuple,
class F, std::size_t... Is>
62 ->
decltype(std::make_tuple(std::forward<F>(f)(std::get<Is>(std::forward<Tuple>(t)))...))
64 return std::make_tuple(std::forward<F>(f)(std::get<Is>(std::forward<Tuple>(t)))...);
83template<
typename... Ts,
typename Function>
84auto transform(std::tuple<Ts...>
const& inputs, Function function)
86 return transform_impl(inputs, function, std::make_index_sequence<
sizeof...(Ts)>{});
93template<
typename Tuple,
typename Predicate>
94size_t find_if(Tuple&& tuple, Predicate pred)
96 size_t index = std::tuple_size<std::decay_t<Tuple>>::value;
97 size_t currentIndex = 0;
100 if (!found && pred(value))
102 ++index = currentIndex;
114template<
typename Tuple,
typename Predicate>
115bool any_of(Tuple&& tuple, Predicate pred)
117 return find_if(tuple, pred) != std::tuple_size<std::decay_t<Tuple>>::value;
124template<
typename... Ts>
127 return tuple_algos::transform(tuple, [](
auto&& element) ->
decltype(
auto) {
return *element; });
138 template<
typename... Iterators>
139 static void _(std::tuple<Iterators...>& iterators, std::tuple<Iterators...>
const& beginIterators, std::tuple<Iterators...>
const& endIterators)
141 auto& it = std::get<I>(iterators);
142 auto const begin = std::get<I>(beginIterators);
143 auto const end = std::get<I>(endIterators);
161 template<
typename... Iterators>
162 static void _(std::tuple<Iterators...>& iterators, std::tuple<Iterators...>
const& , std::tuple<Iterators...>
const& )
164 auto& it = std::get<0>(iterators);
174template<
typename... Iterators>
175void next_combination(std::tuple<Iterators...>& iterators, std::tuple<Iterators...>
const& beginIterators, std::tuple<Iterators...>
const& endIterators)
177 constexpr auto N =
sizeof...(Iterators);
184template<
typename Function,
typename... Ts,
size_t... Is>
185void callFunction(Function function, std::tuple<Ts...>
const& tuple, std::index_sequence<Is...> )
187 function(std::get<Is>(tuple)...);
195template<
typename Function,
typename... Ranges>
198 static_assert(
sizeof...(Ranges) > 0,
"There should be at least one range in cartesian_product.");
199 auto const hasEmptyRange = CartesianProduct::tuple_algos::any_of(std::forward_as_tuple(ranges...), [](
auto&& range) { return range.size() == 0; });
203 auto const beginIterators = std::make_tuple(begin(ranges)...);
204 auto const endIterators = std::make_tuple(end(ranges)...);
206 for (
auto iterators = beginIterators; std::get<0>(iterators) != std::get<0>(endIterators); CartesianProduct::next_combination(iterators, beginIterators, endIterators))
208 std::apply(function, CartesianProduct::dereference(iterators));
216template<
typename SubList,
size_t N,
typename Function>
219 std::apply([function](
auto... xs) {
cartesian_product(function, std::forward<
decltype(xs)>(xs)...); }, list);
226template<
typename SubList,
size_t N,
typename Function>
229 std::array<std::vector<size_t>, N> indices;
230 for (
size_t i = 0; i < list.size(); i++)
232 indices.at(i) = std::vector<size_t>(list.at(i).size());
233 std::iota(indices.at(i).begin(), indices.at(i).end(), 0);
236 std::apply([function](
auto... xs) {
cartesian_product(function, std::forward<
decltype(xs)>(xs)...); }, indices);
auto transform_impl(Tuple &&t, F &&f, std::index_sequence< Is... >) -> decltype(std::make_tuple(std::forward< F >(f)(std::get< Is >(std::forward< Tuple >(t)))...))
Transform implementation for tuples.
Definition CartesianProduct.hpp:61
auto transform(std::tuple< Ts... > const &inputs, Function function)
Transform algorithm for tuples.
Definition CartesianProduct.hpp:84
void cartesian_product(Function function, Ranges const &... ranges)
Calls a function on all combinations over ranges.
Definition CartesianProduct.hpp:196
F for_each_impl(Tuple &&t, F &&f, std::index_sequence< I... >)
For-each implementation for tuples.
Definition CartesianProduct.hpp:40
void callFunction(Function function, std::tuple< Ts... > const &tuple, std::index_sequence< Is... >)
Calls the function on the tuple.
Definition CartesianProduct.hpp:185
bool any_of(Tuple &&tuple, Predicate pred)
Any_of algorithm for tuples.
Definition CartesianProduct.hpp:115
void cartesian_product_idx(Function function, std::array< SubList, N > list)
Calls a function on all combinations over ranges defined in an array, e.g. std::array<std::vector>....
Definition CartesianProduct.hpp:227
constexpr decltype(auto) for_each(Tuple &&t, F &&f)
For-each algorithm for tuples.
Definition CartesianProduct.hpp:50
void next_combination(std::tuple< Iterators... > &iterators, std::tuple< Iterators... > const &beginIterators, std::tuple< Iterators... > const &endIterators)
Gets the next combination of the tuples of iterators.
Definition CartesianProduct.hpp:175
auto dereference(std::tuple< Ts... > const &tuple)
Dereference a tuple.
Definition CartesianProduct.hpp:125
size_t find_if(Tuple &&tuple, Predicate pred)
Find_if for tuples.
Definition CartesianProduct.hpp:94
@ I
Ionosphere phase delay.
static void _(std::tuple< Iterators... > &iterators, std::tuple< Iterators... > const &, std::tuple< Iterators... > const &)
Increments an iterator of tuples.
Definition CartesianProduct.hpp:162
Helper struct to increment an iterator.
Definition CartesianProduct.hpp:133
static void _(std::tuple< Iterators... > &iterators, std::tuple< Iterators... > const &beginIterators, std::tuple< Iterators... > const &endIterators)
Increments an iterator of tuples.
Definition CartesianProduct.hpp:139