13#ifndef RANGES_V3_ITERATOR_COUNTED_ITERATOR_HPP
14#define RANGES_V3_ITERATOR_COUNTED_ITERATOR_HPP
27#include <range/v3/detail/prologue.hpp>
35 namespace _counted_iterator_
40 static constexpr iter_difference_t<counted_iterator<I>> &
count(
41 counted_iterator<I> & ci)
noexcept
47 static constexpr I & current(counted_iterator<I> & ci)
noexcept
53 static constexpr I
const & current(counted_iterator<I>
const & ci)
noexcept
60 struct contiguous_iterator_concept_base
64 struct contiguous_iterator_concept_base<true>
73 struct counted_iterator
74 : _counted_iterator_::contiguous_iterator_concept_base<(bool)contiguous_iterator<I>>
78 CPP_assert(input_or_output_iterator<I>);
79 friend _counted_iterator_::access;
82 iter_difference_t<I> cnt_{0};
84 constexpr void post_increment_(std::true_type)
86 CPP_assert(std::is_void<
decltype(current_++)>());
90 constexpr auto post_increment_(std::false_type) ->
decltype(current_++)
92 CPP_assert(!std::is_void<
decltype(current_++)>());
93 auto && tmp = current_++;
95 return static_cast<decltype(tmp) &&
>(tmp);
99 using iterator_type = I;
100 using difference_type = iter_difference_t<I>;
102 counted_iterator() =
default;
104 constexpr counted_iterator(I x, iter_difference_t<I> n)
105 : current_(std::move(x))
108 RANGES_EXPECT(n >= 0);
111 template(
typename I2)(
112 requires convertible_to<I2, I>)
113 constexpr counted_iterator(counted_iterator<I2>
const & i)
114 : current_(_counted_iterator_::access::current(i))
118 template(
typename I2)(
119 requires convertible_to<I2, I>)
120 constexpr counted_iterator & operator=(counted_iterator<I2>
const & i)
122 current_ = _counted_iterator_::access::current(i);
126 constexpr I base()
const
131 constexpr iter_difference_t<I>
count()
const
136 constexpr iter_reference_t<I>
operator*() noexcept(
137 noexcept(iter_reference_t<I>(*current_)))
139 RANGES_EXPECT(cnt_ > 0);
142 template(
typename I2 = I)(
143 requires indirectly_readable<I2 const>)
144 constexpr iter_reference_t<I2>
operator*() const
145 noexcept(noexcept(iter_reference_t<I>(*current_)))
147 RANGES_EXPECT(cnt_ > 0);
151 constexpr counted_iterator & operator++()
153 RANGES_EXPECT(cnt_ > 0);
159#ifdef RANGES_WORKAROUND_MSVC_677925
160 template(
typename I2 = I)(
161 requires (!forward_iterator<I2>))
162 constexpr auto operator++(
int) ->
decltype(std::declval<I2 &>()++)
165 constexpr auto operator++(
int)
166 -> CPP_ret(
decltype(std::declval<I &>()++))(
167 requires (!forward_iterator<I>))
170 RANGES_EXPECT(cnt_ > 0);
171 return post_increment_(std::is_void<
decltype(current_++)>());
175 constexpr auto operator++(
int)
176 -> CPP_ret(counted_iterator)(
177 requires forward_iterator<I>)
185 constexpr auto operator--()
186 -> CPP_ret(counted_iterator &)(
187 requires bidirectional_iterator<I>)
195 constexpr auto operator--(
int)
196 -> CPP_ret(counted_iterator)(
197 requires bidirectional_iterator<I>)
205 constexpr auto operator+=(difference_type n)
206 -> CPP_ret(counted_iterator &)(
207 requires random_access_iterator<I>)
209 RANGES_EXPECT(cnt_ >= n);
216 constexpr auto operator+(difference_type n)
const
217 -> CPP_ret(counted_iterator)(
218 requires random_access_iterator<I>)
226 constexpr auto operator-=(difference_type n)
227 -> CPP_ret(counted_iterator &)(
228 requires random_access_iterator<I>)
230 RANGES_EXPECT(cnt_ >= -n);
237 constexpr auto operator-(difference_type n)
const
238 -> CPP_ret(counted_iterator)(
239 requires random_access_iterator<I>)
247 constexpr auto operator[](difference_type n)
const
248 -> CPP_ret(iter_reference_t<I>)(
249 requires random_access_iterator<I>)
251 RANGES_EXPECT(cnt_ >= n);
255#if !RANGES_BROKEN_CPO_LOOKUP
257 friend constexpr auto iter_move(counted_iterator
const & i)
258 noexcept(detail::has_nothrow_iter_move_v<I>)
259 -> CPP_broken_friend_ret(iter_rvalue_reference_t<I>)(
260 requires input_iterator<I>)
262 return ranges::iter_move(i.current_);
264 template<
typename I2,
typename S2>
265 friend constexpr auto iter_swap(counted_iterator
const & x,
266 counted_iterator<I2>
const & y)
267 noexcept(is_nothrow_indirectly_swappable<I, I2>::value)
268 -> CPP_broken_friend_ret(
void)(
269 requires indirectly_swappable<I2, I>)
271 return ranges::iter_swap(x.current_, _counted_iterator_::access::current(y));
277#if RANGES_BROKEN_CPO_LOOKUP
278 namespace _counted_iterator_
281 constexpr auto iter_move(counted_iterator<I>
const & i)
noexcept(
282 detail::has_nothrow_iter_move_v<I>)
283 -> CPP_broken_friend_ret(iter_rvalue_reference_t<I>)(
284 requires input_iterator<I>)
286 return ranges::iter_move(_counted_iterator_::access::current(i));
288 template<
typename I1,
typename I2>
289 constexpr auto iter_swap(
290 counted_iterator<I1>
const & x,
291 counted_iterator<I2>
const &
292 y)
noexcept(is_nothrow_indirectly_swappable<I1, I2>::value)
293 -> CPP_broken_friend_ret(
void)(
294 requires indirectly_swappable<I2, I1>)
296 return ranges::iter_swap(_counted_iterator_::access::current(x),
297 _counted_iterator_::access::current(y));
303 template(
typename I1,
typename I2)(
304 requires common_with<I1, I2>)
305 constexpr bool operator==(counted_iterator<I1>
const & x,
306 counted_iterator<I2>
const & y)
308 return x.count() == y.count();
312 constexpr bool operator==(counted_iterator<I>
const & x, default_sentinel_t)
314 return x.count() == 0;
318 constexpr bool operator==(default_sentinel_t, counted_iterator<I>
const & x)
320 return x.count() == 0;
323 template(
typename I1,
typename I2)(
324 requires common_with<I1, I2>)
325 constexpr bool operator!=(counted_iterator<I1>
const & x,
326 counted_iterator<I2>
const & y)
332 constexpr bool operator!=(counted_iterator<I>
const & x, default_sentinel_t y)
338 constexpr bool operator!=(default_sentinel_t x, counted_iterator<I>
const & y)
343 template(
typename I1,
typename I2)(
344 requires common_with<I1, I2>)
345 constexpr bool operator<(counted_iterator<I1>
const & x,
346 counted_iterator<I2>
const & y)
348 return y.count() < x.count();
351 template(
typename I1,
typename I2)(
352 requires common_with<I1, I2>)
353 constexpr bool operator<=(counted_iterator<I1>
const & x,
354 counted_iterator<I2>
const & y)
359 template(
typename I1,
typename I2)(
360 requires common_with<I1, I2>)
361 constexpr bool operator>(counted_iterator<I1>
const & x,
362 counted_iterator<I2>
const & y)
367 template(
typename I1,
typename I2)(
368 requires common_with<I1, I2>)
369 constexpr bool operator>=(counted_iterator<I1>
const & x,
370 counted_iterator<I2>
const & y)
375 template(
typename I1,
typename I2)(
376 requires common_with<I1, I2>)
377 constexpr iter_difference_t<I2>
operator-(counted_iterator<I1>
const & x,
378 counted_iterator<I2>
const & y)
380 return y.count() - x.count();
384 constexpr iter_difference_t<I>
operator-(counted_iterator<I>
const & x,
391 constexpr iter_difference_t<I>
operator-(default_sentinel_t,
392 counted_iterator<I>
const & y)
397 template(
typename I)(
398 requires random_access_iterator<I>)
399 constexpr counted_iterator<I> operator+(iter_difference_t<I> n,
400 counted_iterator<I>
const & x)
405 template(
typename I)(
406 requires input_or_output_iterator<I>)
407 constexpr counted_iterator<I> make_counted_iterator(I i, iter_difference_t<I> n)
409 return {std::move(i), n};
413 struct indirectly_readable_traits<counted_iterator<I>>
415 (bool)indirectly_readable<I>,
416 indirectly_readable_traits<I>,
420 CPP_template_def(
typename I)(
421 requires input_or_output_iterator<I>)
422 constexpr void advance_fn::operator()(counted_iterator<I> & i,
423 iter_difference_t<I> n)
const
425 RANGES_EXPECT(n <= i.cnt_);
426 advance(i.current_, n);
432 using ranges::counted_iterator;
440 namespace _counted_iterator_
442 template<
typename I,
typename =
void>
443 struct iterator_traits_
445 using difference_type = iter_difference_t<I>;
446 using value_type = void;
447 using reference = void;
448 using pointer = void;
449 using iterator_category = std::output_iterator_tag;
453 struct iterator_traits_<I,
meta::if_c<input_iterator<I>>>
454 : std::iterator_traits<I>
456 using pointer = void;
464 struct iterator_traits<::ranges::counted_iterator<I>>
465 : ::ranges::_counted_iterator_::iterator_traits_<I>
470#include <range/v3/detail/epilogue.hpp>
#define CPP_broken_friend_member
INTERNAL ONLY.
Definition concepts.hpp:447
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1148
_t< detail::count_< L, T > > count
Count the number of times a type T appears in the list L.
Definition meta.hpp:2725
Point operator*(double s, const Point &a)
Multiply point by scalar.
Definition shapes.h:250
Point operator-(const Point &a, const Point &b)
Subtract two points_ component-wise.
Definition shapes.h:244