49 ,
private detail::non_propagating_cache<iterator_t<Rng>, cycled_view<Rng>,
57 using cache_t = detail::non_propagating_cache<iterator_t<Rng>,
cycled_view<Rng>,
60 template<
bool IsConst>
64 friend struct cursor<!IsConst>;
66 using constify_if = meta::const_if_c<IsConst, T>;
67 using cycled_view_t = constify_if<cycled_view>;
68 using CRng = constify_if<Rng>;
71 cycled_view_t * rng_{};
75 iterator get_end_(std::true_type,
bool =
false)
const
77 return ranges::end(rng_->rng_);
79 template<
bool CanBeEmpty = false>
82 auto & end_ =
static_cast<cache_t &
>(*rng_);
83 RANGES_EXPECT(CanBeEmpty || end_);
84 if(CanBeEmpty && !end_)
85 end_ = ranges::next(it_, ranges::end(rng_->rng_));
88 void set_end_(std::true_type)
const
90 void set_end_(std::false_type)
const
92 auto & end_ =
static_cast<cache_t &
>(*rng_);
99 cursor(cycled_view_t * rng)
101 , it_(ranges::begin(rng->rng_))
103 template(
bool Other)(
104 requires IsConst AND CPP_NOT(Other))
105 cursor(cursor<Other> that)
107 , it_(std::move(that.it_))
110 auto CPP_auto_fun(read)()(
const)
116 auto equal(cursor
const & pos)
const
118 requires equality_comparable<iterator>)
120 RANGES_EXPECT(rng_ == pos.rng_);
121 return n_ == pos.n_ && it_ == pos.it_;
125 auto const last = ranges::end(rng_->rng_);
126 RANGES_EXPECT(it_ != last);
131 it_ = ranges::begin(rng_->rng_);
139 if(it_ == ranges::begin(rng_->rng_))
141 RANGES_EXPECT(n_ > 0);
147 template(
typename Diff)(
149 detail::integer_like_<Diff>)
152 auto const first = ranges::begin(rng_->rng_);
155 auto const dist = last - first;
156 auto const d = it_ - first;
157 auto const off = (d + n) % dist;
158 n_ += (d + n) / dist;
159 RANGES_EXPECT(n_ >= 0);
160 using D = range_difference_t<Rng>;
161 it_ = first +
static_cast<D
>(off < 0 ? off + dist : off);
164 auto CPP_fun(distance_to)(cursor
const & that)(
const
167 RANGES_EXPECT(that.rng_ == rng_);
168 auto const first = ranges::begin(rng_->rng_);
171 auto const dist = last - first;
172 return (that.n_ - n_) * dist + (that.it_ - it_);
178 -> CPP_ret(cursor<false>)(
184 auto begin_cursor()
const
185 -> CPP_ret(cursor<true>)(
199 : rng_(std::move(rng))
201 RANGES_EXPECT(!ranges::empty(rng_));