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