1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11// ranges::advance(it, n)
12
13#include <iterator>
14
15#include <algorithm>
16#include <cassert>
17
18#include "test_iterators.h"
19#include "test_macros.h"
20
21template <bool Count, typename It>
22constexpr void check(int* first, std::iter_difference_t<It> n, int* expected) {
23 using Difference = std::iter_difference_t<It>;
24 Difference const M = (expected - first); // expected travel distance (which may be negative)
25 auto abs = [](auto x) { return x < 0 ? -x : x; };
26
27 {
28 It it(first);
29 std::ranges::advance(it, n);
30 assert(base(it) == expected);
31 ASSERT_SAME_TYPE(decltype(std::ranges::advance(it, n)), void);
32 }
33
34 // Count operations
35 if constexpr (Count) {
36 IteratorOpCounts ops;
37 auto it = operation_counting_iterator(It(first), &ops);
38 std::ranges::advance(it, n);
39 if constexpr (std::random_access_iterator<It>) {
40 assert(ops.increments + ops.decrements <= 1);
41 } else {
42 const auto big = std::max(ops.increments, ops.decrements);
43 const auto small = std::min(ops.increments, ops.decrements);
44 assert(big == std::size_t(abs(M)));
45 assert(small == 0);
46 }
47 }
48}
49
50constexpr bool test() {
51 int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
52
53 // Check advancing forward
54 for (int n = 0; n != 10; ++n) {
55 check<false, cpp17_input_iterator<int*>>( range, n, range+n);
56 check<false, cpp20_input_iterator<int*>>( range, n, range+n);
57 check<true, forward_iterator<int*>>( range, n, range+n);
58 check<true, bidirectional_iterator<int*>>(range, n, range+n);
59 check<true, random_access_iterator<int*>>(range, n, range+n);
60 check<true, contiguous_iterator<int*>>( range, n, range+n);
61 check<true, int*>( range, n, range+n);
62 check<true, cpp17_output_iterator<int*> >(range, n, range+n);
63 }
64
65 // Check advancing backward
66 for (int n = 0; n != 10; ++n) {
67 check<true, bidirectional_iterator<int*>>(range+9, -n, range+9 - n);
68 check<true, random_access_iterator<int*>>(range+9, -n, range+9 - n);
69 check<true, contiguous_iterator<int*>>( range+9, -n, range+9 - n);
70 check<true, int*>( range+9, -n, range+9 - n);
71 }
72
73 return true;
74}
75
76int main(int, char**) {
77 assert(test());
78 static_assert(test());
79 return 0;
80}
81

source code of libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_count.pass.cpp