Distributed Ranges
Loading...
Searching...
No Matches
normal_distributed_iterator.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4#pragma once
5
6#include <dr/detail/segments_tools.hpp>
7
8namespace dr {
9
10template <rng::viewable_range V>
11/*
12requires(dr::remote_range<rng::range_reference_t<V>> &&
13 rng::random_access_range<rng::range_reference_t<V>>)
14 */
16public:
17 using value_type = rng::range_value_t<rng::range_reference_t<V>>;
18
19 using segment_type = rng::range_value_t<V>;
20
21 using size_type = rng::range_size_t<segment_type>;
22 using difference_type = rng::range_difference_t<segment_type>;
23
24 using reference = rng::range_reference_t<segment_type>;
25
26 using iterator_category = std::random_access_iterator_tag;
27
31
32 constexpr normal_distributed_iterator_accessor() noexcept = default;
33 constexpr ~normal_distributed_iterator_accessor() noexcept = default;
35 const normal_distributed_iterator_accessor &) noexcept = default;
37 operator=(const normal_distributed_iterator_accessor &) noexcept = default;
38
39 constexpr normal_distributed_iterator_accessor(V segments,
40 size_type segment_id,
41 size_type idx) noexcept
42 : segments_(segments), segment_id_(segment_id), idx_(idx) {}
43
45 operator+=(difference_type offset) noexcept {
46
47 while (offset > 0) {
48 difference_type current_offset =
49 std::min(offset, difference_type(segments_[segment_id_].size()) -
50 difference_type(idx_));
51 idx_ += current_offset;
52 offset -= current_offset;
53
54 if (idx_ >= segments_[segment_id_].size()) {
55 segment_id_++;
56 idx_ = 0;
57 }
58 }
59
60 while (offset < 0) {
61 difference_type current_offset =
62 std::min(-offset, difference_type(idx_) + 1);
63
64 difference_type new_idx = difference_type(idx_) - current_offset;
65 offset += current_offset;
66
67 if (new_idx < 0) {
68 segment_id_--;
69 new_idx = segments_[segment_id_].size() - 1;
70 }
71
72 idx_ = new_idx;
73 }
74
75 return *this;
76 }
77
78 constexpr bool operator==(const iterator_accessor &other) const noexcept {
79 return segment_id_ == other.segment_id_ && idx_ == other.idx_;
80 }
81
82 constexpr difference_type
83 operator-(const iterator_accessor &other) const noexcept {
84 return difference_type(get_global_idx()) - other.get_global_idx();
85 }
86
87 constexpr bool operator<(const iterator_accessor &other) const noexcept {
88 if (segment_id_ < other.segment_id_) {
89 return true;
90 } else if (segment_id_ == other.segment_id_) {
91 return idx_ < other.idx_;
92 } else {
93 return false;
94 }
95 }
96
97 constexpr reference operator*() const noexcept {
98 return segments_[segment_id_][idx_];
99 }
100
101 auto segments() const noexcept {
102 return dr::__detail::drop_segments(segments_, segment_id_, idx_);
103 }
104
105private:
106 size_type get_global_idx() const noexcept {
107 size_type cumulative_size = 0;
108 for (std::size_t i = 0; i < segment_id_; i++) {
109 cumulative_size += segments_[i].size();
110 }
111 return cumulative_size + idx_;
112 }
113
114 rng::views::all_t<V> segments_;
115 size_type segment_id_ = 0;
116 size_type idx_ = 0;
117};
118
119template <rng::viewable_range T>
122
123} // namespace dr
Definition: iterator_adaptor.hpp:23
Definition: normal_distributed_iterator.hpp:15