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