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