22#ifndef _ITERTOOLS_PRODUCT_HPP
23#define _ITERTOOLS_PRODUCT_HPP
55 template <
typename EndIters,
typename... Iters>
56 struct prod_iter : iterator_facade<prod_iter<EndIters, Iters...>, std::tuple<typename std::iterator_traits<Iters>::value_type...>> {
67 static constexpr long Rank =
sizeof...(Iters);
82 template <
int N>
void _increment() {
86 if constexpr (N > 0) {
88 if (std::get<N>(
its) == std::get<N>(
its_end)) {
120 template <
size_t... Is> [[gnu::always_inline]] [[nodiscard]]
auto tuple_map_impl(std::index_sequence<Is...>)
const {
121 return std::tuple<decltype(*std::get<Is>(
its))...>(*std::get<Is>(
its)...);
129 [[nodiscard]]
decltype(
auto)
dereference()
const {
return tuple_map_impl(std::index_sequence_for<Iters...>{}); }
142 std::tuple<Rs...>
tu;
156 template <
typename... Us>
multiplied(Us &&...rgs) :
tu{std::forward<Us>(rgs)...} {}
163 template <
size_t... Is> [[gnu::always_inline]]
auto _begin(std::index_sequence<Is...>) {
164 return iterator{std::make_tuple(std::begin(std::get<Is>(
tu))...), std::make_tuple(std::end(std::get<Is>(
tu))...)};
168 template <
size_t... Is> [[gnu::always_inline]]
auto _cbegin(std::index_sequence<Is...>)
const {
169 return const_iterator{std::make_tuple(std::cbegin(std::get<Is>(
tu))...), std::make_tuple(std::cend(std::get<Is>(
tu))...)};
177 [[nodiscard]]
iterator begin() noexcept {
return _begin(std::index_sequence_for<Rs...>{}); }
195 [[nodiscard]]
auto end() const noexcept {
return cend(); }
199 template <
typename... Rs> multiplied(Rs &&...) -> multiplied<std::decay_t<Rs>...>;
245 template <
typename C,
size_t... Is> [[gnu::always_inline]] [[nodiscard]]
auto make_product_impl(C &cont, std::index_sequence<Is...>) {
259 template <
typename R,
size_t N> [[nodiscard]]
auto make_product(std::array<R, N> &arr) {
260 return detail::make_product_impl(arr, std::make_index_sequence<N>{});
264 template <
typename R,
size_t N> [[nodiscard]]
auto make_product(std::array<R, N>
const &arr) {
265 return detail::make_product_impl(arr, std::make_index_sequence<N>{});
auto make_product(std::array< R, N > &arr)
Create a cartesian product range from an array of ranges.
itertools::multiplied< Rs... > product(Rs &&...rgs)
Lazy-multiply a given number of ranges by forming their cartesian product.
sentinel_t< Iter > make_sentinel(Iter it)
Create an itertools::sentinel_t from an iterator using template type deduction.
Provides a CRTP base class for various iterator types in itertools.
Provides a generic sentinel type for various iterator types in itertools.