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     static_assert( CountedInvocable<int*, size_t>);
52     static_assert(!CountedInvocable<int*, LvalueConvertible>);
53     static_assert( CountedInvocable<int*, LvalueConvertible&>);
54     static_assert( CountedInvocable<int*, RvalueConvertible>);
55     static_assert(!CountedInvocable<int*, RvalueConvertible&>);
56     static_assert(!CountedInvocable<int*, OnlyExplicitlyConvertible>);
57     static_assert(!CountedInvocable<int*, int*>);
58     static_assert(!CountedInvocable<int*>);
59     static_assert(!CountedInvocable<size_t>);
60     static_assert(!CountedInvocable<>);
61   }
62 
63   {
64     auto c1 = std::views::counted(buffer, 3);
65     auto c2 = std::views::counted(std::as_const(buffer), 3);
66 
67     ASSERT_SAME_TYPE(decltype(c1), std::span<int>);
68     ASSERT_SAME_TYPE(decltype(c2), std::span<const int>);
69 
70     assert(c1.data() == buffer && c1.size() == 3);
71     assert(c2.data() == buffer && c2.size() == 3);
72   }
73 
74   {
75     auto it = contiguous_iterator<int*>(buffer);
76     auto cit = contiguous_iterator<const int*>(buffer);
77 
78     auto c1 = std::views::counted(it, 3);
79     auto c2 = std::views::counted(std::as_const(it), 3);
80     auto c3 = std::views::counted(std::move(it), 3);
81     auto c4 = std::views::counted(contiguous_iterator<int*>(buffer), 3);
82     auto c5 = std::views::counted(cit, 3);
83     auto c6 = std::views::counted(std::as_const(cit), 3);
84     auto c7 = std::views::counted(std::move(cit), 3);
85     auto c8 = std::views::counted(contiguous_iterator<const int*>(buffer), 3);
86 
87     ASSERT_SAME_TYPE(decltype(c1), std::span<int>);
88     ASSERT_SAME_TYPE(decltype(c2), std::span<int>);
89     ASSERT_SAME_TYPE(decltype(c3), std::span<int>);
90     ASSERT_SAME_TYPE(decltype(c4), std::span<int>);
91     ASSERT_SAME_TYPE(decltype(c5), std::span<const int>);
92     ASSERT_SAME_TYPE(decltype(c6), std::span<const int>);
93     ASSERT_SAME_TYPE(decltype(c7), std::span<const int>);
94     ASSERT_SAME_TYPE(decltype(c8), std::span<const int>);
95 
96     assert(c1.data() == buffer && c1.size() == 3);
97     assert(c2.data() == buffer && c2.size() == 3);
98     assert(c3.data() == buffer && c3.size() == 3);
99     assert(c4.data() == buffer && c4.size() == 3);
100     assert(c5.data() == buffer && c5.size() == 3);
101     assert(c6.data() == buffer && c6.size() == 3);
102     assert(c7.data() == buffer && c7.size() == 3);
103     assert(c8.data() == buffer && c8.size() == 3);
104   }
105 
106   {
107     auto it = random_access_iterator<int*>(buffer);
108     auto cit = random_access_iterator<const int*>(buffer);
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), 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), 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 
142     auto c1 = std::views::counted(it, 3);
143     auto c2 = std::views::counted(std::as_const(it), 3);
144     auto c3 = std::views::counted(std::move(it), 3);
145     auto c4 = std::views::counted(bidirectional_iterator<int*>(buffer), 3);
146     auto c5 = std::views::counted(cit, 3);
147     auto c6 = std::views::counted(std::as_const(cit), 3);
148     auto c7 = std::views::counted(std::move(cit), 3);
149     auto c8 = std::views::counted(bidirectional_iterator<const int*>(buffer), 3);
150 
151     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
152     using ConstExpected = std::ranges::subrange<std::counted_iterator<decltype(cit)>, std::default_sentinel_t>;
153 
154     ASSERT_SAME_TYPE(decltype(c1), Expected);
155     ASSERT_SAME_TYPE(decltype(c2), Expected);
156     ASSERT_SAME_TYPE(decltype(c3), Expected);
157     ASSERT_SAME_TYPE(decltype(c4), Expected);
158     ASSERT_SAME_TYPE(decltype(c5), ConstExpected);
159     ASSERT_SAME_TYPE(decltype(c6), ConstExpected);
160     ASSERT_SAME_TYPE(decltype(c7), ConstExpected);
161     ASSERT_SAME_TYPE(decltype(c8), ConstExpected);
162 
163     assert(c1.begin().base() == it && c1.size() == 3);
164     assert(c2.begin().base() == it && c2.size() == 3);
165     assert(c3.begin().base() == it && c3.size() == 3);
166     assert(c4.begin().base() == it && c4.size() == 3);
167     assert(c5.begin().base() == cit && c5.size() == 3);
168     assert(c6.begin().base() == cit && c6.size() == 3);
169     assert(c7.begin().base() == cit && c7.size() == 3);
170     assert(c8.begin().base() == cit && c8.size() == 3);
171   }
172 
173   {
174     auto it = output_iterator<int*>(buffer);
175 
176     auto c1 = std::views::counted(it, 3);
177     auto c2 = std::views::counted(std::as_const(it), 3);
178     auto c3 = std::views::counted(std::move(it), 3);
179     auto c4 = std::views::counted(output_iterator<int*>(buffer), 3);
180 
181     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
182 
183     ASSERT_SAME_TYPE(decltype(c1), Expected);
184     ASSERT_SAME_TYPE(decltype(c2), Expected);
185     ASSERT_SAME_TYPE(decltype(c3), Expected);
186     ASSERT_SAME_TYPE(decltype(c4), Expected);
187 
188     assert(base(c1.begin().base()) == buffer && c1.size() == 3);
189     assert(base(c2.begin().base()) == buffer && c2.size() == 3);
190     assert(base(c3.begin().base()) == buffer && c3.size() == 3);
191     assert(base(c4.begin().base()) == buffer && c4.size() == 3);
192   }
193 
194   {
195     auto it = cpp17_input_iterator<int*>(buffer);
196 
197     auto c1 = std::views::counted(it, 3);
198     auto c2 = std::views::counted(std::as_const(it), 3);
199     auto c3 = std::views::counted(std::move(it), 3);
200     auto c4 = std::views::counted(cpp17_input_iterator<int*>(buffer), 3);
201 
202     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
203 
204     ASSERT_SAME_TYPE(decltype(c1), Expected);
205     ASSERT_SAME_TYPE(decltype(c2), Expected);
206     ASSERT_SAME_TYPE(decltype(c3), Expected);
207     ASSERT_SAME_TYPE(decltype(c4), Expected);
208 
209     assert(base(c1.begin().base()) == buffer && c1.size() == 3);
210     assert(base(c2.begin().base()) == buffer && c2.size() == 3);
211     assert(base(c3.begin().base()) == buffer && c3.size() == 3);
212     assert(base(c4.begin().base()) == buffer && c4.size() == 3);
213   }
214 
215   {
216     auto it = cpp20_input_iterator<int*>(buffer);
217 
218     static_assert(!std::copyable<cpp20_input_iterator<int*>>);
219     static_assert(!CountedInvocable<cpp20_input_iterator<int*>&, int>);
220     static_assert(!CountedInvocable<const cpp20_input_iterator<int*>&, int>);
221     auto c3 = std::views::counted(std::move(it), 3);
222     auto c4 = std::views::counted(cpp20_input_iterator<int*>(buffer), 3);
223 
224     using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>;
225 
226     ASSERT_SAME_TYPE(decltype(c3), Expected);
227     ASSERT_SAME_TYPE(decltype(c4), Expected);
228 
229     assert(base(c3.begin().base()) == buffer && c3.size() == 3);
230     assert(base(c4.begin().base()) == buffer && c4.size() == 3);
231   }
232 
233   return true;
234 }
235 
236 int main(int, char**) {
237   test();
238   static_assert(test());
239 
240   return 0;
241 }
242