13#include <dr/detail/ranges_shim.hpp>
14#include <dr/mp/alignment.hpp>
15#include <dr/mp/views/segmented.hpp>
17namespace dr::mp::__detail {
20concept zipable = rng::random_access_range<R> && rng::common_range<R>;
30template <
typename... Rs>
auto zip(Rs &&...rs) {
31 return zip_view(std::forward<Rs>(rs)...);
42template <
typename T,
typename... Rest>
43inline auto select_segments(T &&t, Rest &&...rest) {
45 return dr::ranges::segments(std::forward<T>(t));
47 return select_segments(std::forward<Rest>(rest)...);
51template <
typename T,
typename Seg>
inline auto tpl_segments(T &&t, Seg &&tpl) {
53 return dr::ranges::segments(std::forward<T>(t));
54 }
else if constexpr (rng::forward_range<T>) {
55 return views::segmented(std::forward<T>(t), std::forward<Seg>(tpl));
56 }
else if constexpr (rng::forward_iterator<T>) {
57 return views::segmented(rng::subrange(std::forward<T>(t), T{}),
58 std::forward<Seg>(tpl));
62template <
typename Base>
auto base_to_segments(Base &&base) {
64 auto zip_segments = [](
auto &&...segments) {
65 return views::zip(segments...);
70 auto zip_segment_tuple = [zip_segments](
auto &&v) {
71 return std::apply(zip_segments, v);
75 auto bases_to_segments = [zip_segment_tuple](
auto &&...bases) {
76 bool is_aligned = aligned(bases...);
77 auto tpl = select_segments(bases...);
78 return rng::views::zip(tpl_segments(bases, tpl)...) |
79 rng::views::transform(zip_segment_tuple) |
80 rng::views::filter([is_aligned](
auto &&v) {
return is_aligned; });
83 return std::apply(bases_to_segments, base);
88template <std::random_access_iterator RngIter,
89 std::random_access_iterator... BaseIters>
92 using value_type = rng::iter_value_t<RngIter>;
93 using difference_type = rng::iter_difference_t<RngIter>;
95 using iterator_category = std::random_access_iterator_tag;
99 : rng_iter_(rng_iter), base_(base_iters...) {}
101 auto operator+(difference_type n)
const {
107 friend auto operator+(difference_type n,
const zip_iterator &other) {
110 auto operator-(difference_type n)
const {
117 return rng_iter_ - other.rng_iter_;
120 auto &operator+=(difference_type n) {
125 auto &operator-=(difference_type n) {
135 auto operator++(
int) {
146 auto operator--(
int) {
154 return rng_iter_ == other.rng_iter_;
157 return offset_ <=> other.offset_;
161 auto operator*()
const {
return *rng_iter_; }
162 auto operator[](difference_type n)
const {
return rng_iter_[n]; }
167 auto segments()
const
170 return dr::__detail::drop_segments(__detail::base_to_segments(base_),
177 return dr::ranges::rank(std::get<0>(base_));
186 auto zip = [
this]<
typename... Iters>(Iters &&...iters) {
187 return rng::begin(rng::views::zip(
188 rng::subrange(base_local(std::forward<Iters>(iters)) + this->offset_,
189 decltype(base_local(iters)){})...));
192 return std::apply(zip, base_);
197 auto static base_local(
auto iter) {
return iter; }
200 return dr::ranges::local(iter);
204 std::tuple<BaseIters...> base_;
205 difference_type offset_ = 0;
209class zip_view :
public rng::view_interface<zip_view<Rs...>> {
211 using rng_zip = rng::zip_view<Rs...>;
212 using rng_zip_iterator = rng::iterator_t<rng_zip>;
213 using difference_type = std::iter_difference_t<rng_zip_iterator>;
217 : rng_zip_(rng::views::all(rs)...), base_(rng::views::all(rs)...) {}
220 auto make_begin = [
this](
auto &&...bases) {
221 return zip_iterator(rng::begin(this->rng_zip_), rng::begin(bases)...);
223 return std::apply(make_begin, base_);
226 requires(rng::common_range<rng_zip>)
228 auto make_end = [
this](
auto &&...bases) {
229 return zip_iterator(rng::end(this->rng_zip_), rng::end(bases)...);
231 return std::apply(make_end, base_);
233 auto size()
const {
return rng::size(rng_zip_); }
235 auto operator[](difference_type n)
const {
return rng_zip_[n]; }
237 auto base()
const {
return base_; }
242 auto segments()
const
245 return __detail::base_to_segments(base_);
251 return dr::ranges::rank(std::get<0>(base_));
257 auto zip = []<
typename... Vs>(Vs &&...bases) {
258 return rng::views::zip(dr::ranges::local(std::forward<Vs>(bases))...);
261 return std::apply(zip, base_);
266 std::tuple<rng::views::all_t<Rs>...> base_;
269template <
typename... Rs>
Definition: concepts.hpp:31
Definition: concepts.hpp:20
Definition: ranges.hpp:242
Definition: concepts.hpp:12
Definition: concepts.hpp:16