1 // -*- C++ -*-
2 //===------------------------------ span ---------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===---------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10
11 // <span>
12
13 // constexpr span& operator=(const span& other) noexcept = default;
14
15 #include <span>
16 #include <cassert>
17 #include <string>
18 #include <utility>
19
20 #include "test_macros.h"
21
22 template <typename T>
doAssign(T lhs,T rhs)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
main(int,char **)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 (size_t i = 0; i < std::size(spans); ++i)
245 for (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 (size_t i = 0; i < std::size(spans); ++i)
259 for (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 (size_t i = 0; i < std::size(spans); ++i)
279 for (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 (size_t i = 0; i < std::size(spans); ++i)
292 for (size_t j = i; j < std::size(spans); ++j)
293 assert((doAssign(spans[i], spans[j])));
294 }
295
296 return 0;
297 }
298