1*042dc3c4SHui Xie //===----------------------------------------------------------------------===//
2*042dc3c4SHui Xie //
3*042dc3c4SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*042dc3c4SHui Xie // See https://llvm.org/LICENSE.txt for license information.
5*042dc3c4SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*042dc3c4SHui Xie //
7*042dc3c4SHui Xie //===----------------------------------------------------------------------===//
8*042dc3c4SHui Xie
9*042dc3c4SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10*042dc3c4SHui Xie
11*042dc3c4SHui Xie // constexpr iterator& operator++();
12*042dc3c4SHui Xie // constexpr void operator++(int);
13*042dc3c4SHui Xie // constexpr iterator operator++(int) requires all_forward<Const, Views...>;
14*042dc3c4SHui Xie
15*042dc3c4SHui Xie #include <array>
16*042dc3c4SHui Xie #include <cassert>
17*042dc3c4SHui Xie #include <ranges>
18*042dc3c4SHui Xie #include <tuple>
19*042dc3c4SHui Xie
20*042dc3c4SHui Xie #include "../types.h"
21*042dc3c4SHui Xie
22*042dc3c4SHui Xie struct InputRange : IntBufferView {
23*042dc3c4SHui Xie using IntBufferView::IntBufferView;
24*042dc3c4SHui Xie using iterator = cpp20_input_iterator<int*>;
beginInputRange25*042dc3c4SHui Xie constexpr iterator begin() const { return iterator(buffer_); }
endInputRange26*042dc3c4SHui Xie constexpr sentinel_wrapper<iterator> end() const { return sentinel_wrapper<iterator>(iterator(buffer_ + size_)); }
27*042dc3c4SHui Xie };
28*042dc3c4SHui Xie
test()29*042dc3c4SHui Xie constexpr bool test() {
30*042dc3c4SHui Xie std::array a{1, 2, 3, 4};
31*042dc3c4SHui Xie std::array b{4.1, 3.2, 4.3};
32*042dc3c4SHui Xie {
33*042dc3c4SHui Xie // random/contiguous
34*042dc3c4SHui Xie std::ranges::zip_view v(a, b, std::views::iota(0, 5));
35*042dc3c4SHui Xie auto it = v.begin();
36*042dc3c4SHui Xie using Iter = decltype(it);
37*042dc3c4SHui Xie
38*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(a[0]));
39*042dc3c4SHui Xie assert(&(std::get<1>(*it)) == &(b[0]));
40*042dc3c4SHui Xie assert(std::get<2>(*it) == 0);
41*042dc3c4SHui Xie
42*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(++it), Iter&>);
43*042dc3c4SHui Xie
44*042dc3c4SHui Xie auto& it_ref = ++it;
45*042dc3c4SHui Xie assert(&it_ref == &it);
46*042dc3c4SHui Xie
47*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(a[1]));
48*042dc3c4SHui Xie assert(&(std::get<1>(*it)) == &(b[1]));
49*042dc3c4SHui Xie assert(std::get<2>(*it) == 1);
50*042dc3c4SHui Xie
51*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(it++), Iter>);
52*042dc3c4SHui Xie auto original = it;
53*042dc3c4SHui Xie auto copy = it++;
54*042dc3c4SHui Xie assert(original == copy);
55*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(a[2]));
56*042dc3c4SHui Xie assert(&(std::get<1>(*it)) == &(b[2]));
57*042dc3c4SHui Xie assert(std::get<2>(*it) == 2);
58*042dc3c4SHui Xie }
59*042dc3c4SHui Xie
60*042dc3c4SHui Xie {
61*042dc3c4SHui Xie // bidi
62*042dc3c4SHui Xie int buffer[2] = {1, 2};
63*042dc3c4SHui Xie
64*042dc3c4SHui Xie std::ranges::zip_view v(BidiCommonView{buffer});
65*042dc3c4SHui Xie auto it = v.begin();
66*042dc3c4SHui Xie using Iter = decltype(it);
67*042dc3c4SHui Xie
68*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(buffer[0]));
69*042dc3c4SHui Xie
70*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(++it), Iter&>);
71*042dc3c4SHui Xie auto& it_ref = ++it;
72*042dc3c4SHui Xie assert(&it_ref == &it);
73*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(buffer[1]));
74*042dc3c4SHui Xie
75*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(it++), Iter>);
76*042dc3c4SHui Xie auto original = it;
77*042dc3c4SHui Xie auto copy = it++;
78*042dc3c4SHui Xie assert(copy == original);
79*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(buffer[2]));
80*042dc3c4SHui Xie }
81*042dc3c4SHui Xie
82*042dc3c4SHui Xie {
83*042dc3c4SHui Xie // forward
84*042dc3c4SHui Xie int buffer[2] = {1, 2};
85*042dc3c4SHui Xie
86*042dc3c4SHui Xie std::ranges::zip_view v(ForwardSizedView{buffer});
87*042dc3c4SHui Xie auto it = v.begin();
88*042dc3c4SHui Xie using Iter = decltype(it);
89*042dc3c4SHui Xie
90*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(buffer[0]));
91*042dc3c4SHui Xie
92*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(++it), Iter&>);
93*042dc3c4SHui Xie auto& it_ref = ++it;
94*042dc3c4SHui Xie assert(&it_ref == &it);
95*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(buffer[1]));
96*042dc3c4SHui Xie
97*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(it++), Iter>);
98*042dc3c4SHui Xie auto original = it;
99*042dc3c4SHui Xie auto copy = it++;
100*042dc3c4SHui Xie assert(copy == original);
101*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(buffer[2]));
102*042dc3c4SHui Xie }
103*042dc3c4SHui Xie
104*042dc3c4SHui Xie {
105*042dc3c4SHui Xie // all input+
106*042dc3c4SHui Xie int buffer[3] = {4, 5, 6};
107*042dc3c4SHui Xie std::ranges::zip_view v(a, InputRange{buffer});
108*042dc3c4SHui Xie auto it = v.begin();
109*042dc3c4SHui Xie using Iter = decltype(it);
110*042dc3c4SHui Xie
111*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(a[0]));
112*042dc3c4SHui Xie assert(&(std::get<1>(*it)) == &(buffer[0]));
113*042dc3c4SHui Xie
114*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(++it), Iter&>);
115*042dc3c4SHui Xie auto& it_ref = ++it;
116*042dc3c4SHui Xie assert(&it_ref == &it);
117*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(a[1]));
118*042dc3c4SHui Xie assert(&(std::get<1>(*it)) == &(buffer[1]));
119*042dc3c4SHui Xie
120*042dc3c4SHui Xie static_assert(std::is_same_v<decltype(it++), void>);
121*042dc3c4SHui Xie it++;
122*042dc3c4SHui Xie assert(&(std::get<0>(*it)) == &(a[2]));
123*042dc3c4SHui Xie assert(&(std::get<1>(*it)) == &(buffer[2]));
124*042dc3c4SHui Xie }
125*042dc3c4SHui Xie
126*042dc3c4SHui Xie return true;
127*042dc3c4SHui Xie }
128*042dc3c4SHui Xie
main(int,char **)129*042dc3c4SHui Xie int main(int, char**) {
130*042dc3c4SHui Xie test();
131*042dc3c4SHui Xie static_assert(test());
132*042dc3c4SHui Xie
133*042dc3c4SHui Xie return 0;
134*042dc3c4SHui Xie }
135