6#include <dr/detail/segments_tools.hpp>
10template <rng::viewable_range V>
17 using value_type = rng::range_value_t<rng::range_reference_t<V>>;
19 using segment_type = rng::range_value_t<V>;
21 using size_type = rng::range_size_t<segment_type>;
22 using difference_type = rng::range_difference_t<segment_type>;
24 using reference = rng::range_reference_t<segment_type>;
26 using iterator_category = std::random_access_iterator_tag;
41 size_type idx) noexcept
42 : segments_(segments), segment_id_(segment_id), idx_(idx) {}
45 operator+=(difference_type offset)
noexcept {
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;
54 if (idx_ >= segments_[segment_id_].size()) {
61 difference_type current_offset =
62 std::min(-offset, difference_type(idx_) + 1);
64 difference_type new_idx = difference_type(idx_) - current_offset;
65 offset += current_offset;
69 new_idx = segments_[segment_id_].size() - 1;
79 return segment_id_ == other.segment_id_ && idx_ == other.idx_;
82 constexpr difference_type
84 return difference_type(get_global_idx()) - other.get_global_idx();
88 if (segment_id_ < other.segment_id_) {
90 }
else if (segment_id_ == other.segment_id_) {
91 return idx_ < other.idx_;
97 constexpr reference operator*()
const noexcept {
98 return segments_[segment_id_][idx_];
101 auto segments()
const noexcept {
102 return dr::__detail::drop_segments(segments_, segment_id_, idx_);
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();
111 return cumulative_size + idx_;
114 rng::views::all_t<V> segments_;
115 size_type segment_id_ = 0;
119template <rng::viewable_range T>
Definition: iterator_adaptor.hpp:23
Definition: normal_distributed_iterator.hpp:15