22#ifndef _ITERTOOLS_PRODUCT_HPP
23#define _ITERTOOLS_PRODUCT_HPP
56 template <
typename EndIters,
typename... Iters>
57 struct prod_iter : iterator_facade<prod_iter<EndIters, Iters...>, std::tuple<typename std::iterator_traits<Iters>::value_type...>> {
68 static constexpr long Rank =
sizeof...(Iters);
83 template <
int N>
void _increment() {
87 if constexpr (N > 0) {
89 if (std::get<N>(
its) == std::get<N>(
its_end)) {
121 template <
size_t... Is> [[gnu::always_inline]] [[nodiscard]]
auto tuple_map_impl(std::index_sequence<Is...>)
const {
122 return std::tuple<decltype(*std::get<Is>(
its))...>(*std::get<Is>(
its)...);
130 [[nodiscard]]
decltype(
auto)
dereference()
const {
return tuple_map_impl(std::index_sequence_for<Iters...>{}); }
143 std::tuple<Rs...>
tu;
157 template <
typename... Us>
multiplied(Us &&...rgs) :
tu{std::forward<Us>(rgs)...} {}
164 template <
size_t... Is> [[gnu::always_inline]]
auto _begin(std::index_sequence<Is...>) {
165 return iterator{std::make_tuple(std::begin(std::get<Is>(
tu))...), std::make_tuple(std::end(std::get<Is>(
tu))...)};
169 template <
size_t... Is> [[gnu::always_inline]]
auto _cbegin(std::index_sequence<Is...>)
const {
170 return const_iterator{std::make_tuple(std::cbegin(std::get<Is>(
tu))...), std::make_tuple(std::cend(std::get<Is>(
tu))...)};
178 [[nodiscard]]
iterator begin() noexcept {
return _begin(std::index_sequence_for<Rs...>{}); }
196 [[nodiscard]]
auto end() const noexcept {
return cend(); }
200 template <
typename... Rs> multiplied(Rs &&...) -> multiplied<std::decay_t<Rs>...>;
219 template <
typename Iter>
220 struct prod_iter_vec : iterator_facade<prod_iter_vec<Iter>, std::vector<typename std::iterator_traits<Iter>::value_type>> {
222 using value_type =
typename std::iterator_traits<Iter>::value_type;
254 for (std::size_t i =
its.size(); i-- > 1;) {
282 return s.
it ==
its[0];
290 std::vector<value_type> result;
291 result.reserve(
its.size());
292 for (
auto const &it :
its) result.push_back(*it);
330 std::vector<decltype(std::begin(std::declval<R &>()))> b, e;
331 b.reserve(
tu.size());
332 e.reserve(
tu.size());
334 b.push_back(std::begin(r));
335 e.push_back(std::end(r));
337 return iterator{std::move(b), std::move(e)};
342 std::vector<decltype(std::cbegin(std::declval<R const &>()))> b, e;
343 b.reserve(
tu.size());
344 e.reserve(
tu.size());
345 for (
auto const &r :
tu) {
346 b.push_back(std::cbegin(r));
347 e.push_back(std::cend(r));
360 [[nodiscard]]
auto end() noexcept {
361 using SentinelIter =
decltype(std::end(std::declval<R &>()));
367 [[nodiscard]]
auto cend() const noexcept {
368 using SentinelIter =
decltype(std::cend(std::declval<R const &>()));
374 [[nodiscard]]
auto end() const noexcept {
return cend(); }
462 template <
typename C,
size_t... Is> [[gnu::always_inline]] [[nodiscard]]
auto make_product_impl(C &cont, std::index_sequence<Is...>) {
476 template <
typename R,
size_t N> [[nodiscard]]
auto make_product(std::array<R, N> &arr) {
477 return detail::make_product_impl(arr, std::make_index_sequence<N>{});
481 template <
typename R,
size_t N> [[nodiscard]]
auto make_product(std::array<R, N>
const &arr) {
482 return detail::make_product_impl(arr, std::make_index_sequence<N>{});
itertools::multiplied_vec< R > product_vec(std::vector< R > rgs)
Lazy-multiply a vector of homogeneous ranges by forming their cartesian product.
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.