1 // -*- C++ -*-
2 //===------------------------------ span ---------------------------------===//
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===---------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
11
12 // <span>
13
14 // constexpr span& operator=(const span& other) noexcept = default;
15
16 #include <span>
17 #include <cassert>
18 #include <string>
19 #include <utility>
20
21 #include "test_macros.h"
22
23 template <typename T>
doAssign(T lhs,T rhs)24 constexpr bool doAssign(T lhs, T rhs)
25 {
26 ASSERT_NOEXCEPT(std::declval<T&>() = rhs);
27 lhs = rhs;
28 return lhs.data() == rhs.data()
29 && lhs.size() == rhs.size();
30 }
31
32 struct A{};
33
34 constexpr int carr1[] = {1,2,3,4};
35 constexpr int carr2[] = {3,4,5};
36 constexpr int carr3[] = {7,8};
37 int arr[] = {5,6,7,9};
38 std::string strs[] = {"ABC", "DEF", "GHI"};
39
40
main()41 int main ()
42 {
43
44 // constexpr dynamically sized assignment
45 {
46 // On systems where 'ptrdiff_t' is a synonym for 'int',
47 // the call span(ptr, 0) selects the (pointer, index_type) constructor.
48 // On systems where 'ptrdiff_t' is NOT a synonym for 'int',
49 // it is ambiguous, because of 0 also being convertible to a null pointer
50 // and so the compiler can't choose between:
51 // span(pointer, index_type)
52 // and span(pointer, pointer)
53 // We cast zero to std::ptrdiff_t to remove that ambiguity.
54 // Example:
55 // On darwin x86_64, ptrdiff_t is the same as long int.
56 // On darwin i386, ptrdiff_t is the same as int.
57 constexpr std::span<const int> spans[] = {
58 {},
59 {carr1, static_cast<std::ptrdiff_t>(0)},
60 {carr1, 1},
61 {carr1, 2},
62 {carr1, 3},
63 {carr1, 4},
64 {carr2, static_cast<std::ptrdiff_t>(0)},
65 {carr2, 1},
66 {carr2, 2},
67 {carr2, 3},
68 {carr3, static_cast<std::ptrdiff_t>(0)},
69 {carr3, 1},
70 {carr3, 2}
71 };
72
73 static_assert(std::size(spans) == 13, "" );
74
75 // No for loops in constexpr land :-(
76 static_assert(doAssign(spans[0], spans[0]), "");
77 static_assert(doAssign(spans[0], spans[1]), "");
78 static_assert(doAssign(spans[0], spans[2]), "");
79 static_assert(doAssign(spans[0], spans[3]), "");
80 static_assert(doAssign(spans[0], spans[4]), "");
81 static_assert(doAssign(spans[0], spans[5]), "");
82 static_assert(doAssign(spans[0], spans[6]), "");
83 static_assert(doAssign(spans[0], spans[7]), "");
84 static_assert(doAssign(spans[0], spans[8]), "");
85 static_assert(doAssign(spans[0], spans[9]), "");
86 static_assert(doAssign(spans[0], spans[10]), "");
87 static_assert(doAssign(spans[0], spans[11]), "");
88 static_assert(doAssign(spans[0], spans[12]), "");
89
90 static_assert(doAssign(spans[1], spans[1]), "");
91 static_assert(doAssign(spans[1], spans[2]), "");
92 static_assert(doAssign(spans[1], spans[3]), "");
93 static_assert(doAssign(spans[1], spans[4]), "");
94 static_assert(doAssign(spans[1], spans[5]), "");
95 static_assert(doAssign(spans[1], spans[6]), "");
96 static_assert(doAssign(spans[1], spans[7]), "");
97 static_assert(doAssign(spans[1], spans[8]), "");
98 static_assert(doAssign(spans[1], spans[9]), "");
99 static_assert(doAssign(spans[1], spans[10]), "");
100 static_assert(doAssign(spans[1], spans[11]), "");
101 static_assert(doAssign(spans[1], spans[12]), "");
102
103 static_assert(doAssign(spans[2], spans[2]), "");
104 static_assert(doAssign(spans[2], spans[3]), "");
105 static_assert(doAssign(spans[2], spans[4]), "");
106 static_assert(doAssign(spans[2], spans[5]), "");
107 static_assert(doAssign(spans[2], spans[6]), "");
108 static_assert(doAssign(spans[2], spans[7]), "");
109 static_assert(doAssign(spans[2], spans[8]), "");
110 static_assert(doAssign(spans[2], spans[9]), "");
111 static_assert(doAssign(spans[2], spans[10]), "");
112 static_assert(doAssign(spans[2], spans[11]), "");
113 static_assert(doAssign(spans[2], spans[12]), "");
114
115 static_assert(doAssign(spans[3], spans[3]), "");
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[4]), "");
124 static_assert(doAssign(spans[3], spans[10]), "");
125 static_assert(doAssign(spans[3], spans[11]), "");
126 static_assert(doAssign(spans[3], spans[12]), "");
127
128 static_assert(doAssign(spans[4], spans[4]), "");
129 static_assert(doAssign(spans[4], spans[5]), "");
130 static_assert(doAssign(spans[4], spans[6]), "");
131 static_assert(doAssign(spans[4], spans[7]), "");
132 static_assert(doAssign(spans[4], spans[8]), "");
133 static_assert(doAssign(spans[4], spans[9]), "");
134 static_assert(doAssign(spans[4], spans[10]), "");
135 static_assert(doAssign(spans[4], spans[11]), "");
136 static_assert(doAssign(spans[4], spans[12]), "");
137
138 static_assert(doAssign(spans[5], spans[5]), "");
139 static_assert(doAssign(spans[5], spans[6]), "");
140 static_assert(doAssign(spans[5], spans[7]), "");
141 static_assert(doAssign(spans[5], spans[8]), "");
142 static_assert(doAssign(spans[5], spans[9]), "");
143 static_assert(doAssign(spans[5], spans[10]), "");
144 static_assert(doAssign(spans[5], spans[11]), "");
145 static_assert(doAssign(spans[5], spans[12]), "");
146
147 static_assert(doAssign(spans[6], spans[6]), "");
148 static_assert(doAssign(spans[6], spans[7]), "");
149 static_assert(doAssign(spans[6], spans[8]), "");
150 static_assert(doAssign(spans[6], spans[9]), "");
151 static_assert(doAssign(spans[6], spans[10]), "");
152 static_assert(doAssign(spans[6], spans[11]), "");
153 static_assert(doAssign(spans[6], spans[12]), "");
154
155 static_assert(doAssign(spans[7], spans[7]), "");
156 static_assert(doAssign(spans[7], spans[8]), "");
157 static_assert(doAssign(spans[7], spans[9]), "");
158 static_assert(doAssign(spans[7], spans[10]), "");
159 static_assert(doAssign(spans[7], spans[11]), "");
160 static_assert(doAssign(spans[7], spans[12]), "");
161
162 static_assert(doAssign(spans[8], spans[8]), "");
163 static_assert(doAssign(spans[8], spans[9]), "");
164 static_assert(doAssign(spans[8], spans[10]), "");
165 static_assert(doAssign(spans[8], spans[11]), "");
166 static_assert(doAssign(spans[8], spans[12]), "");
167
168 static_assert(doAssign(spans[9], spans[9]), "");
169 static_assert(doAssign(spans[9], spans[10]), "");
170 static_assert(doAssign(spans[9], spans[11]), "");
171 static_assert(doAssign(spans[9], spans[12]), "");
172
173 static_assert(doAssign(spans[10], spans[10]), "");
174 static_assert(doAssign(spans[10], spans[11]), "");
175 static_assert(doAssign(spans[10], spans[12]), "");
176
177 static_assert(doAssign(spans[11], spans[11]), "");
178 static_assert(doAssign(spans[11], spans[12]), "");
179
180 static_assert(doAssign(spans[12], spans[12]), "");
181
182 // for (size_t i = 0; i < std::size(spans); ++i)
183 // for (size_t j = i; j < std::size(spans); ++j)
184 // static_assert(doAssign(spans[i], spans[j]), "");
185 }
186
187 // constexpr statically sized assignment
188 {
189 constexpr std::span<const int,2> spans[] = {
190 {carr1, 2},
191 {carr1 + 1, 2},
192 {carr1 + 2, 2},
193 {carr2, 2},
194 {carr2 + 1, 2},
195 {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 std::span<int,2> spans[] = {
252 {arr, arr + 2},
253 {arr + 1, arr + 3},
254 {arr + 2, arr + 4}
255 };
256
257 for (size_t i = 0; i < std::size(spans); ++i)
258 for (size_t j = i; j < std::size(spans); ++j)
259 assert((doAssign(spans[i], spans[j])));
260 }
261
262 // dynamically sized assignment
263 {
264 std::span<std::string> spans[] = {
265 {strs, strs},
266 {strs, strs + 1},
267 {strs, strs + 2},
268 {strs, strs + 3},
269 {strs + 1, strs + 1},
270 {strs + 1, strs + 2},
271 {strs + 1, strs + 3},
272 {strs + 2, strs + 2},
273 {strs + 2, strs + 3},
274 {strs + 3, strs + 3}
275 };
276
277 for (size_t i = 0; i < std::size(spans); ++i)
278 for (size_t j = i; j < std::size(spans); ++j)
279 assert((doAssign(spans[i], spans[j])));
280 }
281
282 {
283 std::span<std::string, 1> spans[] = {
284 {strs, strs + 1},
285 {strs + 1, strs + 2},
286 {strs + 2, strs + 3}
287 };
288
289 for (size_t i = 0; i < std::size(spans); ++i)
290 for (size_t j = i; j < std::size(spans); ++j)
291 assert((doAssign(spans[i], spans[j])));
292 }
293 }
294