# 25 Iterators library [iterators]

## 25.4 Iterator primitives [iterator.primitives]

### 25.4.4 Range iterator operations [range.iter.ops]

```template<input_or_output_iterator I> constexpr void ranges::advance(I& i, iter_difference_t<I> n); ```
Preconditions: If I does not model bidirectional_iterator, n is not negative.
Effects:
```template<input_or_output_iterator I, sentinel_for<I> S> constexpr void ranges::advance(I& i, S bound); ```
Preconditions: Either assignable_from<I&, S> || sized_sentinel_for<S, I> is modeled, or [i, bound) denotes a range.
Effects:
• If I and S model assignable_from<I&, S>, equivalent to i = std​::​move(bound).
• Otherwise, if S and I model sized_sentinel_for<S, I>, equivalent to ranges​::​advance(i, bound - i).
• Otherwise, while bool(i != bound) is true, increments i.
```template<input_or_output_iterator I, sentinel_for<I> S> constexpr iter_difference_t<I> ranges::advance(I& i, iter_difference_t<I> n, S bound); ```
Preconditions: If n > 0, [i, bound) denotes a range.
If n == 0, [i, bound) or [bound, i) denotes a range.
If n < 0, [bound, i) denotes a range, I models bidirectional_iterator, and I and S model same_as<I, S>.
Effects:
• If S and I model sized_sentinel_for<S, I>:
• If ​, equivalent to ranges​::​advance(i, bound).
• Otherwise, equivalent to ranges​::​advance(i, n).
• Otherwise,
• if n is non-negative, while bool(i != bound) is true, increments i but at most n times.
• Otherwise, while bool(i != bound) is true, decrements i but at most -n times.
Returns: n - M, where M is the difference between the ending and starting positions of i.