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