9#include <dr/concepts/concepts.hpp>
10#include <dr/detail/iterator_adaptor.hpp>
11#include <dr/detail/ranges.hpp>
12#include <dr/detail/segments_tools.hpp>
13#include <dr/sp/device_span.hpp>
19 using element_type = T;
20 using value_type = std::remove_cv_t<T>;
22 using segment_type = L;
24 using size_type = rng::range_size_t<segment_type>;
25 using difference_type = rng::range_difference_t<segment_type>;
28 using reference = rng::range_reference_t<segment_type>;
30 using iterator_category = std::random_access_iterator_tag;
45 size_type idx) noexcept
46 : segments_(segments), segment_id_(segment_id), idx_(idx) {}
49 operator+=(difference_type offset)
noexcept {
52 difference_type current_offset =
53 std::min(offset, difference_type(segments_[segment_id_].size()) -
54 difference_type(idx_));
55 idx_ += current_offset;
56 offset -= current_offset;
58 if (idx_ >= segments_[segment_id_].size()) {
65 difference_type current_offset =
66 std::min(-offset, difference_type(idx_) + 1);
68 difference_type new_idx = difference_type(idx_) - current_offset;
72 new_idx = segments_[segment_id_].size() - 1;
82 return segment_id_ == other.segment_id_ && idx_ == other.idx_;
85 constexpr difference_type
87 return difference_type(get_global_idx()) - other.get_global_idx();
91 if (segment_id_ < other.segment_id_) {
93 }
else if (segment_id_ == other.segment_id_) {
94 return idx_ < other.idx_;
100 constexpr reference operator*()
const noexcept {
101 return segments_[segment_id_][idx_];
104 auto segments()
const noexcept {
105 return dr::__detail::drop_segments(segments_, segment_id_, idx_);
109 size_type get_global_idx()
const noexcept {
110 size_type cumulative_size = 0;
111 for (std::size_t i = 0; i < segment_id_; i++) {
112 cumulative_size += segments_[i].size();
114 return cumulative_size + idx_;
117 std::span<segment_type> segments_;
118 size_type segment_id_ = 0;
122template <
typename T,
typename L>
126template <
typename T,
typename L>
129 using element_type = T;
130 using value_type = std::remove_cv_t<T>;
134 using size_type = rng::range_size_t<segment_type>;
135 using difference_type = rng::range_difference_t<segment_type>;
138 using reference = rng::range_reference_t<segment_type>;
156 template <rng::input_range R>
159 for (
auto &&segment : segments) {
160 std::size_t size = rng::size(segment);
162 segment_type(rng::begin(segment), size, dr::ranges::rank(segment)));
168 for (
auto &&segment : dr::ranges::segments(std::forward<R>(r))) {
169 std::size_t size = rng::size(segment);
171 segment_type(rng::begin(segment), size, dr::ranges::rank(segment)));
176 constexpr size_type size()
const noexcept {
return size_; }
178 constexpr size_type size_bytes()
const noexcept {
179 return size() *
sizeof(element_type);
182 constexpr reference operator[](size_type idx)
const {
184 std::size_t span_id = 0;
185 for (std::size_t span_id = 0; idx >= segments()[span_id].size();
187 idx -= segments()[span_id].size();
189 return segments()[span_id][idx];
192 [[nodiscard]]
constexpr bool empty()
const noexcept {
return size() == 0; }
195 subspan(size_type Offset, size_type Count = std::dynamic_extent)
const {
196 Count = std::min(Count, size() - Offset);
198 std::vector<segment_type> new_segments;
201 std::size_t segment_id = 0;
202 for (segment_id = 0; Offset >= segments()[segment_id].size();
204 Offset -= segments()[segment_id].size();
210 std::size_t local_count =
211 std::min(Count, segments()[segment_id].size() - Offset);
212 auto new_segment = segments()[segment_id].subspan(Offset, local_count);
213 new_segments.push_back(new_segment);
214 Count -= local_count;
223 return subspan(0, Count);
227 return subspan(size() - Count, Count);
234 constexpr reference front() {
return segments().front().front(); }
236 constexpr reference back() {
return segments().back().back(); }
238 std::span<segment_type> segments() {
return segments_; }
240 std::span<const segment_type> segments()
const {
return segments_; }
243 std::size_t size_ = 0;
244 std::vector<segment_type> segments_;
247template <rng::input_range R>
250 rng::iterator_t<rng::range_value_t<R>>>;
252template <dr::distributed_contiguous_range R>
254 rng::range_value_t<R>,
255 rng::iterator_t<rng::range_value_t<
decltype(dr::ranges::segments(r))>>>;
Definition: iterator_adaptor.hpp:23
Definition: device_span.hpp:44
Definition: distributed_span.hpp:17
Definition: distributed_span.hpp:127
Definition: concepts.hpp:16