Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
zip_view.hpp
Go to the documentation of this file.
1#pragma once
2/* ********************************* FILE ************************************/
75static_assert(__cplusplus >= 201703L,
76 " must be c++17 or greater"); // could be rewritten in c++11, but the features you must use will be buggy
77 // in an older compiler anyways.
79#include <algorithm>
80#include <cassert>
81#include <functional>
82#include <iostream>
83#include <sstream>
84#include <tuple>
85#include <type_traits>
86#include <vector>
87
88template <class T>
95 public:
96 // speeds up compilation a little bit...
98
100 : iter(iter)
102 {}
103 // prefix, inc first, then return
105 {
106 for_each_in_tuple([](auto&& x) { return x++; }, iter);
107 // then if any hit end, update all to point to end.
108 auto end = apply2([](auto x, auto y) { return x == y; }, iter, iter_end);
109 if (if_any_in(end)) {
110 apply2([](auto& x, auto y) { return x = y; }, iter, iter_end);
111 }
112 index++;
113 return *this;
114 }
115 // sufficient because ++ keeps track and sets all to end when any is
116 bool operator!=(const zip_iterator& other) const { return other.iter != iter; }
117 auto operator*() const
118 {
120 }
121
122 private:
125
126 // This indirection over std::ref fixes iota_view() and other non-reference containers
127 static auto ref(const auto& t) { return std::ref(t); }
128 static auto ref(auto& t) { return std::ref(t); }
129 // We don't forward any reference if we have a value type
130 static auto ref(const auto&& t) { return t; }
131 static auto ref(auto&& t) { return t; }
132 template <std::size_t... I> auto get_refs(T t, std::index_sequence<I...>) const
133 {
134 return std::make_tuple(ref(*std::get<I>(t))...);
135 }
136
137 template <class F, class A, std::size_t... I> auto apply2_impl(F&& f, A&& a, A&& b, std::index_sequence<I...>)
138 {
139 return std::make_tuple(f(std::get<I>(a), std::get<I>(b))...);
140 }
141 template <class F, class A> auto apply2(F&& f, A&& a, A&& b)
142 {
144 }
145 template <class A, std::size_t... I> bool if_any_impl(const A& t, std::index_sequence<I...>) const
146 {
147 return (... || std::get<I>(t)); // c++17
148 }
149
150 // in general context we must enforce that these are tuples
151 template <class A> bool if_any_in(A&& t) const { return if_any_impl(std::forward<A>(t), tuple_indexes{}); }
152
153 template <class F, class Tuple, std::size_t... I>
154 auto for_each_in_impl(F&& f, Tuple&& t, std::index_sequence<I...>) const
155 {
156 return std::make_tuple(f(std::get<I>(t))...);
157 }
158
159 template <class F, class A> void for_each_in_tuple(F&& f, A&& t) const
160 {
162 }
163};
164
166template <class... S> class zip_view {
168
169 public:
171 : args(std::forward<S>(args)...)
172 {
173 // min size matches max size
175 }
177 : args(std::forward<S>(args)...)
178 {
179 // Same in a release build, in a debug build doesn't error with different container sizes
180 }
181 auto begin() const { return get_begins(arg_indexes{}); }
182 auto end() const { return get_ends(arg_indexes{}); }
183 [[nodiscard]] std::size_t size() const { return size_impl(arg_indexes{}); }
184
185 private:
186 std::tuple<S...> args;
188 {
189 return zip_iterator(std::make_tuple(std::get<I>(args).begin()...), std::make_tuple(std::get<I>(args).end()...));
190 }
192 {
193 return zip_iterator(std::make_tuple(std::get<I>(args).end()...), std::make_tuple(std::get<I>(args).end()...));
194 }
196 {
197 return std::min({ std::size_t(std::get<I>(args).size())... });
198 }
200 {
201 return std::max({ std::size_t(std::get<I>(args).size())... });
202 }
203
204 template <class A, std::size_t... I> bool if_any_impl(const A& t, std::index_sequence<I...>) const
205 {
206 return (... || std::get<I>(t)); // c++17
207 }
208};
209
210// deduction guide,
211template <class... S> zip_view(S&&...) -> zip_view<S...>;
212
213// deduction guide,
214template <class... S> zip_view(ZipAllowDifferentSizes, S&&...) -> zip_view<S...>;
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:59
The zip_iterator class.
Definition zip_view.hpp:94
std::size_t index
Definition zip_view.hpp:124
static auto ref(const auto &t)
Definition zip_view.hpp:127
bool if_any_impl(const A &t, std::index_sequence< I... >) const
Definition zip_view.hpp:145
auto get_refs(T t, std::index_sequence< I... >) const
Definition zip_view.hpp:132
void for_each_in_tuple(F &&f, A &&t) const
Definition zip_view.hpp:159
auto apply2_impl(F &&f, A &&a, A &&b, std::index_sequence< I... >)
Definition zip_view.hpp:137
auto apply2(F &&f, A &&a, A &&b)
Definition zip_view.hpp:141
std::make_index_sequence< std::tuple_size_v< std::remove_reference_t< T > > > tuple_indexes
Definition zip_view.hpp:97
bool if_any_in(A &&t) const
Definition zip_view.hpp:151
static auto ref(const auto &&t)
Definition zip_view.hpp:130
static auto ref(auto &&t)
Definition zip_view.hpp:131
static auto ref(auto &t)
Definition zip_view.hpp:128
auto operator*() const
Definition zip_view.hpp:117
bool operator!=(const zip_iterator &other) const
Definition zip_view.hpp:116
auto for_each_in_impl(F &&f, Tuple &&t, std::index_sequence< I... >) const
Definition zip_view.hpp:154
zip_iterator(T iter, T iter_end)
Definition zip_view.hpp:99
zip_iterator & operator++()
Definition zip_view.hpp:104
auto size_impl(std::index_sequence< I... >) const
Definition zip_view.hpp:195
std::make_index_sequence< sizeof...(S)> arg_indexes
Definition zip_view.hpp:167
auto end() const
Definition zip_view.hpp:182
auto max_size_impl(std::index_sequence< I... >) const
Definition zip_view.hpp:199
auto begin() const
Definition zip_view.hpp:181
bool if_any_impl(const A &t, std::index_sequence< I... >) const
Definition zip_view.hpp:204
zip_view(S... args)
Definition zip_view.hpp:170
std::tuple< S... > args
Definition zip_view.hpp:186
zip_view(ZipAllowDifferentSizes, S... args)
Definition zip_view.hpp:176
auto get_begins(std::index_sequence< I... >) const
Definition zip_view.hpp:187
std::size_t size() const
Definition zip_view.hpp:183
auto get_ends(std::index_sequence< I... >) const
Definition zip_view.hpp:191
FF a
FF b
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
ZipAllowDifferentSizes
Definition zip_view.hpp:165