Distributed Ranges
Loading...
Searching...
No Matches
multiply_view.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <concepts>
8#include <iterator>
9#include <type_traits>
10
11#include <dr/concepts/concepts.hpp>
12#include <dr/detail/ranges_shim.hpp>
13
14namespace dr::__detail {
15
16template <std::random_access_iterator Iter> class multiply_iterator {
17public:
18 using value_type = std::iter_value_t<Iter>;
19 using difference_type = long long;
21 using reference = value_type;
22
23 using pointer = iterator;
24
25 using iterator_category = std::random_access_iterator_tag;
26
27 multiply_iterator(Iter iter, std::size_t len, long long pos) noexcept
28 : iter_(iter), len_(len), pos_(pos) {}
29 multiply_iterator() noexcept = default;
30 ~multiply_iterator() noexcept = default;
31 multiply_iterator(const multiply_iterator &) noexcept = default;
32 multiply_iterator &operator=(const multiply_iterator &) noexcept = default;
33
34 bool operator==(const multiply_iterator &other) const noexcept {
35 return iter_ == other.iter_ && pos_ == other.pos_ && len_ == other.len_;
36 }
37
38 bool operator!=(const multiply_iterator &other) const noexcept {
39 return iter_ != other.iter_ || pos_ != other.pos_ || len_ != other.len_;
40 }
41
42 iterator operator+(difference_type offset) const noexcept {
43 return iterator(iter_, len_, pos_ + offset);
44 }
45
46 iterator operator-(difference_type offset) const noexcept {
47 return iterator(iter_, len_, pos_ + offset);
48 }
49
50 difference_type operator-(iterator other) const noexcept {
51 return pos_ - other.pos_;
52 }
53
54 bool operator<(iterator other) const noexcept { return pos_ < other.pos_; }
55
56 bool operator>(iterator other) const noexcept { return pos_ > other.pos_; }
57
58 bool operator<=(iterator other) const noexcept { return pos_ <= other.pos_; }
59
60 bool operator>=(iterator other) const noexcept { return pos_ >= other.pos_; }
61
62 iterator &operator++() noexcept {
63 ++pos_;
64 return *this;
65 }
66
67 iterator operator++(int) noexcept {
68 iterator other = *this;
69 ++(*this);
70 return other;
71 }
72
73 iterator &operator--() noexcept {
74 --pos_;
75 return *this;
76 }
77
78 iterator operator--(int) noexcept {
79 iterator other = *this;
80 --(*this);
81 return other;
82 }
83
84 iterator &operator+=(difference_type offset) noexcept {
85 pos_ += offset;
86 return *this;
87 }
88
89 iterator &operator-=(difference_type offset) noexcept {
90 pos_ -= offset;
91 return *this;
92 }
93
94 reference operator*() const noexcept { return *(iter_ + (pos_ % len_)); }
95
96 reference operator[](difference_type offset) const noexcept {
97 return *(*this + offset);
98 }
99
100 friend iterator operator+(difference_type n, iterator iter) {
101 return iter.pos_ + n;
102 }
103
104 auto local() const
106 {
107 auto iter = dr::ranges::__detail::local(iter_);
108 return multiply_iterator<decltype(iter)>(std::move(iter), len_, pos_);
109 }
110
111private:
112 Iter iter_;
113 std::size_t len_;
114 long long pos_;
115};
116
117template <rng::random_access_range V>
118 requires(rng::sized_range<V>)
119class multiply_view : public rng::view_interface<multiply_view<V>> {
120public:
121 template <rng::viewable_range R>
122 multiply_view(R &&r, std::size_t n)
123 : base_(rng::views::all(std::forward<R>(r))), n_(n) {}
124
125 auto begin() const {
126 return multiply_iterator(rng::begin(base_), base_.size(), 0);
127 }
128
129 auto end() const {
130 return multiply_iterator(rng::begin(base_), base_.size(),
131 n_ * base_.size());
132 }
133
134 auto size() const { return rng::size(base_); }
135
136private:
137 V base_;
138 std::size_t n_;
139};
140
141template <rng::viewable_range R>
142multiply_view(R &&r, std::size_t n) -> multiply_view<rng::views::all_t<R>>;
143
144} // namespace dr::__detail
Definition: multiply_view.hpp:16
Definition: multiply_view.hpp:119
Definition: ranges.hpp:242