TRIQS/itertools 1.3.0
C++ range library
Loading...
Searching...
No Matches
zip.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn, Olivier Parcollet, Nils Wentzell, chuffa
16
22#ifndef _ITERTOOLS_ZIP_HPP
23#define _ITERTOOLS_ZIP_HPP
24
25#include "./iterator_facade.hpp"
26#include "./sentinel.hpp"
27
28#include <cstddef>
29#include <iterator>
30#include <tuple>
31#include <utility>
32
33namespace itertools {
34
46 template <typename... Iters>
47 struct zip_iter : iterator_facade<zip_iter<Iters...>, std::tuple<typename std::iterator_traits<Iters>::value_type...>> {
49 std::tuple<Iters...> its;
50
52 zip_iter() = default;
53
58 zip_iter(std::tuple<Iters...> its) : its(std::move(its)) {}
59
60 private:
61 // Helper function which increments all original iterators.
62 template <size_t... Is> [[gnu::always_inline]] void increment_all(std::index_sequence<Is...>) { ((void)(++std::get<Is>(its)), ...); }
63
64 public:
66 void increment() { increment_all(std::index_sequence_for<Iters...>{}); }
67
74 [[nodiscard]] bool operator==(zip_iter const &other) const { return its == other.its; }
75
86 template <typename SentinelIter> [[nodiscard]] bool operator==(sentinel_t<SentinelIter> const &s) const {
87 return [&]<size_t... Is>(std::index_sequence<Is...>) {
88 return ((std::get<Is>(its) == std::get<Is>(s.it)) || ...);
89 }(std::index_sequence_for<Iters...>{});
90 }
91
92 private:
93 // Helper function to dereference all original iterators.
94 template <size_t... Is> [[nodiscard]] auto tuple_map_impl(std::index_sequence<Is...>) const {
95 return std::tuple<decltype(*std::get<Is>(its))...>(*std::get<Is>(its)...);
96 }
97
98 public:
103 [[nodiscard]] decltype(auto) dereference() const { return tuple_map_impl(std::index_sequence_for<Iters...>{}); }
104 };
105
114 template <typename... Rs> struct zipped {
116 std::tuple<Rs...> tu;
117
119 using seq_t = std::index_sequence_for<Rs...>;
120
123
126
133 template <typename... Us> zipped(Us &&...rgs) : tu{std::forward<Us>(rgs)...} {}
134
136 [[nodiscard]] bool operator==(zipped const &) const = default;
137
138 private:
139 // Helper function that applies a given callable to each range in the stored tuple and returns a new tuple with the results.
140 template <typename F, size_t... Is> [[gnu::always_inline]] auto tuple_map(F &&f, std::index_sequence<Is...>) {
141 return std::make_tuple(std::forward<F>(f)(std::get<Is>(tu))...);
142 }
143
144 // Const overload of tuple_map(F &&, std::index_sequence<Is...>).
145 template <typename F, size_t... Is> [[gnu::always_inline]] auto tuple_map(F &&f, std::index_sequence<Is...>) const {
146 return std::make_tuple(std::forward<F>(f)(std::get<Is>(tu))...);
147 }
148
149 public:
154 [[nodiscard]] iterator begin() noexcept {
155 return tuple_map([](auto &&rg) { return std::begin(rg); }, seq_t{});
156 }
157
159 [[nodiscard]] const_iterator cbegin() const noexcept {
160 return tuple_map([](auto &&rg) { return std::cbegin(rg); }, seq_t{});
161 }
162
164 [[nodiscard]] const_iterator begin() const noexcept { return cbegin(); }
165
170 [[nodiscard]] auto end() noexcept {
171 return make_sentinel(tuple_map([](auto &&rg) { return std::end(rg); }, seq_t{}));
172 }
173
175 [[nodiscard]] auto cend() const noexcept {
176 return make_sentinel(tuple_map([](auto &&rg) { return std::cend(rg); }, seq_t{}));
177 }
178
180 [[nodiscard]] auto end() const noexcept { return cend(); }
181 };
182
218 template <typename... Rs> [[nodiscard]] zipped<Rs...> zip(Rs &&...rgs) { return {std::forward<Rs>(rgs)...}; }
219
220} // namespace itertools
221
222#endif // _ITERTOOLS_ZIP_HPP
zipped< Rs... > zip(Rs &&...rgs)
Lazy-zip ranges together (similar to Python's zip).
Definition zip.hpp:218
sentinel_t< Iter > make_sentinel(Iter it)
Create an itertools::sentinel_t from an iterator using template type deduction.
Definition sentinel.hpp:50
Provides a CRTP base class for various iterator types in itertools.
Provides a generic sentinel type for various iterator types in itertools.
Generic sentinel type that can be used to mark the end of a range.
Definition sentinel.hpp:38
Iter it
End iterator of some range.
Definition sentinel.hpp:40
Iterator for a itertools::zipped range.
Definition zip.hpp:47
decltype(auto) dereference() const
Dereference the iterator.
Definition zip.hpp:103
bool operator==(sentinel_t< SentinelIter > const &s) const
Equal-to operator for a itertools::zip_iter and an itertools::sentinel_t.
Definition zip.hpp:86
zip_iter(std::tuple< Iters... > its)
Constructs a zipped iterator from given iterators.
Definition zip.hpp:58
void increment()
Increment the iterator by incrementing all original iterators stored in the tuple.
Definition zip.hpp:66
bool operator==(zip_iter const &other) const
Equal-to operator for two itertools::zip_iter objects.
Definition zip.hpp:74
std::tuple< Iters... > its
Tuple containing iterators of the original ranges.
Definition zip.hpp:49
zip_iter()=default
Default constructor.
Represents a zipped range.
Definition zip.hpp:114
auto end() const noexcept
Const overload of end().
Definition zip.hpp:180
zipped(Us &&...rgs)
Construct a zipped range from the given ranges.
Definition zip.hpp:133
const_iterator begin() const noexcept
Const overload of begin().
Definition zip.hpp:164
const_iterator cbegin() const noexcept
Const version of begin().
Definition zip.hpp:159
std::tuple< Rs... > tu
Tuple containing the original ranges.
Definition zip.hpp:116
auto cend() const noexcept
Const version of end().
Definition zip.hpp:175
bool operator==(zipped const &) const =default
Default equal-to operator.
iterator begin() noexcept
Beginning of the zipped range.
Definition zip.hpp:154
auto end() noexcept
End of the zipped range.
Definition zip.hpp:170
std::index_sequence_for< Rs... > seq_t
Convenience typedef for an std::index_sequence.
Definition zip.hpp:119