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-no-concepts
11 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
12 
13 // std::views::counted;
14 
15 #include <ranges>
16 #include <cassert>
17 #include <concepts>
18 #include <cstddef>
19 #include <memory>
20 #include <span>
21 #include <utility>
22 
23 #include "test_macros.h"
24 #include "test_iterators.h"
25 
26 struct RvalueConvertible {
27   RvalueConvertible(const RvalueConvertible&) = delete;
28   operator int() &&;
29 };
30 
31 struct LvalueConvertible {
32   LvalueConvertible(const LvalueConvertible&) = delete;
33   operator int() &;
34 };
35 
36 struct OnlyExplicitlyConvertible {
37   explicit operator int() const;
38 };
39 
40 template<class... Ts>
41 concept CountedInvocable = requires (Ts&&... ts) {
42   std::views::counted(std::forward<Ts>(ts)...);
43 };
44 
45 constexpr bool test() {
46   int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
47 
48   {
49     static_assert(std::addressof(std::views::counted) == std::addressof(std::ranges::views::counted));
50 
51     auto copy = std::views::counted;
52     static_assert(std::semiregular<decltype(copy)>);
53 
54     static_assert( CountedInvocable<int*, size_t>);
55     static_assert(!CountedInvocable<int*, LvalueConvertible>);
56     static_assert( CountedInvocable<int*, LvalueConvertible&>);
57     static_assert( CountedInvocable<int*, RvalueConvertible>);
58     static_assert(!CountedInvocable<int*, RvalueConvertible&>);
59     static_assert(!CountedInvocable<int*, OnlyExplicitlyConvertible>);
60     static_assert(!CountedInvocable<int*, int*>);
61     static_assert(!CountedInvocable<int*>);
62     static_assert(!CountedInvocable<size_t>);
63     static_assert(!CountedInvocable<>);
64   }
65 
66   {
67     auto c1 = std::views::counted(buffer, 3);
68     auto c2 = std::views::counted(std::as_const(buffer), 3);
69 
70     ASSERT_SAME_TYPE(decltype(c1), std::span<int>);
71     ASSERT_SAME_TYPE(decltype(c2), std::span<const int>);
72 
73     assert(c1.data() == buffer && c1.size() == 3);
74     assert(c2.data() == buffer && c2.size() == 3);
75   }
76 
77   {
78     auto it = contiguous_iterator<int*>(buffer);
79     auto cit = contiguous_iterator<const int*>(buffer);
80 
81     auto c1 = std::views::counted(it, 3);
82     auto c2 = std::views::counted(std::as_const(it), 3);
83     auto c3 = std::views::counted(std::move(it), 3);
84     auto c4 = std::views::counted(contiguous_iterator<int*>(buffer), 3);
85     auto c5 = std::views::counted(cit, 3);
86     auto c6 = std::views::counted(std::as_const(cit), 3);
87     auto c7 = std::views::counted(std::move(cit), 3);
88     auto c8 = std::views::counted(contiguous_iterator<const int*>(buffer), 3);
89 
90     ASSERT_SAME_TYPE(decltype(c1), std::span<int>);
91     ASSERT_SAME_TYPE(decltype(c2), std::span<int>);
92     ASSERT_SAME_TYPE(decltype(c3), std::span<int>);
93     ASSERT_SAME_TYPE(decltype(c4), std::span<int>);
94     ASSERT_SAME_TYPE(decltype(c5), std::span<const int>);
95     ASSERT_SAME_TYPE(decltype(c6), std::span<const int>);
96     ASSERT_SAME_TYPE(decltype(c7), std::span<const int>);
97     ASSERT_SAME_TYPE(decltype(c8), std::span<const int>);
98 
99     assert(c1.data() == buffer && c1.size() == 3);
100     assert(c2.data() == buffer && c2.size() == 3);
101     assert(c3.data() == buffer && c3.size() == 3);
102     assert(c4.data() == buffer && c4.size() == 3);
103     assert(c5.data() == buffer && c5.size() == 3);
104     assert(c6.data() == buffer && c6.size() == 3);
105     assert(c7.data() == buffer && c7.size() == 3);
106     assert(c8.data() == buffer && c8.size() == 3);
107   }
108 
109   {
110     auto it = random_access_iterator<int*>(buffer);
111     auto cit = random_access_iterator<const int*>(buffer);
112 
113     auto c1 = std::views::counted(it, 3);
114     auto c2 = std::views::counted(std::as_const(it), 3);
115     auto c3 = std::views::counted(std::move(it), 3);
116     auto c4 = std::views::counted(random_access_iterator<int*>(buffer), 3);
117     auto c5 = std::views::counted(cit, 3);
118     auto c6 = std::views::counted(std::as_const(cit), 3);
119     auto c7 = std::views::counted(std::move(cit), 3);
120     auto c8 = std::views::counted(random_access_iterator<const int*>(buffer), 3);
121 
122     ASSERT_SAME_TYPE(decltype(c1), std::ranges::subrange<random_access_iterator<int*>>);
123     ASSERT_SAME_TYPE(decltype(c2), std::ranges::subrange<random_access_iterator<int*>>);
124     ASSERT_SAME_TYPE(decltype(c3), std::ranges::subrange<random_access_iterator<int*>>);
125     ASSERT_SAME_TYPE(decltype(c4), std::ranges::subrange<random_access_iterator<int*>>);
126     ASSERT_SAME_TYPE(decltype(c5), std::ranges::subrange<random_access_iterator<const int*>>);
127     ASSERT_SAME_TYPE(decltype(c6), std::ranges::subrange<random_access_iterator<const int*>>);
128     ASSERT_SAME_TYPE(decltype(c7), std::ranges::subrange<random_access_iterator<const int*>>);
129     ASSERT_SAME_TYPE(decltype(c8), std::ranges::subrange<random_access_iterator<const int*>>);
130 
131     assert(c1.begin() == it && c1.end() == it + 3);
132     assert(c2.begin() == it && c2.end() == it + 3);
133     assert(c3.begin() == it && c3.end() == it + 3);
134     assert(c4.begin() == it && c4.end() == it + 3);
135     assert(c5.begin() == cit && c5.end() == cit + 3);
136     assert(c6.begin() == cit && c6.end() == cit + 3);
137     assert(c7.begin() == cit && c7.end() == cit + 3);
138     assert(c8.begin() == cit && c8.end() == cit + 3);
139   }
140 
141   {
142     auto it = bidirectional_iterator<int*>(buffer);
143     auto cit = bidirectional_iterator<const int*>(buffer);
144 
145     auto c1 = std::views::counted(it, 3);
146     auto c2 = std::views::counted(std::as_const(it), 3);
147     auto c3 = std::views::counted(std::move(it), 3);
148     auto c4 = std::views::counted(bidirectional_iterator<int*>(buffer), 3);
149     auto c5 = std::views::counted(cit, 3);
150     auto c6 = std::views::counted(std::as_const(cit), 3);
151     auto c7 = std::views::counted(std::move(cit), 3);
152     auto c8 = std::views::counted(bidirectional_iterator<const int*>(buffer), 3);
153 
154     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
155     using ConstExpected = std::ranges::subrange<std::counted_iterator<decltype(cit)>, std::default_sentinel_t>;
156 
157     ASSERT_SAME_TYPE(decltype(c1), Expected);
158     ASSERT_SAME_TYPE(decltype(c2), Expected);
159     ASSERT_SAME_TYPE(decltype(c3), Expected);
160     ASSERT_SAME_TYPE(decltype(c4), Expected);
161     ASSERT_SAME_TYPE(decltype(c5), ConstExpected);
162     ASSERT_SAME_TYPE(decltype(c6), ConstExpected);
163     ASSERT_SAME_TYPE(decltype(c7), ConstExpected);
164     ASSERT_SAME_TYPE(decltype(c8), ConstExpected);
165 
166     assert(c1.begin().base() == it && c1.size() == 3);
167     assert(c2.begin().base() == it && c2.size() == 3);
168     assert(c3.begin().base() == it && c3.size() == 3);
169     assert(c4.begin().base() == it && c4.size() == 3);
170     assert(c5.begin().base() == cit && c5.size() == 3);
171     assert(c6.begin().base() == cit && c6.size() == 3);
172     assert(c7.begin().base() == cit && c7.size() == 3);
173     assert(c8.begin().base() == cit && c8.size() == 3);
174   }
175 
176   {
177     auto it = output_iterator<int*>(buffer);
178 
179     auto c1 = std::views::counted(it, 3);
180     auto c2 = std::views::counted(std::as_const(it), 3);
181     auto c3 = std::views::counted(std::move(it), 3);
182     auto c4 = std::views::counted(output_iterator<int*>(buffer), 3);
183 
184     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
185 
186     ASSERT_SAME_TYPE(decltype(c1), Expected);
187     ASSERT_SAME_TYPE(decltype(c2), Expected);
188     ASSERT_SAME_TYPE(decltype(c3), Expected);
189     ASSERT_SAME_TYPE(decltype(c4), Expected);
190 
191     assert(base(c1.begin().base()) == buffer && c1.size() == 3);
192     assert(base(c2.begin().base()) == buffer && c2.size() == 3);
193     assert(base(c3.begin().base()) == buffer && c3.size() == 3);
194     assert(base(c4.begin().base()) == buffer && c4.size() == 3);
195   }
196 
197   {
198     auto it = cpp17_input_iterator<int*>(buffer);
199 
200     auto c1 = std::views::counted(it, 3);
201     auto c2 = std::views::counted(std::as_const(it), 3);
202     auto c3 = std::views::counted(std::move(it), 3);
203     auto c4 = std::views::counted(cpp17_input_iterator<int*>(buffer), 3);
204 
205     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
206 
207     ASSERT_SAME_TYPE(decltype(c1), Expected);
208     ASSERT_SAME_TYPE(decltype(c2), Expected);
209     ASSERT_SAME_TYPE(decltype(c3), Expected);
210     ASSERT_SAME_TYPE(decltype(c4), Expected);
211 
212     assert(base(c1.begin().base()) == buffer && c1.size() == 3);
213     assert(base(c2.begin().base()) == buffer && c2.size() == 3);
214     assert(base(c3.begin().base()) == buffer && c3.size() == 3);
215     assert(base(c4.begin().base()) == buffer && c4.size() == 3);
216   }
217 
218   {
219     auto it = cpp20_input_iterator<int*>(buffer);
220 
221     static_assert(!std::copyable<cpp20_input_iterator<int*>>);
222     static_assert(!CountedInvocable<cpp20_input_iterator<int*>&, int>);
223     static_assert(!CountedInvocable<const cpp20_input_iterator<int*>&, int>);
224     auto c3 = std::views::counted(std::move(it), 3);
225     auto c4 = std::views::counted(cpp20_input_iterator<int*>(buffer), 3);
226 
227     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
228 
229     ASSERT_SAME_TYPE(decltype(c3), Expected);
230     ASSERT_SAME_TYPE(decltype(c4), Expected);
231 
232     assert(base(c3.begin().base()) == buffer && c3.size() == 3);
233     assert(base(c4.begin().base()) == buffer && c4.size() == 3);
234   }
235 
236   return true;
237 }
238 
239 int main(int, char**) {
240   test();
241   static_assert(test());
242 
243   return 0;
244 }
245