13#ifndef RANGES_V3_ITERATOR_OPERATIONS_HPP
14#define RANGES_V3_ITERATOR_OPERATIONS_HPP
25#include <range/v3/detail/prologue.hpp>
35 struct counted_iterator;
40#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
43 constexpr void operator()(I & i, iter_difference_t<I> n)
const
55 RANGES_EXPECT(0 <= n);
61 template(
typename I,
typename S)(
63 constexpr void operator()(I & i, S bound)
const
66 if constexpr(assignable_from<I &, S>)
72 iter_difference_t<I> d = bound - i;
73 RANGES_EXPECT(0 <= d);
81 template(
typename I,
typename S)(
83 constexpr iter_difference_t<I>
84 operator()(I & i, iter_difference_t<I> n, S bound)
const
94 const auto d = bound - i;
97 RANGES_EXPECT(0 <= n ? 0 <= d : 0 >= d);
98 if(0 <= n ? d <= n : d >= n)
100 i = std::move(bound);
106 RANGES_EXPECT(0 <= n && 0 <= d);
109 (*this)(i, std::move(bound));
126 }
while(0 != n && i != bound);
130 RANGES_EXPECT(0 <= n);
131 while(0 != n && i != bound)
142 static constexpr void n_(I & i, iter_difference_t<I> n, std::input_iterator_tag);
144 static constexpr void n_(I & i, iter_difference_t<I> n,
145 std::bidirectional_iterator_tag);
147 static constexpr void n_(I & i, iter_difference_t<I> n,
148 std::random_access_iterator_tag);
149 template<
typename I,
typename S>
150 static constexpr void to_impl_(I & i, S s,
sentinel_tag);
151 template<
typename I,
typename S>
153 template<
typename I,
typename S>
154 static constexpr void to_(I & i, S s, std::true_type);
155 template<
typename I,
typename S>
156 static constexpr void to_(I & i, S s, std::false_type);
157 template<
typename I,
typename S>
158 static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
160 std::input_iterator_tag);
162 static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
164 std::bidirectional_iterator_tag);
165 template<
typename I,
typename S,
typename Concept>
166 static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
172 template(
typename I)(
174 constexpr void operator()(I & i, iter_difference_t<I> n)
const
176 advance_fn::n_(i, n, iterator_tag_of<I>{});
179 template(
typename I,
typename S)(
181 constexpr void operator()(I & i, S s)
const
184 i,
static_cast<S &&
>(s),
meta::bool_<assignable_from<I &, S>>());
187 template(
typename I,
typename S)(
189 constexpr iter_difference_t<I>
190 operator()(I & it, iter_difference_t<I> n, S bound)
const
192 return advance_fn::bounded_(it,
194 static_cast<S &&
>(bound),
195 sentinel_tag_of<S, I>(),
196 iterator_tag_of<I>());
200 template(
typename I)(
202 constexpr void operator()(counted_iterator<I> & i, iter_difference_t<I> n)
const;
208#if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
210 constexpr void advance_fn::n_(I & i, iter_difference_t<I> n, std::input_iterator_tag)
212 RANGES_EXPECT(n >= 0);
217 constexpr void advance_fn::n_(I & i, iter_difference_t<I> n,
218 std::bidirectional_iterator_tag)
228 constexpr void advance_fn::n_(I & i, iter_difference_t<I> n,
229 std::random_access_iterator_tag)
233 template<
typename I,
typename S>
234 constexpr void advance_fn::to_impl_(I & i, S s, sentinel_tag)
239 template<
typename I,
typename S>
240 constexpr void advance_fn::to_impl_(I & i, S s, sized_sentinel_tag)
242 iter_difference_t<I> d = s - i;
243 RANGES_EXPECT(0 <= d);
247 template<
typename I,
typename S>
248 constexpr void advance_fn::to_(I & i, S s, std::true_type)
250 i =
static_cast<S &&
>(s);
252 template<
typename I,
typename S>
253 constexpr void advance_fn::to_(I & i, S s, std::false_type)
255 advance_fn::to_impl_(i,
static_cast<S &&
>(s), sentinel_tag_of<S, I>());
257 template<
typename I,
typename S>
258 constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
259 S bound, sentinel_tag,
260 std::input_iterator_tag)
262 RANGES_EXPECT(0 <= n);
263 for(; 0 != n && it != bound; --n)
268 constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
269 I bound, sentinel_tag,
270 std::bidirectional_iterator_tag)
273 for(; 0 != n && it != bound; --n)
276 for(; 0 != n && it != bound; ++n)
280 template<
typename I,
typename S,
typename Concept>
281 constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
282 S bound, sized_sentinel_tag,
285 RANGES_EXPECT(((
bool)same_as<I, S> || 0 <= n));
288 iter_difference_t<I> d = bound - it;
289 RANGES_EXPECT(0 <= n ? 0 <= d : 0 >= d);
290 if(0 <= n ? n >= d : n <= d)
292 advance(it,
static_cast<S &&
>(bound));
302 template(
typename I)(
304 constexpr I operator()(I it)
const
308 template(
typename I)(
310 constexpr I operator()(I it, iter_difference_t<I> n)
const
315 template(
typename I,
typename S)(
317 constexpr I operator()(I it, S s)
const
319 advance(it,
static_cast<S &&
>(s));
322 template(
typename I,
typename S)(
324 constexpr I operator()(I it, iter_difference_t<I> n, S bound)
const
326 advance(it, n,
static_cast<S &&
>(bound));
332 RANGES_INLINE_VARIABLE(
next_fn, next)
336 template(
typename I)(
338 constexpr I operator()(I it)
const
342 template(
typename I)(
344 constexpr I operator()(I it, iter_difference_t<I> n)
const
349 template(
typename I)(
351 constexpr I operator()(I it, iter_difference_t<I> n, I bound)
const
353 advance(it, -n,
static_cast<I &&
>(bound));
359 RANGES_INLINE_VARIABLE(
prev_fn, prev)
364 template(
typename I,
typename S)(
366 static constexpr std::pair<iter_difference_t<I>, I>
369 iter_difference_t<I> d = 0;
370 for(; first != last; ++first)
374 template(
typename I,
typename S)(
376 static constexpr std::pair<iter_difference_t<I>, I>
379 I last = ranges::next(first, end_);
380 auto n =
static_cast<iter_difference_t<I>
>(last - first);
381 RANGES_EXPECT(((
bool)same_as<I, S> || 0 <= n));
384 template<
typename I,
typename S>
385 static constexpr std::pair<iter_difference_t<I>, I>
388 auto n =
static_cast<iter_difference_t<I>
>(last - first);
389 RANGES_EXPECT(((
bool)same_as<I, S> || 0 <= n));
390 return {n, ranges::next(first, last)};
394 template(
typename I,
typename S)(
396 constexpr std::pair<iter_difference_t<I>, I> operator()(I first, S last)
const
398 return iter_enumerate_fn::impl_i(
static_cast<I &&
>(first),
399 static_cast<S &&
>(last),
400 sentinel_tag_of<S, I>());
410 template<
typename I,
typename S>
411 static constexpr iter_difference_t<I> impl_i(I first, S last,
sentinel_tag)
413 return iter_enumerate(
static_cast<I &&
>(first),
static_cast<S &&
>(last))
416 template<
typename I,
typename S>
419 auto n =
static_cast<iter_difference_t<I>
>(last - first);
420 RANGES_EXPECT(((
bool)same_as<I, S> || 0 <= n));
425 template(
typename I,
typename S)(
427 constexpr iter_difference_t<I> operator()(I first, S last)
const
429 return iter_distance_fn::impl_i(
static_cast<I &&
>(first),
430 static_cast<S &&
>(last),
431 sentinel_tag_of<S, I>());
441 template<
typename I,
typename S>
442 static constexpr int impl_i(I first, S last, iter_difference_t<I> n,
sentinel_tag)
446 for(; n > 0; --n, ++first)
451 return first == last ? 0 : 1;
453 template<
typename I,
typename S>
454 static constexpr int impl_i(I first, S last, iter_difference_t<I> n,
457 iter_difference_t<I> dist = last - first;
466 template(
typename I,
typename S)(
468 constexpr int operator()(I first, S last, iter_difference_t<I> n)
const
470 return iter_distance_compare_fn::impl_i(
static_cast<I &&
>(first),
471 static_cast<S &&
>(last),
473 sentinel_tag_of<S, I>());
483 template(
typename I,
typename S)(
486 operator()(I
const & first, S last)
const
489 iter_difference_t<I> n = last - first;
490 RANGES_EXPECT(0 <= n);
491 return static_cast<size_type
>(n);
499 namespace adl_uncounted_recounted_detail
502 constexpr I uncounted(I i)
508 constexpr I recounted(I
const &, I i, iter_difference_t<I>)
516 constexpr auto operator()(I i)
const ->
decltype(uncounted((I &&) i))
518 return uncounted((I &&) i);
524 template<
typename I,
typename J>
525 constexpr auto operator()(I i, J j, iter_difference_t<J> n)
const
526 ->
decltype(recounted((I &&) i, (J &&) j, n))
528 return recounted((I &&) i, (J &&) j, n);
534 RANGES_INLINE_VARIABLE(adl_uncounted_recounted_detail::uncounted_fn, uncounted)
535 RANGES_INLINE_VARIABLE(adl_uncounted_recounted_detail::recounted_fn, recounted)
540 template<
typename Rng>
541 static constexpr std::pair<range_difference_t<Rng>,
iterator_t<Rng>> impl_r(
544 return iter_enumerate(begin(rng), end(rng));
546 template<
typename Rng>
547 static constexpr std::pair<range_difference_t<Rng>,
iterator_t<Rng>> impl_r(
550 return {
static_cast<range_difference_t<Rng>
>(size(rng)), end(rng)};
554 using iter_enumerate_fn::operator();
556 template(
typename Rng)(
558 constexpr std::pair<range_difference_t<Rng>,
iterator_t<Rng>> operator()(Rng && rng)
const
561 RANGES_EXPECT(!is_infinite<Rng>::value);
562 return enumerate_fn::impl_r(
563 rng, common_range_tag_of<Rng>(), sized_range_tag_of<Rng>());
573 template<
typename Rng>
574 static range_difference_t<Rng> impl_r(Rng & rng,
range_tag)
576 return enumerate(rng).first;
578 template<
typename Rng>
579 static constexpr range_difference_t<Rng> impl_r(Rng & rng,
sized_range_tag)
581 return static_cast<range_difference_t<Rng>
>(size(rng));
585 using iter_distance_fn::operator();
587 template(
typename Rng)(
589 constexpr range_difference_t<Rng> operator()(Rng && rng)
const
592 RANGES_EXPECT(!is_infinite<Rng>::value);
593 return distance_fn::impl_r(rng, sized_range_tag_of<Rng>());
604 template<
typename Rng>
605 static constexpr int impl_r(Rng & rng, range_difference_t<Rng> n,
range_tag)
608 return is_infinite<Rng>::value
610 : iter_distance_compare(begin(rng), end(rng), n);
612 template<
typename Rng>
613 static constexpr int impl_r(Rng & rng, range_difference_t<Rng> n,
sized_range_tag)
615 auto dist = distance(rng);
625 using iter_distance_compare_fn::operator();
627 template(
typename Rng)(
629 constexpr int operator()(Rng && rng, range_difference_t<Rng> n)
const
631 return distance_compare_fn::impl_r(rng, n, sized_range_tag_of<Rng>());
640 using ranges::advance;
641 using ranges::distance;
648#include <range/v3/detail/epilogue.hpp>
The bidirectional_iterator concept.
The random_access_iterator concept.
The sentinel_for concept.
The sized_sentinel_for concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
Definition operations.hpp:39
Definition concepts.hpp:305
Definition operations.hpp:602
Definition operations.hpp:571
Definition operations.hpp:538
Definition operations.hpp:439
Definition operations.hpp:408
Definition operations.hpp:362
Definition operations.hpp:482
Definition operations.hpp:301
Definition operations.hpp:335
Definition concepts.hpp:268
Definition concepts.hpp:871
Definition concepts.hpp:316
Definition concepts.hpp:873