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// constexpr iterator& operator++();
12// constexpr iterator operator++(int);
13
14#include <cassert>
15#include <ranges>
16
17#include "test_iterators.h"
18
19template <class Iter>
20constexpr void testOne() {
21 constexpr auto make_subrange = []<std::size_t N>(int(&buffer)[N]) {
22 return std::ranges::subrange<Iter>{Iter{buffer}, Iter{buffer + N}};
23 };
24
25 // next subrange does not reach the end
26 {
27 int buffer[] = {0, 1, 2, -1, 4, 5, -1, 7};
28 auto input = make_subrange(buffer);
29 std::ranges::split_view sv(input, -1);
30 using SplitIter = std::ranges::iterator_t<decltype(sv)>;
31
32 // ++it
33 {
34 auto it = sv.begin();
35
36 decltype(auto) it1 = ++it;
37 static_assert(std::is_same_v<decltype(it1), SplitIter&>);
38 assert(&it1 == &it);
39
40 assert(base((*it).begin()) == buffer + 4);
41 assert(base((*it).end()) == buffer + 6);
42
43 ++it;
44 assert(base((*it).begin()) == buffer + 7);
45 assert(base((*it).end()) == buffer + 8);
46 }
47
48 // it++
49 {
50 auto it = sv.begin();
51 auto original = it;
52
53 decltype(auto) it1 = it++;
54 static_assert(std::is_same_v<decltype(it1), SplitIter>);
55 assert(it1 == original);
56
57 assert(base((*it).begin()) == buffer + 4);
58 assert(base((*it).end()) == buffer + 6);
59
60 it++;
61 assert(base((*it).begin()) == buffer + 7);
62 assert(base((*it).end()) == buffer + 8);
63 }
64 }
65
66 // next's begin is the end
67 {
68 int buffer[] = {0, 1, 2};
69 auto input = make_subrange(buffer);
70 std::ranges::split_view sv(input, -1);
71 using SplitIter = std::ranges::iterator_t<decltype(sv)>;
72
73 // ++it
74 {
75 auto it = sv.begin();
76
77 decltype(auto) it1 = ++it; // trailing_empty is false
78 static_assert(std::is_same_v<decltype(it1), SplitIter&>);
79 assert(&it1 == &it);
80
81 assert(it == sv.end());
82 }
83
84 // it++
85 {
86 auto it = sv.begin();
87 auto original = it;
88
89 decltype(auto) it1 = it++; // trailing_empty is false
90 static_assert(std::is_same_v<decltype(it1), SplitIter>);
91 assert(it1 == original);
92
93 assert(it == sv.end());
94 }
95 }
96
97 // next's end is the end
98 {
99 int buffer[] = {0, 1, 2, -1};
100 auto input = make_subrange(buffer);
101 std::ranges::split_view sv(input, -1);
102 using SplitIter = std::ranges::iterator_t<decltype(sv)>;
103
104 // ++it
105 {
106 auto it = sv.begin();
107
108 decltype(auto) it1 = ++it; // trailing_empty is true
109 static_assert(std::is_same_v<decltype(it1), SplitIter&>);
110 assert(&it1 == &it);
111
112 assert(it != sv.end());
113 assert(base((*it).begin()) == buffer + 4);
114 assert(base((*it).begin()) == buffer + 4);
115
116 ++it;
117 assert(it == sv.end());
118 }
119
120 // it++
121 {
122 auto it = sv.begin();
123 auto original = it;
124
125 decltype(auto) it1 = it++; // trailing_empty is true
126 static_assert(std::is_same_v<decltype(it1), SplitIter>);
127 assert(it1 == original);
128
129 assert(it != sv.end());
130
131 assert(base((*it).begin()) == buffer + 4);
132 assert(base((*it).begin()) == buffer + 4);
133
134 it++;
135 assert(it == sv.end());
136 }
137 }
138}
139
140constexpr bool test() {
141 testOne<forward_iterator<int*>>();
142 testOne<bidirectional_iterator<int*>>();
143 testOne<random_access_iterator<int*>>();
144 testOne<contiguous_iterator<int*>>();
145 testOne<int*>();
146
147 return true;
148}
149
150int main(int, char**) {
151 test();
152 static_assert(test());
153
154 return 0;
155}
156

source code of libcxx/test/std/ranges/range.adaptors/range.split/iterator/increment.pass.cpp