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 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
9 | |
10 | // <span> |
11 | |
12 | // constexpr span& operator=(const span& other) noexcept = default; |
13 | |
14 | #include <span> |
15 | #include <cassert> |
16 | #include <iterator> |
17 | #include <string> |
18 | #include <utility> |
19 | |
20 | #include "test_macros.h" |
21 | |
22 | template <typename T> |
23 | constexpr bool doAssign(T lhs, T rhs) |
24 | { |
25 | ASSERT_NOEXCEPT(std::declval<T&>() = rhs); |
26 | lhs = rhs; |
27 | return lhs.data() == rhs.data() |
28 | && lhs.size() == rhs.size(); |
29 | } |
30 | |
31 | struct A{}; |
32 | |
33 | constexpr int carr1[] = {1,2,3,4}; |
34 | constexpr int carr2[] = {3,4,5}; |
35 | constexpr int carr3[] = {7,8}; |
36 | int arr[] = {5,6,7,9}; |
37 | std::string strs[] = {"ABC" , "DEF" , "GHI" }; |
38 | |
39 | |
40 | int main(int, char**) |
41 | { |
42 | |
43 | // constexpr dynamically sized assignment |
44 | { |
45 | // On systems where 'ptrdiff_t' is a synonym for 'int', |
46 | // the call span(ptr, 0) selects the (pointer, size_type) constructor. |
47 | // On systems where 'ptrdiff_t' is NOT a synonym for 'int', |
48 | // it is ambiguous, because of 0 also being convertible to a null pointer |
49 | // and so the compiler can't choose between: |
50 | // span(pointer, size_type) |
51 | // and span(pointer, pointer) |
52 | // We cast zero to std::ptrdiff_t to remove that ambiguity. |
53 | // Example: |
54 | // On darwin x86_64, ptrdiff_t is the same as long int. |
55 | // On darwin i386, ptrdiff_t is the same as int. |
56 | constexpr std::span<const int> spans[] = { |
57 | {}, |
58 | {carr1, static_cast<std::size_t>(0)}, |
59 | {carr1, 1U}, |
60 | {carr1, 2U}, |
61 | {carr1, 3U}, |
62 | {carr1, 4U}, |
63 | {carr2, static_cast<std::size_t>(0)}, |
64 | {carr2, 1U}, |
65 | {carr2, 2U}, |
66 | {carr2, 3U}, |
67 | {carr3, static_cast<std::size_t>(0)}, |
68 | {carr3, 1U}, |
69 | {carr3, 2U} |
70 | }; |
71 | |
72 | static_assert(std::size(spans) == 13, "" ); |
73 | |
74 | // No for loops in constexpr land :-( |
75 | static_assert(doAssign(spans[0], spans[0]), "" ); |
76 | static_assert(doAssign(spans[0], spans[1]), "" ); |
77 | static_assert(doAssign(spans[0], spans[2]), "" ); |
78 | static_assert(doAssign(spans[0], spans[3]), "" ); |
79 | static_assert(doAssign(spans[0], spans[4]), "" ); |
80 | static_assert(doAssign(spans[0], spans[5]), "" ); |
81 | static_assert(doAssign(spans[0], spans[6]), "" ); |
82 | static_assert(doAssign(spans[0], spans[7]), "" ); |
83 | static_assert(doAssign(spans[0], spans[8]), "" ); |
84 | static_assert(doAssign(spans[0], spans[9]), "" ); |
85 | static_assert(doAssign(spans[0], spans[10]), "" ); |
86 | static_assert(doAssign(spans[0], spans[11]), "" ); |
87 | static_assert(doAssign(spans[0], spans[12]), "" ); |
88 | |
89 | static_assert(doAssign(spans[1], spans[1]), "" ); |
90 | static_assert(doAssign(spans[1], spans[2]), "" ); |
91 | static_assert(doAssign(spans[1], spans[3]), "" ); |
92 | static_assert(doAssign(spans[1], spans[4]), "" ); |
93 | static_assert(doAssign(spans[1], spans[5]), "" ); |
94 | static_assert(doAssign(spans[1], spans[6]), "" ); |
95 | static_assert(doAssign(spans[1], spans[7]), "" ); |
96 | static_assert(doAssign(spans[1], spans[8]), "" ); |
97 | static_assert(doAssign(spans[1], spans[9]), "" ); |
98 | static_assert(doAssign(spans[1], spans[10]), "" ); |
99 | static_assert(doAssign(spans[1], spans[11]), "" ); |
100 | static_assert(doAssign(spans[1], spans[12]), "" ); |
101 | |
102 | static_assert(doAssign(spans[2], spans[2]), "" ); |
103 | static_assert(doAssign(spans[2], spans[3]), "" ); |
104 | static_assert(doAssign(spans[2], spans[4]), "" ); |
105 | static_assert(doAssign(spans[2], spans[5]), "" ); |
106 | static_assert(doAssign(spans[2], spans[6]), "" ); |
107 | static_assert(doAssign(spans[2], spans[7]), "" ); |
108 | static_assert(doAssign(spans[2], spans[8]), "" ); |
109 | static_assert(doAssign(spans[2], spans[9]), "" ); |
110 | static_assert(doAssign(spans[2], spans[10]), "" ); |
111 | static_assert(doAssign(spans[2], spans[11]), "" ); |
112 | static_assert(doAssign(spans[2], spans[12]), "" ); |
113 | |
114 | static_assert(doAssign(spans[3], spans[3]), "" ); |
115 | static_assert(doAssign(spans[3], spans[4]), "" ); |
116 | static_assert(doAssign(spans[3], spans[4]), "" ); |
117 | static_assert(doAssign(spans[3], spans[4]), "" ); |
118 | static_assert(doAssign(spans[3], spans[4]), "" ); |
119 | static_assert(doAssign(spans[3], spans[4]), "" ); |
120 | static_assert(doAssign(spans[3], spans[4]), "" ); |
121 | static_assert(doAssign(spans[3], spans[4]), "" ); |
122 | static_assert(doAssign(spans[3], spans[4]), "" ); |
123 | static_assert(doAssign(spans[3], spans[10]), "" ); |
124 | static_assert(doAssign(spans[3], spans[11]), "" ); |
125 | static_assert(doAssign(spans[3], spans[12]), "" ); |
126 | |
127 | static_assert(doAssign(spans[4], spans[4]), "" ); |
128 | static_assert(doAssign(spans[4], spans[5]), "" ); |
129 | static_assert(doAssign(spans[4], spans[6]), "" ); |
130 | static_assert(doAssign(spans[4], spans[7]), "" ); |
131 | static_assert(doAssign(spans[4], spans[8]), "" ); |
132 | static_assert(doAssign(spans[4], spans[9]), "" ); |
133 | static_assert(doAssign(spans[4], spans[10]), "" ); |
134 | static_assert(doAssign(spans[4], spans[11]), "" ); |
135 | static_assert(doAssign(spans[4], spans[12]), "" ); |
136 | |
137 | static_assert(doAssign(spans[5], spans[5]), "" ); |
138 | static_assert(doAssign(spans[5], spans[6]), "" ); |
139 | static_assert(doAssign(spans[5], spans[7]), "" ); |
140 | static_assert(doAssign(spans[5], spans[8]), "" ); |
141 | static_assert(doAssign(spans[5], spans[9]), "" ); |
142 | static_assert(doAssign(spans[5], spans[10]), "" ); |
143 | static_assert(doAssign(spans[5], spans[11]), "" ); |
144 | static_assert(doAssign(spans[5], spans[12]), "" ); |
145 | |
146 | static_assert(doAssign(spans[6], spans[6]), "" ); |
147 | static_assert(doAssign(spans[6], spans[7]), "" ); |
148 | static_assert(doAssign(spans[6], spans[8]), "" ); |
149 | static_assert(doAssign(spans[6], spans[9]), "" ); |
150 | static_assert(doAssign(spans[6], spans[10]), "" ); |
151 | static_assert(doAssign(spans[6], spans[11]), "" ); |
152 | static_assert(doAssign(spans[6], spans[12]), "" ); |
153 | |
154 | static_assert(doAssign(spans[7], spans[7]), "" ); |
155 | static_assert(doAssign(spans[7], spans[8]), "" ); |
156 | static_assert(doAssign(spans[7], spans[9]), "" ); |
157 | static_assert(doAssign(spans[7], spans[10]), "" ); |
158 | static_assert(doAssign(spans[7], spans[11]), "" ); |
159 | static_assert(doAssign(spans[7], spans[12]), "" ); |
160 | |
161 | static_assert(doAssign(spans[8], spans[8]), "" ); |
162 | static_assert(doAssign(spans[8], spans[9]), "" ); |
163 | static_assert(doAssign(spans[8], spans[10]), "" ); |
164 | static_assert(doAssign(spans[8], spans[11]), "" ); |
165 | static_assert(doAssign(spans[8], spans[12]), "" ); |
166 | |
167 | static_assert(doAssign(spans[9], spans[9]), "" ); |
168 | static_assert(doAssign(spans[9], spans[10]), "" ); |
169 | static_assert(doAssign(spans[9], spans[11]), "" ); |
170 | static_assert(doAssign(spans[9], spans[12]), "" ); |
171 | |
172 | static_assert(doAssign(spans[10], spans[10]), "" ); |
173 | static_assert(doAssign(spans[10], spans[11]), "" ); |
174 | static_assert(doAssign(spans[10], spans[12]), "" ); |
175 | |
176 | static_assert(doAssign(spans[11], spans[11]), "" ); |
177 | static_assert(doAssign(spans[11], spans[12]), "" ); |
178 | |
179 | static_assert(doAssign(spans[12], spans[12]), "" ); |
180 | |
181 | // for (size_t i = 0; i < std::size(spans); ++i) |
182 | // for (size_t j = i; j < std::size(spans); ++j) |
183 | // static_assert(doAssign(spans[i], spans[j]), ""); |
184 | } |
185 | |
186 | // constexpr statically sized assignment |
187 | { |
188 | using spanType = std::span<const int,2>; |
189 | constexpr spanType spans[] = { |
190 | spanType{carr1, 2}, |
191 | spanType{carr1 + 1, 2}, |
192 | spanType{carr1 + 2, 2}, |
193 | spanType{carr2, 2}, |
194 | spanType{carr2 + 1, 2}, |
195 | spanType{carr3, 2} |
196 | }; |
197 | |
198 | static_assert(std::size(spans) == 6, "" ); |
199 | |
200 | // No for loops in constexpr land :-( |
201 | static_assert(doAssign(spans[0], spans[0]), "" ); |
202 | static_assert(doAssign(spans[0], spans[1]), "" ); |
203 | static_assert(doAssign(spans[0], spans[2]), "" ); |
204 | static_assert(doAssign(spans[0], spans[3]), "" ); |
205 | static_assert(doAssign(spans[0], spans[4]), "" ); |
206 | static_assert(doAssign(spans[0], spans[5]), "" ); |
207 | |
208 | static_assert(doAssign(spans[1], spans[1]), "" ); |
209 | static_assert(doAssign(spans[1], spans[2]), "" ); |
210 | static_assert(doAssign(spans[1], spans[3]), "" ); |
211 | static_assert(doAssign(spans[1], spans[4]), "" ); |
212 | static_assert(doAssign(spans[1], spans[5]), "" ); |
213 | |
214 | static_assert(doAssign(spans[2], spans[2]), "" ); |
215 | static_assert(doAssign(spans[2], spans[3]), "" ); |
216 | static_assert(doAssign(spans[2], spans[4]), "" ); |
217 | static_assert(doAssign(spans[2], spans[5]), "" ); |
218 | |
219 | static_assert(doAssign(spans[3], spans[3]), "" ); |
220 | static_assert(doAssign(spans[3], spans[4]), "" ); |
221 | static_assert(doAssign(spans[3], spans[5]), "" ); |
222 | |
223 | static_assert(doAssign(spans[4], spans[4]), "" ); |
224 | static_assert(doAssign(spans[4], spans[5]), "" ); |
225 | |
226 | static_assert(doAssign(spans[5], spans[5]), "" ); |
227 | |
228 | // for (size_t i = 0; i < std::size(spans); ++i) |
229 | // for (size_t j = i; j < std::size(spans); ++j) |
230 | // static_assert(doAssign(spans[i], spans[j]), ""); |
231 | } |
232 | |
233 | |
234 | // dynamically sized assignment |
235 | { |
236 | std::span<int> spans[] = { |
237 | {}, |
238 | {arr, arr + 1}, |
239 | {arr, arr + 2}, |
240 | {arr, arr + 3}, |
241 | {arr + 1, arr + 3} // same size as s2 |
242 | }; |
243 | |
244 | for (std::size_t i = 0; i < std::size(spans); ++i) |
245 | for (std::size_t j = i; j < std::size(spans); ++j) |
246 | assert((doAssign(spans[i], spans[j]))); |
247 | } |
248 | |
249 | // statically sized assignment |
250 | { |
251 | using spanType = std::span<int,2>; |
252 | spanType spans[] = { |
253 | spanType{arr, arr + 2}, |
254 | spanType{arr + 1, arr + 3}, |
255 | spanType{arr + 2, arr + 4} |
256 | }; |
257 | |
258 | for (std::size_t i = 0; i < std::size(spans); ++i) |
259 | for (std::size_t j = i; j < std::size(spans); ++j) |
260 | assert((doAssign(spans[i], spans[j]))); |
261 | } |
262 | |
263 | // dynamically sized assignment |
264 | { |
265 | std::span<std::string> spans[] = { |
266 | {strs, strs}, |
267 | {strs, strs + 1}, |
268 | {strs, strs + 2}, |
269 | {strs, strs + 3}, |
270 | {strs + 1, strs + 1}, |
271 | {strs + 1, strs + 2}, |
272 | {strs + 1, strs + 3}, |
273 | {strs + 2, strs + 2}, |
274 | {strs + 2, strs + 3}, |
275 | {strs + 3, strs + 3} |
276 | }; |
277 | |
278 | for (std::size_t i = 0; i < std::size(spans); ++i) |
279 | for (std::size_t j = i; j < std::size(spans); ++j) |
280 | assert((doAssign(spans[i], spans[j]))); |
281 | } |
282 | |
283 | { |
284 | using spanType = std::span<std::string, 1>; |
285 | spanType spans[] = { |
286 | spanType{strs, strs + 1}, |
287 | spanType{strs + 1, strs + 2}, |
288 | spanType{strs + 2, strs + 3} |
289 | }; |
290 | |
291 | for (std::size_t i = 0; i < std::size(spans); ++i) |
292 | for (std::size_t j = i; j < std::size(spans); ++j) |
293 | assert((doAssign(spans[i], spans[j]))); |
294 | } |
295 | |
296 | return 0; |
297 | } |
298 | |