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 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11
12 // constexpr inner-iterator& inner-iterator::operator++();
13 //
14 // constexpr decltype(auto) inner-iterator::operator++(int);
15
16 #include <ranges>
17
18 #include <cassert>
19 #include <type_traits>
20 #include "test_macros.h"
21 #include "../types.h"
22
23 struct EmptyView : std::ranges::view_base {
beginEmptyView24 constexpr int* begin() const { return nullptr; }
endEmptyView25 constexpr int* end() const { return nullptr; }
sizeEmptyView26 constexpr static size_t size() { return 0; }
27 };
28 static_assert(std::ranges::forward_range<EmptyView>);
29 static_assert(std::ranges::view<EmptyView>);
30 LIBCPP_STATIC_ASSERT(std::ranges::__tiny_range<EmptyView>);
31
test()32 constexpr bool test() {
33 // Can call `inner-iterator::operator++`; `View` is a forward range.
34 {
35 SplitViewForward v("abc def", " ");
36 auto val = *v.begin();
37
38 // ++i
39 {
40 auto i = val.begin();
41 assert(*i == 'a');
42
43 decltype(auto) i2 = ++i;
44 static_assert(std::is_lvalue_reference_v<decltype(i2)>);
45 assert(&i2 == &i);
46 assert(*i2 == 'b');
47 }
48
49 // i++
50 {
51 auto i = val.begin();
52 assert(*i == 'a');
53
54 decltype(auto) i2 = i++;
55 static_assert(!std::is_reference_v<decltype(i2)>);
56 assert(*i2 == 'a');
57 assert(*i == 'b');
58 }
59 }
60
61 // Can call `inner-iterator::operator++`; `View` is an input range.
62 {
63 // ++i
64 {
65 SplitViewInput v("abc def", ' ');
66 auto val = *v.begin();
67
68 auto i = val.begin();
69 assert(*i == 'a');
70
71 decltype(auto) i2 = ++i;
72 static_assert(std::is_lvalue_reference_v<decltype(i2)>);
73 assert(&i2 == &i);
74 assert(*i2 == 'b');
75 }
76
77 // i++
78 {
79 SplitViewInput v("abc def", ' ');
80 auto val = *v.begin();
81
82 auto i = val.begin();
83 assert(*i == 'a');
84
85 static_assert(std::is_void_v<decltype(i++)>);
86 i++;
87 assert(*i == 'b');
88 }
89 }
90
91 // Can call `inner-iterator::operator++`; `View` is an input range and `Pattern` is an "empty" range.
92 {
93 // ++i
94 {
95 std::ranges::lazy_split_view<InputView, EmptyView> v("a", EmptyView());
96 auto val = *v.begin();
97
98 auto i = val.begin();
99 assert(*i.base() == 'a');
100 assert(i != std::default_sentinel);
101
102 // The iterator doesn't move to the next character but is considered to point to the end.
103 decltype(auto) i2 = ++i;
104 assert(&i2 == &i);
105 assert(*i2.base() == 'a');
106 assert(i2 == std::default_sentinel);
107 }
108
109 // i++
110 {
111 std::ranges::lazy_split_view<InputView, EmptyView> v("a", EmptyView());
112 auto val = *v.begin();
113
114 auto i = val.begin();
115 assert(*i.base() == 'a');
116 assert(i != std::default_sentinel);
117
118 // The iterator doesn't move to the next character but is considered to point to the end.
119 i++;
120 assert(*i.base() == 'a');
121 assert(i == std::default_sentinel);
122 }
123 }
124
125 return true;
126 }
127
main(int,char **)128 int main(int, char**) {
129 test();
130 static_assert(test());
131
132 return 0;
133 }
134