Distributed Ranges
Loading...
Searching...
No Matches
transform.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 {
15
16template <std::random_access_iterator Iter, std::copy_constructible F>
18public:
19 using value_type = std::invoke_result_t<F, std::iter_value_t<Iter>>;
20 using difference_type = std::iter_difference_t<Iter>;
22 using reference = value_type;
23
24 using pointer = iterator;
25
26 using iterator_category = std::random_access_iterator_tag;
27
28 transform_iterator(Iter iter, F fn) noexcept : iter_(iter) {}
29 transform_iterator() noexcept = default;
30 ~transform_iterator() noexcept = default;
31 transform_iterator(const transform_iterator &) noexcept = default;
32 transform_iterator &operator=(const transform_iterator &) noexcept = default;
33
34 bool operator==(const transform_iterator &other) const noexcept {
35 return iter_ == other.iter_;
36 }
37
38 bool operator!=(const transform_iterator &other) const noexcept {
39 return iter_ != other.iter_;
40 }
41
42 iterator operator+(difference_type offset) const noexcept {
43 return iterator(iter_ + offset, fn_);
44 }
45
46 iterator operator-(difference_type offset) const noexcept {
47 return iterator(iter_ - offset, fn_);
48 }
49
50 difference_type operator-(iterator other) const noexcept {
51 return iter_ - other.iter_;
52 }
53
54 bool operator<(iterator other) const noexcept { return iter_ < other.iter_; }
55
56 bool operator>(iterator other) const noexcept { return iter_ > other.iter_; }
57
58 bool operator<=(iterator other) const noexcept {
59 return iter_ <= other.iter_;
60 }
61
62 bool operator>=(iterator other) const noexcept {
63 return iter_ >= other.iter_;
64 }
65
66 iterator &operator++() noexcept {
67 ++iter_;
68 return *this;
69 }
70
71 iterator operator++(int) noexcept {
72 iterator other = *this;
73 ++(*this);
74 return other;
75 }
76
77 iterator &operator--() noexcept {
78 --iter_;
79 return *this;
80 }
81
82 iterator operator--(int) noexcept {
83 iterator other = *this;
84 --(*this);
85 return other;
86 }
87
88 iterator &operator+=(difference_type offset) noexcept {
89 iter_ += offset;
90 return *this;
91 }
92
93 iterator &operator-=(difference_type offset) noexcept {
94 iter_ -= offset;
95 return *this;
96 }
97
98 reference operator*() const noexcept { return fn_(*iter_); }
99
100 reference operator[](difference_type offset) const noexcept {
101 return *(*this + offset);
102 }
103
104 friend iterator operator+(difference_type n, iterator iter) {
105 return iter.iter_ + n;
106 }
107
108 auto local() const
110 {
111 auto iter = dr::ranges::__detail::local(iter_);
113 }
114
115private:
116 Iter iter_;
117 F fn_;
118};
119
120template <rng::random_access_range V, std::copy_constructible F>
121 requires(std::is_default_constructible_v<F>)
122class transform_view : public rng::view_interface<transform_view<V, F>> {
123public:
124 template <rng::viewable_range R>
125 transform_view(R &&r, F fn)
126 : base_(rng::views::all(std::forward<R>(r))), fn_(fn) {}
127
128 auto begin() const { return transform_iterator(rng::begin(base_), fn_); }
129
130 auto end() const { return transform_iterator(rng::end(base_), fn_); }
131
132 auto size() const
133 requires(rng::sized_range<V>)
134 {
135 return rng::size(base_);
136 }
137
138 auto segments() const
140 {
141 auto fn = fn_;
142 return dr::ranges::segments(base_) |
143 rng::views::transform([fn]<typename T>(T &&segment) {
144 return transform_view<rng::views::all_t<decltype(segment)>, F>(
145 std::forward<T>(segment), fn);
146 });
147 }
148
149 auto rank() const
150 requires(dr::remote_range<V>)
151 {
152 return dr::ranges::rank(base_);
153 }
154
155 V base() const { return base_; }
156
157private:
158 V base_;
159 F fn_;
160};
161
162template <rng::viewable_range R, std::copy_constructible F>
164
165namespace views {
166
167template <std::copy_constructible F> class transform_adapter_closure {
168public:
169 transform_adapter_closure(F fn) : fn_(fn) {}
170
171 template <rng::viewable_range R> auto operator()(R &&r) const {
172 return dr::transform_view(std::forward<R>(r), fn_);
173 }
174
175 template <rng::viewable_range R>
176 friend auto operator|(R &&r, const transform_adapter_closure &closure) {
177 return closure(std::forward<R>(r));
178 }
179
180private:
181 F fn_;
182};
183
185public:
186 template <rng::viewable_range R, std::copy_constructible F>
187 auto operator()(R &&r, F &&f) const {
188 return transform_adapter_closure(std::forward<F>(f))(std::forward<R>(r));
189 }
190
191 template <std::copy_constructible F> auto operator()(F &&fn) const {
192 return transform_adapter_closure(std::forward<F>(fn));
193 }
194};
195
196inline constexpr auto transform = transform_fn_{};
197} // namespace views
198
199} // namespace dr
200
201#if !defined(DR_SPEC)
202
203// Needed to satisfy rng::viewable_range
204template <rng::random_access_range V, std::copy_constructible F>
205inline constexpr bool rng::enable_borrowed_range<dr::transform_view<V, F>> =
206 true;
207
208#endif
Definition: transform.hpp:17
Definition: transform.hpp:122
Definition: transform.hpp:167
Definition: transform.hpp:184
Definition: concepts.hpp:20
Definition: ranges.hpp:242
Definition: concepts.hpp:16