1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/containers/span.h"
6
7 #include <stdint.h>
8
9 #include <algorithm>
10 #include <memory>
11 #include <string>
12 #include <vector>
13
14 #include "base/macros.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using ::testing::ElementsAre;
19 using ::testing::Eq;
20 using ::testing::Pointwise;
21
22 namespace base {
23
TEST(SpanTest,DefaultConstructor)24 TEST(SpanTest, DefaultConstructor) {
25 span<int> dynamic_span;
26 EXPECT_EQ(nullptr, dynamic_span.data());
27 EXPECT_EQ(0u, dynamic_span.size());
28
29 constexpr span<int, 0> static_span;
30 static_assert(nullptr == static_span.data(), "");
31 static_assert(0u == static_span.size(), "");
32 }
33
TEST(SpanTest,ConstructFromDataAndSize)34 TEST(SpanTest, ConstructFromDataAndSize) {
35 constexpr span<int> empty_span(nullptr, 0);
36 EXPECT_TRUE(empty_span.empty());
37 EXPECT_EQ(nullptr, empty_span.data());
38
39 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
40
41 span<int> dynamic_span(vector.data(), vector.size());
42 EXPECT_EQ(vector.data(), dynamic_span.data());
43 EXPECT_EQ(vector.size(), dynamic_span.size());
44
45 for (size_t i = 0; i < dynamic_span.size(); ++i)
46 EXPECT_EQ(vector[i], dynamic_span[i]);
47
48 span<int, 6> static_span(vector.data(), vector.size());
49 EXPECT_EQ(vector.data(), static_span.data());
50 EXPECT_EQ(vector.size(), static_span.size());
51
52 for (size_t i = 0; i < static_span.size(); ++i)
53 EXPECT_EQ(vector[i], static_span[i]);
54 }
55
TEST(SpanTest,ConstructFromPointerPair)56 TEST(SpanTest, ConstructFromPointerPair) {
57 constexpr span<int> empty_span(nullptr, nullptr);
58 EXPECT_TRUE(empty_span.empty());
59 EXPECT_EQ(nullptr, empty_span.data());
60
61 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
62
63 span<int> dynamic_span(vector.data(), vector.data() + vector.size() / 2);
64 EXPECT_EQ(vector.data(), dynamic_span.data());
65 EXPECT_EQ(vector.size() / 2, dynamic_span.size());
66
67 for (size_t i = 0; i < dynamic_span.size(); ++i)
68 EXPECT_EQ(vector[i], dynamic_span[i]);
69
70 span<int, 3> static_span(vector.data(), vector.data() + vector.size() / 2);
71 EXPECT_EQ(vector.data(), static_span.data());
72 EXPECT_EQ(vector.size() / 2, static_span.size());
73
74 for (size_t i = 0; i < static_span.size(); ++i)
75 EXPECT_EQ(vector[i], static_span[i]);
76 }
77
TEST(SpanTest,ConstructFromConstexprArray)78 TEST(SpanTest, ConstructFromConstexprArray) {
79 static constexpr int kArray[] = {5, 4, 3, 2, 1};
80
81 constexpr span<const int> dynamic_span(kArray);
82 static_assert(kArray == dynamic_span.data(), "");
83 static_assert(base::size(kArray) == dynamic_span.size(), "");
84
85 static_assert(kArray[0] == dynamic_span[0], "");
86 static_assert(kArray[1] == dynamic_span[1], "");
87 static_assert(kArray[2] == dynamic_span[2], "");
88 static_assert(kArray[3] == dynamic_span[3], "");
89 static_assert(kArray[4] == dynamic_span[4], "");
90
91 constexpr span<const int, base::size(kArray)> static_span(kArray);
92 static_assert(kArray == static_span.data(), "");
93 static_assert(base::size(kArray) == static_span.size(), "");
94
95 static_assert(kArray[0] == static_span[0], "");
96 static_assert(kArray[1] == static_span[1], "");
97 static_assert(kArray[2] == static_span[2], "");
98 static_assert(kArray[3] == static_span[3], "");
99 static_assert(kArray[4] == static_span[4], "");
100 }
101
TEST(SpanTest,ConstructFromArray)102 TEST(SpanTest, ConstructFromArray) {
103 int array[] = {5, 4, 3, 2, 1};
104
105 span<const int> const_span(array);
106 EXPECT_EQ(array, const_span.data());
107 EXPECT_EQ(arraysize(array), const_span.size());
108 for (size_t i = 0; i < const_span.size(); ++i)
109 EXPECT_EQ(array[i], const_span[i]);
110
111 span<int> dynamic_span(array);
112 EXPECT_EQ(array, dynamic_span.data());
113 EXPECT_EQ(base::size(array), dynamic_span.size());
114 for (size_t i = 0; i < dynamic_span.size(); ++i)
115 EXPECT_EQ(array[i], dynamic_span[i]);
116
117 span<int, base::size(array)> static_span(array);
118 EXPECT_EQ(array, static_span.data());
119 EXPECT_EQ(base::size(array), static_span.size());
120 for (size_t i = 0; i < static_span.size(); ++i)
121 EXPECT_EQ(array[i], static_span[i]);
122 }
123
TEST(SpanTest,ConstructFromStdArray)124 TEST(SpanTest, ConstructFromStdArray) {
125 // Note: Constructing a constexpr span from a constexpr std::array does not
126 // work prior to C++17 due to non-constexpr std::array::data.
127 std::array<int, 5> array = {{5, 4, 3, 2, 1}};
128
129 span<const int> const_span(array);
130 EXPECT_EQ(array.data(), const_span.data());
131 EXPECT_EQ(array.size(), const_span.size());
132 for (size_t i = 0; i < const_span.size(); ++i)
133 EXPECT_EQ(array[i], const_span[i]);
134
135 span<int> dynamic_span(array);
136 EXPECT_EQ(array.data(), dynamic_span.data());
137 EXPECT_EQ(array.size(), dynamic_span.size());
138 for (size_t i = 0; i < dynamic_span.size(); ++i)
139 EXPECT_EQ(array[i], dynamic_span[i]);
140
141 span<int, base::size(array)> static_span(array);
142 EXPECT_EQ(array.data(), static_span.data());
143 EXPECT_EQ(array.size(), static_span.size());
144 for (size_t i = 0; i < static_span.size(); ++i)
145 EXPECT_EQ(array[i], static_span[i]);
146 }
147
TEST(SpanTest,ConstructFromInitializerList)148 TEST(SpanTest, ConstructFromInitializerList) {
149 std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
150
151 span<const int> const_span(il);
152 EXPECT_EQ(il.begin(), const_span.data());
153 EXPECT_EQ(il.size(), const_span.size());
154
155 for (size_t i = 0; i < const_span.size(); ++i)
156 EXPECT_EQ(il.begin()[i], const_span[i]);
157
158 span<const int, 6> static_span(il);
159 EXPECT_EQ(il.begin(), static_span.data());
160 EXPECT_EQ(il.size(), static_span.size());
161
162 for (size_t i = 0; i < static_span.size(); ++i)
163 EXPECT_EQ(il.begin()[i], static_span[i]);
164 }
165
TEST(SpanTest,ConstructFromStdString)166 TEST(SpanTest, ConstructFromStdString) {
167 std::string str = "foobar";
168
169 span<const char> const_span(str);
170 EXPECT_EQ(str.data(), const_span.data());
171 EXPECT_EQ(str.size(), const_span.size());
172
173 for (size_t i = 0; i < const_span.size(); ++i)
174 EXPECT_EQ(str[i], const_span[i]);
175
176 span<char> dynamic_span(str);
177 EXPECT_EQ(str.data(), dynamic_span.data());
178 EXPECT_EQ(str.size(), dynamic_span.size());
179
180 for (size_t i = 0; i < dynamic_span.size(); ++i)
181 EXPECT_EQ(str[i], dynamic_span[i]);
182
183 span<char, 6> static_span(str);
184 EXPECT_EQ(str.data(), static_span.data());
185 EXPECT_EQ(str.size(), static_span.size());
186
187 for (size_t i = 0; i < static_span.size(); ++i)
188 EXPECT_EQ(str[i], static_span[i]);
189 }
190
TEST(SpanTest,ConstructFromConstContainer)191 TEST(SpanTest, ConstructFromConstContainer) {
192 const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
193
194 span<const int> const_span(vector);
195 EXPECT_EQ(vector.data(), const_span.data());
196 EXPECT_EQ(vector.size(), const_span.size());
197
198 for (size_t i = 0; i < const_span.size(); ++i)
199 EXPECT_EQ(vector[i], const_span[i]);
200
201 span<const int, 6> static_span(vector);
202 EXPECT_EQ(vector.data(), static_span.data());
203 EXPECT_EQ(vector.size(), static_span.size());
204
205 for (size_t i = 0; i < static_span.size(); ++i)
206 EXPECT_EQ(vector[i], static_span[i]);
207 }
208
TEST(SpanTest,ConstructFromContainer)209 TEST(SpanTest, ConstructFromContainer) {
210 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
211
212 span<const int> const_span(vector);
213 EXPECT_EQ(vector.data(), const_span.data());
214 EXPECT_EQ(vector.size(), const_span.size());
215
216 for (size_t i = 0; i < const_span.size(); ++i)
217 EXPECT_EQ(vector[i], const_span[i]);
218
219 span<int> dynamic_span(vector);
220 EXPECT_EQ(vector.data(), dynamic_span.data());
221 EXPECT_EQ(vector.size(), dynamic_span.size());
222
223 for (size_t i = 0; i < dynamic_span.size(); ++i)
224 EXPECT_EQ(vector[i], dynamic_span[i]);
225
226 span<int, 6> static_span(vector);
227 EXPECT_EQ(vector.data(), static_span.data());
228 EXPECT_EQ(vector.size(), static_span.size());
229
230 for (size_t i = 0; i < static_span.size(); ++i)
231 EXPECT_EQ(vector[i], static_span[i]);
232 }
233
TEST(SpanTest,ConvertNonConstIntegralToConst)234 TEST(SpanTest, ConvertNonConstIntegralToConst) {
235 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
236
237 span<int> int_span(vector.data(), vector.size());
238 span<const int> const_span(int_span);
239 EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
240
241 span<int, 6> static_int_span(vector.data(), vector.size());
242 span<const int, 6> static_const_span(static_int_span);
243 EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
244 }
245
TEST(SpanTest,ConvertNonConstPointerToConst)246 TEST(SpanTest, ConvertNonConstPointerToConst) {
247 auto a = std::make_unique<int>(11);
248 auto b = std::make_unique<int>(22);
249 auto c = std::make_unique<int>(33);
250 std::vector<int*> vector = {a.get(), b.get(), c.get()};
251
252 span<int*> non_const_pointer_span(vector);
253 EXPECT_THAT(non_const_pointer_span, Pointwise(Eq(), vector));
254 span<int* const> const_pointer_span(non_const_pointer_span);
255 EXPECT_THAT(const_pointer_span, Pointwise(Eq(), non_const_pointer_span));
256 // Note: no test for conversion from span<int> to span<const int*>, since that
257 // would imply a conversion from int** to const int**, which is unsafe.
258 //
259 // Note: no test for conversion from span<int*> to span<const int* const>,
260 // due to CWG Defect 330:
261 // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
262
263 span<int*, 3> static_non_const_pointer_span(vector);
264 EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
265 span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
266 EXPECT_THAT(static_const_pointer_span,
267 Pointwise(Eq(), static_non_const_pointer_span));
268 }
269
TEST(SpanTest,ConvertBetweenEquivalentTypes)270 TEST(SpanTest, ConvertBetweenEquivalentTypes) {
271 std::vector<int32_t> vector = {2, 4, 8, 16, 32};
272
273 span<int32_t> int32_t_span(vector);
274 span<int> converted_span(int32_t_span);
275 EXPECT_EQ(int32_t_span, converted_span);
276
277 span<int32_t, 5> static_int32_t_span(vector);
278 span<int, 5> static_converted_span(static_int32_t_span);
279 EXPECT_EQ(static_int32_t_span, static_converted_span);
280 }
281
TEST(SpanTest,TemplatedFirst)282 TEST(SpanTest, TemplatedFirst) {
283 static constexpr int array[] = {1, 2, 3};
284 constexpr span<const int, 3> span(array);
285
286 {
287 constexpr auto subspan = span.first<0>();
288 static_assert(span.data() == subspan.data(), "");
289 static_assert(0u == subspan.size(), "");
290 static_assert(0u == decltype(subspan)::extent, "");
291 }
292
293 {
294 constexpr auto subspan = span.first<1>();
295 static_assert(span.data() == subspan.data(), "");
296 static_assert(1u == subspan.size(), "");
297 static_assert(1u == decltype(subspan)::extent, "");
298 static_assert(1 == subspan[0], "");
299 }
300
301 {
302 constexpr auto subspan = span.first<2>();
303 static_assert(span.data() == subspan.data(), "");
304 static_assert(2u == subspan.size(), "");
305 static_assert(2u == decltype(subspan)::extent, "");
306 static_assert(1 == subspan[0], "");
307 static_assert(2 == subspan[1], "");
308 }
309
310 {
311 constexpr auto subspan = span.first<3>();
312 static_assert(span.data() == subspan.data(), "");
313 static_assert(3u == subspan.size(), "");
314 static_assert(3u == decltype(subspan)::extent, "");
315 static_assert(1 == subspan[0], "");
316 static_assert(2 == subspan[1], "");
317 static_assert(3 == subspan[2], "");
318 }
319 }
320
TEST(SpanTest,TemplatedLast)321 TEST(SpanTest, TemplatedLast) {
322 static constexpr int array[] = {1, 2, 3};
323 constexpr span<const int, 3> span(array);
324
325 {
326 constexpr auto subspan = span.last<0>();
327 static_assert(span.data() + 3 == subspan.data(), "");
328 static_assert(0u == subspan.size(), "");
329 static_assert(0u == decltype(subspan)::extent, "");
330 }
331
332 {
333 constexpr auto subspan = span.last<1>();
334 static_assert(span.data() + 2 == subspan.data(), "");
335 static_assert(1u == subspan.size(), "");
336 static_assert(1u == decltype(subspan)::extent, "");
337 static_assert(3 == subspan[0], "");
338 }
339
340 {
341 constexpr auto subspan = span.last<2>();
342 static_assert(span.data() + 1 == subspan.data(), "");
343 static_assert(2u == subspan.size(), "");
344 static_assert(2u == decltype(subspan)::extent, "");
345 static_assert(2 == subspan[0], "");
346 static_assert(3 == subspan[1], "");
347 }
348
349 {
350 constexpr auto subspan = span.last<3>();
351 static_assert(span.data() == subspan.data(), "");
352 static_assert(3u == subspan.size(), "");
353 static_assert(3u == decltype(subspan)::extent, "");
354 static_assert(1 == subspan[0], "");
355 static_assert(2 == subspan[1], "");
356 static_assert(3 == subspan[2], "");
357 }
358 }
359
TEST(SpanTest,TemplatedSubspan)360 TEST(SpanTest, TemplatedSubspan) {
361 static constexpr int array[] = {1, 2, 3};
362 constexpr span<const int, 3> span(array);
363
364 {
365 constexpr auto subspan = span.subspan<0>();
366 static_assert(span.data() == subspan.data(), "");
367 static_assert(3u == subspan.size(), "");
368 static_assert(3u == decltype(subspan)::extent, "");
369 static_assert(1 == subspan[0], "");
370 static_assert(2 == subspan[1], "");
371 static_assert(3 == subspan[2], "");
372 }
373
374 {
375 constexpr auto subspan = span.subspan<1>();
376 static_assert(span.data() + 1 == subspan.data(), "");
377 static_assert(2u == subspan.size(), "");
378 static_assert(2u == decltype(subspan)::extent, "");
379 static_assert(2 == subspan[0], "");
380 static_assert(3 == subspan[1], "");
381 }
382
383 {
384 constexpr auto subspan = span.subspan<2>();
385 static_assert(span.data() + 2 == subspan.data(), "");
386 static_assert(1u == subspan.size(), "");
387 static_assert(1u == decltype(subspan)::extent, "");
388 static_assert(3 == subspan[0], "");
389 }
390
391 {
392 constexpr auto subspan = span.subspan<3>();
393 static_assert(span.data() + 3 == subspan.data(), "");
394 static_assert(0u == subspan.size(), "");
395 static_assert(0u == decltype(subspan)::extent, "");
396 }
397
398 {
399 constexpr auto subspan = span.subspan<0, 0>();
400 static_assert(span.data() == subspan.data(), "");
401 static_assert(0u == subspan.size(), "");
402 static_assert(0u == decltype(subspan)::extent, "");
403 }
404
405 {
406 constexpr auto subspan = span.subspan<1, 0>();
407 static_assert(span.data() + 1 == subspan.data(), "");
408 static_assert(0u == subspan.size(), "");
409 static_assert(0u == decltype(subspan)::extent, "");
410 }
411
412 {
413 constexpr auto subspan = span.subspan<2, 0>();
414 static_assert(span.data() + 2 == subspan.data(), "");
415 static_assert(0u == subspan.size(), "");
416 static_assert(0u == decltype(subspan)::extent, "");
417 }
418
419 {
420 constexpr auto subspan = span.subspan<0, 1>();
421 static_assert(span.data() == subspan.data(), "");
422 static_assert(1u == subspan.size(), "");
423 static_assert(1u == decltype(subspan)::extent, "");
424 static_assert(1 == subspan[0], "");
425 }
426
427 {
428 constexpr auto subspan = span.subspan<1, 1>();
429 static_assert(span.data() + 1 == subspan.data(), "");
430 static_assert(1u == subspan.size(), "");
431 static_assert(1u == decltype(subspan)::extent, "");
432 static_assert(2 == subspan[0], "");
433 }
434
435 {
436 constexpr auto subspan = span.subspan<2, 1>();
437 static_assert(span.data() + 2 == subspan.data(), "");
438 static_assert(1u == subspan.size(), "");
439 static_assert(1u == decltype(subspan)::extent, "");
440 static_assert(3 == subspan[0], "");
441 }
442
443 {
444 constexpr auto subspan = span.subspan<0, 2>();
445 static_assert(span.data() == subspan.data(), "");
446 static_assert(2u == subspan.size(), "");
447 static_assert(2u == decltype(subspan)::extent, "");
448 static_assert(1 == subspan[0], "");
449 static_assert(2 == subspan[1], "");
450 }
451
452 {
453 constexpr auto subspan = span.subspan<1, 2>();
454 static_assert(span.data() + 1 == subspan.data(), "");
455 static_assert(2u == subspan.size(), "");
456 static_assert(2u == decltype(subspan)::extent, "");
457 static_assert(2 == subspan[0], "");
458 static_assert(3 == subspan[1], "");
459 }
460
461 {
462 constexpr auto subspan = span.subspan<0, 3>();
463 static_assert(span.data() == subspan.data(), "");
464 static_assert(3u == subspan.size(), "");
465 static_assert(3u == decltype(subspan)::extent, "");
466 static_assert(1 == subspan[0], "");
467 static_assert(2 == subspan[1], "");
468 static_assert(3 == subspan[2], "");
469 }
470 }
471
TEST(SpanTest,TemplatedFirstOnDynamicSpan)472 TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
473 int array[] = {1, 2, 3};
474 span<const int> span(array);
475
476 {
477 auto subspan = span.first<0>();
478 EXPECT_EQ(span.data(), subspan.data());
479 EXPECT_EQ(0u, subspan.size());
480 static_assert(0u == decltype(subspan)::extent, "");
481 }
482
483 {
484 auto subspan = span.first<1>();
485 EXPECT_EQ(span.data(), subspan.data());
486 EXPECT_EQ(1u, subspan.size());
487 static_assert(1u == decltype(subspan)::extent, "");
488 EXPECT_EQ(1, subspan[0]);
489 }
490
491 {
492 auto subspan = span.first<2>();
493 EXPECT_EQ(span.data(), subspan.data());
494 EXPECT_EQ(2u, subspan.size());
495 static_assert(2u == decltype(subspan)::extent, "");
496 EXPECT_EQ(1, subspan[0]);
497 EXPECT_EQ(2, subspan[1]);
498 }
499
500 {
501 auto subspan = span.first<3>();
502 EXPECT_EQ(span.data(), subspan.data());
503 EXPECT_EQ(3u, subspan.size());
504 static_assert(3u == decltype(subspan)::extent, "");
505 EXPECT_EQ(1, subspan[0]);
506 EXPECT_EQ(2, subspan[1]);
507 EXPECT_EQ(3, subspan[2]);
508 }
509 }
510
TEST(SpanTest,TemplatedLastOnDynamicSpan)511 TEST(SpanTest, TemplatedLastOnDynamicSpan) {
512 int array[] = {1, 2, 3};
513 span<int> span(array);
514
515 {
516 auto subspan = span.last<0>();
517 EXPECT_EQ(span.data() + 3, subspan.data());
518 EXPECT_EQ(0u, subspan.size());
519 static_assert(0u == decltype(subspan)::extent, "");
520 }
521
522 {
523 auto subspan = span.last<1>();
524 EXPECT_EQ(span.data() + 2, subspan.data());
525 EXPECT_EQ(1u, subspan.size());
526 static_assert(1u == decltype(subspan)::extent, "");
527 EXPECT_EQ(3, subspan[0]);
528 }
529
530 {
531 auto subspan = span.last<2>();
532 EXPECT_EQ(span.data() + 1, subspan.data());
533 EXPECT_EQ(2u, subspan.size());
534 static_assert(2u == decltype(subspan)::extent, "");
535 EXPECT_EQ(2, subspan[0]);
536 EXPECT_EQ(3, subspan[1]);
537 }
538
539 {
540 auto subspan = span.last<3>();
541 EXPECT_EQ(span.data(), subspan.data());
542 EXPECT_EQ(3u, subspan.size());
543 static_assert(3u == decltype(subspan)::extent, "");
544 EXPECT_EQ(1, subspan[0]);
545 EXPECT_EQ(2, subspan[1]);
546 EXPECT_EQ(3, subspan[2]);
547 }
548 }
549
TEST(SpanTest,TemplatedSubspanFromDynamicSpan)550 TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
551 int array[] = {1, 2, 3};
552 span<int, 3> span(array);
553
554 {
555 auto subspan = span.subspan<0>();
556 EXPECT_EQ(span.data(), subspan.data());
557 static_assert(3u == decltype(subspan)::extent, "");
558 EXPECT_EQ(3u, subspan.size());
559 EXPECT_EQ(1, subspan[0]);
560 EXPECT_EQ(2, subspan[1]);
561 EXPECT_EQ(3, subspan[2]);
562 }
563
564 {
565 auto subspan = span.subspan<1>();
566 EXPECT_EQ(span.data() + 1, subspan.data());
567 EXPECT_EQ(2u, subspan.size());
568 static_assert(2u == decltype(subspan)::extent, "");
569 EXPECT_EQ(2, subspan[0]);
570 EXPECT_EQ(3, subspan[1]);
571 }
572
573 {
574 auto subspan = span.subspan<2>();
575 EXPECT_EQ(span.data() + 2, subspan.data());
576 EXPECT_EQ(1u, subspan.size());
577 static_assert(1u == decltype(subspan)::extent, "");
578 EXPECT_EQ(3, subspan[0]);
579 }
580
581 {
582 auto subspan = span.subspan<3>();
583 EXPECT_EQ(span.data() + 3, subspan.data());
584 EXPECT_EQ(0u, subspan.size());
585 static_assert(0u == decltype(subspan)::extent, "");
586 }
587
588 {
589 auto subspan = span.subspan<0, 0>();
590 EXPECT_EQ(span.data(), subspan.data());
591 EXPECT_EQ(0u, subspan.size());
592 static_assert(0u == decltype(subspan)::extent, "");
593 }
594
595 {
596 auto subspan = span.subspan<1, 0>();
597 EXPECT_EQ(span.data() + 1, subspan.data());
598 EXPECT_EQ(0u, subspan.size());
599 static_assert(0u == decltype(subspan)::extent, "");
600 }
601
602 {
603 auto subspan = span.subspan<2, 0>();
604 EXPECT_EQ(span.data() + 2, subspan.data());
605 EXPECT_EQ(0u, subspan.size());
606 static_assert(0u == decltype(subspan)::extent, "");
607 }
608
609 {
610 auto subspan = span.subspan<0, 1>();
611 EXPECT_EQ(span.data(), subspan.data());
612 EXPECT_EQ(1u, subspan.size());
613 static_assert(1u == decltype(subspan)::extent, "");
614 EXPECT_EQ(1, subspan[0]);
615 }
616
617 {
618 auto subspan = span.subspan<1, 1>();
619 EXPECT_EQ(span.data() + 1, subspan.data());
620 EXPECT_EQ(1u, subspan.size());
621 static_assert(1u == decltype(subspan)::extent, "");
622 EXPECT_EQ(2, subspan[0]);
623 }
624
625 {
626 auto subspan = span.subspan<2, 1>();
627 EXPECT_EQ(span.data() + 2, subspan.data());
628 EXPECT_EQ(1u, subspan.size());
629 static_assert(1u == decltype(subspan)::extent, "");
630 EXPECT_EQ(3, subspan[0]);
631 }
632
633 {
634 auto subspan = span.subspan<0, 2>();
635 EXPECT_EQ(span.data(), subspan.data());
636 EXPECT_EQ(2u, subspan.size());
637 static_assert(2u == decltype(subspan)::extent, "");
638 EXPECT_EQ(1, subspan[0]);
639 EXPECT_EQ(2, subspan[1]);
640 }
641
642 {
643 auto subspan = span.subspan<1, 2>();
644 EXPECT_EQ(span.data() + 1, subspan.data());
645 EXPECT_EQ(2u, subspan.size());
646 static_assert(2u == decltype(subspan)::extent, "");
647 EXPECT_EQ(2, subspan[0]);
648 EXPECT_EQ(3, subspan[1]);
649 }
650
651 {
652 auto subspan = span.subspan<0, 3>();
653 EXPECT_EQ(span.data(), subspan.data());
654 EXPECT_EQ(3u, subspan.size());
655 static_assert(3u == decltype(subspan)::extent, "");
656 EXPECT_EQ(1, subspan[0]);
657 EXPECT_EQ(2, subspan[1]);
658 EXPECT_EQ(3, subspan[2]);
659 }
660 }
661
TEST(SpanTest,First)662 TEST(SpanTest, First) {
663 int array[] = {1, 2, 3};
664 span<int> span(array);
665
666 {
667 auto subspan = span.first(0);
668 EXPECT_EQ(span.data(), subspan.data());
669 EXPECT_EQ(0u, subspan.size());
670 }
671
672 {
673 auto subspan = span.first(1);
674 EXPECT_EQ(span.data(), subspan.data());
675 EXPECT_EQ(1u, subspan.size());
676 EXPECT_EQ(1, subspan[0]);
677 }
678
679 {
680 auto subspan = span.first(2);
681 EXPECT_EQ(span.data(), subspan.data());
682 EXPECT_EQ(2u, subspan.size());
683 EXPECT_EQ(1, subspan[0]);
684 EXPECT_EQ(2, subspan[1]);
685 }
686
687 {
688 auto subspan = span.first(3);
689 EXPECT_EQ(span.data(), subspan.data());
690 EXPECT_EQ(3u, subspan.size());
691 EXPECT_EQ(1, subspan[0]);
692 EXPECT_EQ(2, subspan[1]);
693 EXPECT_EQ(3, subspan[2]);
694 }
695 }
696
TEST(SpanTest,Last)697 TEST(SpanTest, Last) {
698 int array[] = {1, 2, 3};
699 span<int> span(array);
700
701 {
702 auto subspan = span.last(0);
703 EXPECT_EQ(span.data() + 3, subspan.data());
704 EXPECT_EQ(0u, subspan.size());
705 }
706
707 {
708 auto subspan = span.last(1);
709 EXPECT_EQ(span.data() + 2, subspan.data());
710 EXPECT_EQ(1u, subspan.size());
711 EXPECT_EQ(3, subspan[0]);
712 }
713
714 {
715 auto subspan = span.last(2);
716 EXPECT_EQ(span.data() + 1, subspan.data());
717 EXPECT_EQ(2u, subspan.size());
718 EXPECT_EQ(2, subspan[0]);
719 EXPECT_EQ(3, subspan[1]);
720 }
721
722 {
723 auto subspan = span.last(3);
724 EXPECT_EQ(span.data(), subspan.data());
725 EXPECT_EQ(3u, subspan.size());
726 EXPECT_EQ(1, subspan[0]);
727 EXPECT_EQ(2, subspan[1]);
728 EXPECT_EQ(3, subspan[2]);
729 }
730 }
731
TEST(SpanTest,Subspan)732 TEST(SpanTest, Subspan) {
733 int array[] = {1, 2, 3};
734 span<int> span(array);
735
736 {
737 auto subspan = span.subspan(0);
738 EXPECT_EQ(span.data(), subspan.data());
739 EXPECT_EQ(3u, subspan.size());
740 EXPECT_EQ(1, subspan[0]);
741 EXPECT_EQ(2, subspan[1]);
742 EXPECT_EQ(3, subspan[2]);
743 }
744
745 {
746 auto subspan = span.subspan(1);
747 EXPECT_EQ(span.data() + 1, subspan.data());
748 EXPECT_EQ(2u, subspan.size());
749 EXPECT_EQ(2, subspan[0]);
750 EXPECT_EQ(3, subspan[1]);
751 }
752
753 {
754 auto subspan = span.subspan(2);
755 EXPECT_EQ(span.data() + 2, subspan.data());
756 EXPECT_EQ(1u, subspan.size());
757 EXPECT_EQ(3, subspan[0]);
758 }
759
760 {
761 auto subspan = span.subspan(3);
762 EXPECT_EQ(span.data() + 3, subspan.data());
763 EXPECT_EQ(0u, subspan.size());
764 }
765
766 {
767 auto subspan = span.subspan(0, 0);
768 EXPECT_EQ(span.data(), subspan.data());
769 EXPECT_EQ(0u, subspan.size());
770 }
771
772 {
773 auto subspan = span.subspan(1, 0);
774 EXPECT_EQ(span.data() + 1, subspan.data());
775 EXPECT_EQ(0u, subspan.size());
776 }
777
778 {
779 auto subspan = span.subspan(2, 0);
780 EXPECT_EQ(span.data() + 2, subspan.data());
781 EXPECT_EQ(0u, subspan.size());
782 }
783
784 {
785 auto subspan = span.subspan(0, 1);
786 EXPECT_EQ(span.data(), subspan.data());
787 EXPECT_EQ(1u, subspan.size());
788 EXPECT_EQ(1, subspan[0]);
789 }
790
791 {
792 auto subspan = span.subspan(1, 1);
793 EXPECT_EQ(span.data() + 1, subspan.data());
794 EXPECT_EQ(1u, subspan.size());
795 EXPECT_EQ(2, subspan[0]);
796 }
797
798 {
799 auto subspan = span.subspan(2, 1);
800 EXPECT_EQ(span.data() + 2, subspan.data());
801 EXPECT_EQ(1u, subspan.size());
802 EXPECT_EQ(3, subspan[0]);
803 }
804
805 {
806 auto subspan = span.subspan(0, 2);
807 EXPECT_EQ(span.data(), subspan.data());
808 EXPECT_EQ(2u, subspan.size());
809 EXPECT_EQ(1, subspan[0]);
810 EXPECT_EQ(2, subspan[1]);
811 }
812
813 {
814 auto subspan = span.subspan(1, 2);
815 EXPECT_EQ(span.data() + 1, subspan.data());
816 EXPECT_EQ(2u, subspan.size());
817 EXPECT_EQ(2, subspan[0]);
818 EXPECT_EQ(3, subspan[1]);
819 }
820
821 {
822 auto subspan = span.subspan(0, 3);
823 EXPECT_EQ(span.data(), subspan.data());
824 EXPECT_EQ(span.size(), subspan.size());
825 EXPECT_EQ(1, subspan[0]);
826 EXPECT_EQ(2, subspan[1]);
827 EXPECT_EQ(3, subspan[2]);
828 }
829 }
830
TEST(SpanTest,Size)831 TEST(SpanTest, Size) {
832 {
833 span<int> span;
834 EXPECT_EQ(0u, span.size());
835 }
836
837 {
838 int array[] = {1, 2, 3};
839 span<int> span(array);
840 EXPECT_EQ(3u, span.size());
841 }
842 }
843
TEST(SpanTest,SizeBytes)844 TEST(SpanTest, SizeBytes) {
845 {
846 span<int> span;
847 EXPECT_EQ(0u, span.size_bytes());
848 }
849
850 {
851 int array[] = {1, 2, 3};
852 span<int> span(array);
853 EXPECT_EQ(3u * sizeof(int), span.size_bytes());
854 }
855 }
856
TEST(SpanTest,Empty)857 TEST(SpanTest, Empty) {
858 {
859 span<int> span;
860 EXPECT_TRUE(span.empty());
861 }
862
863 {
864 int array[] = {1, 2, 3};
865 span<int> span(array);
866 EXPECT_FALSE(span.empty());
867 }
868 }
869
TEST(SpanTest,OperatorAt)870 TEST(SpanTest, OperatorAt) {
871 static constexpr int kArray[] = {1, 6, 1, 8, 0};
872 constexpr span<const int> span(kArray);
873
874 static_assert(kArray[0] == span[0], "span[0] does not equal kArray[0]");
875 static_assert(kArray[1] == span[1], "span[1] does not equal kArray[1]");
876 static_assert(kArray[2] == span[2], "span[2] does not equal kArray[2]");
877 static_assert(kArray[3] == span[3], "span[3] does not equal kArray[3]");
878 static_assert(kArray[4] == span[4], "span[4] does not equal kArray[4]");
879
880 static_assert(kArray[0] == span(0), "span(0) does not equal kArray[0]");
881 static_assert(kArray[1] == span(1), "span(1) does not equal kArray[1]");
882 static_assert(kArray[2] == span(2), "span(2) does not equal kArray[2]");
883 static_assert(kArray[3] == span(3), "span(3) does not equal kArray[3]");
884 static_assert(kArray[4] == span(4), "span(4) does not equal kArray[4]");
885 }
886
TEST(SpanTest,Iterator)887 TEST(SpanTest, Iterator) {
888 static constexpr int kArray[] = {1, 6, 1, 8, 0};
889 constexpr span<const int> span(kArray);
890
891 std::vector<int> results;
892 for (int i : span)
893 results.emplace_back(i);
894 EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
895 }
896
TEST(SpanTest,ReverseIterator)897 TEST(SpanTest, ReverseIterator) {
898 static constexpr int kArray[] = {1, 6, 1, 8, 0};
899 constexpr span<const int> span(kArray);
900
901 EXPECT_TRUE(std::equal(std::rbegin(kArray), std::rend(kArray), span.rbegin(),
902 span.rend()));
903 EXPECT_TRUE(std::equal(std::crbegin(kArray), std::crend(kArray),
904 span.crbegin(), span.crend()));
905 }
906
TEST(SpanTest,Equality)907 TEST(SpanTest, Equality) {
908 static constexpr int kArray1[] = {3, 1, 4, 1, 5};
909 static constexpr int kArray2[] = {3, 1, 4, 1, 5};
910 constexpr span<const int> span1(kArray1);
911 constexpr span<const int, 5> span2(kArray2);
912
913 EXPECT_EQ(span1, span2);
914
915 static constexpr int kArray3[] = {2, 7, 1, 8, 3};
916 constexpr span<const int> span3(kArray3);
917
918 EXPECT_FALSE(span1 == span3);
919
920 static double kArray4[] = {2.0, 7.0, 1.0, 8.0, 3.0};
921 span<double, 5> span4(kArray4);
922
923 EXPECT_EQ(span3, span4);
924 }
925
TEST(SpanTest,Inequality)926 TEST(SpanTest, Inequality) {
927 static constexpr int kArray1[] = {2, 3, 5, 7, 11};
928 static constexpr int kArray2[] = {1, 4, 6, 8, 9};
929 constexpr span<const int> span1(kArray1);
930 constexpr span<const int, 5> span2(kArray2);
931
932 EXPECT_NE(span1, span2);
933
934 static constexpr int kArray3[] = {2, 3, 5, 7, 11};
935 constexpr span<const int> span3(kArray3);
936
937 EXPECT_FALSE(span1 != span3);
938
939 static double kArray4[] = {1.0, 4.0, 6.0, 8.0, 9.0};
940 span<double, 5> span4(kArray4);
941
942 EXPECT_NE(span3, span4);
943 }
944
TEST(SpanTest,LessThan)945 TEST(SpanTest, LessThan) {
946 static constexpr int kArray1[] = {2, 3, 5, 7, 11};
947 static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
948 constexpr span<const int> span1(kArray1);
949 constexpr span<const int, 6> span2(kArray2);
950
951 EXPECT_LT(span1, span2);
952
953 static constexpr int kArray3[] = {2, 3, 5, 7, 11};
954 constexpr span<const int> span3(kArray3);
955
956 EXPECT_FALSE(span1 < span3);
957
958 static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
959 span<double, 6> span4(kArray4);
960
961 EXPECT_LT(span3, span4);
962 }
963
TEST(SpanTest,LessEqual)964 TEST(SpanTest, LessEqual) {
965 static constexpr int kArray1[] = {2, 3, 5, 7, 11};
966 static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
967 constexpr span<const int> span1(kArray1);
968 constexpr span<const int, 6> span2(kArray2);
969
970 EXPECT_LE(span1, span1);
971 EXPECT_LE(span1, span2);
972
973 static constexpr int kArray3[] = {2, 3, 5, 7, 10};
974 constexpr span<const int> span3(kArray3);
975
976 EXPECT_FALSE(span1 <= span3);
977
978 static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
979 span<double, 6> span4(kArray4);
980
981 EXPECT_LE(span3, span4);
982 }
983
TEST(SpanTest,GreaterThan)984 TEST(SpanTest, GreaterThan) {
985 static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
986 static constexpr int kArray2[] = {2, 3, 5, 7, 11};
987 constexpr span<const int> span1(kArray1);
988 constexpr span<const int, 5> span2(kArray2);
989
990 EXPECT_GT(span1, span2);
991
992 static constexpr int kArray3[] = {2, 3, 5, 7, 11, 13};
993 constexpr span<const int> span3(kArray3);
994
995 EXPECT_FALSE(span1 > span3);
996
997 static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
998 span<double, 5> span4(kArray4);
999
1000 EXPECT_GT(span3, span4);
1001 }
1002
TEST(SpanTest,GreaterEqual)1003 TEST(SpanTest, GreaterEqual) {
1004 static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
1005 static constexpr int kArray2[] = {2, 3, 5, 7, 11};
1006 constexpr span<const int> span1(kArray1);
1007 constexpr span<const int, 5> span2(kArray2);
1008
1009 EXPECT_GE(span1, span1);
1010 EXPECT_GE(span1, span2);
1011
1012 static constexpr int kArray3[] = {2, 3, 5, 7, 12};
1013 constexpr span<const int> span3(kArray3);
1014
1015 EXPECT_FALSE(span1 >= span3);
1016
1017 static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
1018 span<double, 5> span4(kArray4);
1019
1020 EXPECT_GE(span3, span4);
1021 }
1022
TEST(SpanTest,AsBytes)1023 TEST(SpanTest, AsBytes) {
1024 {
1025 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1026 span<const uint8_t, sizeof(kArray)> bytes_span =
1027 as_bytes(make_span(kArray));
1028 EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
1029 EXPECT_EQ(sizeof(kArray), bytes_span.size());
1030 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1031 }
1032
1033 {
1034 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1035 span<int> mutable_span(vec);
1036 span<const uint8_t> bytes_span = as_bytes(mutable_span);
1037 EXPECT_EQ(reinterpret_cast<const uint8_t*>(vec.data()), bytes_span.data());
1038 EXPECT_EQ(sizeof(int) * vec.size(), bytes_span.size());
1039 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1040 }
1041 }
1042
TEST(SpanTest,AsWritableBytes)1043 TEST(SpanTest, AsWritableBytes) {
1044 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1045 span<int> mutable_span(vec);
1046 span<uint8_t> writable_bytes_span = as_writable_bytes(mutable_span);
1047 EXPECT_EQ(reinterpret_cast<uint8_t*>(vec.data()), writable_bytes_span.data());
1048 EXPECT_EQ(sizeof(int) * vec.size(), writable_bytes_span.size());
1049 EXPECT_EQ(writable_bytes_span.size(), writable_bytes_span.size_bytes());
1050
1051 // Set the first entry of vec to zero while writing through the span.
1052 std::fill(writable_bytes_span.data(),
1053 writable_bytes_span.data() + sizeof(int), 0);
1054 EXPECT_EQ(0, vec[0]);
1055 }
1056
TEST(SpanTest,MakeSpanFromDataAndSize)1057 TEST(SpanTest, MakeSpanFromDataAndSize) {
1058 int* nullint = nullptr;
1059 auto empty_span = make_span(nullint, 0);
1060 EXPECT_TRUE(empty_span.empty());
1061 EXPECT_EQ(nullptr, empty_span.data());
1062
1063 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1064 span<int> span(vector.data(), vector.size());
1065 auto made_span = make_span(vector.data(), vector.size());
1066 EXPECT_EQ(span, made_span);
1067 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1068 }
1069
TEST(SpanTest,MakeSpanFromPointerPair)1070 TEST(SpanTest, MakeSpanFromPointerPair) {
1071 int* nullint = nullptr;
1072 auto empty_span = make_span(nullint, nullint);
1073 EXPECT_TRUE(empty_span.empty());
1074 EXPECT_EQ(nullptr, empty_span.data());
1075
1076 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1077 span<int> span(vector.data(), vector.size());
1078 auto made_span = make_span(vector.data(), vector.data() + vector.size());
1079 EXPECT_EQ(span, made_span);
1080 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1081 }
1082
TEST(SpanTest,MakeSpanFromConstexprArray)1083 TEST(SpanTest, MakeSpanFromConstexprArray) {
1084 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1085 constexpr span<const int> span(kArray);
1086 EXPECT_EQ(span, make_span(kArray));
1087 static_assert(decltype(make_span(kArray))::extent == 5, "");
1088 }
1089
TEST(SpanTest,MakeSpanFromStdArray)1090 TEST(SpanTest, MakeSpanFromStdArray) {
1091 const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
1092 span<const int> span(kArray);
1093 EXPECT_EQ(span, make_span(kArray));
1094 static_assert(decltype(make_span(kArray))::extent == 5, "");
1095 }
1096
TEST(SpanTest,MakeSpanFromConstContainer)1097 TEST(SpanTest, MakeSpanFromConstContainer) {
1098 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1099 span<const int> span(vector);
1100 EXPECT_EQ(span, make_span(vector));
1101 static_assert(decltype(make_span(vector))::extent == dynamic_extent, "");
1102 }
1103
TEST(SpanTest,MakeSpanFromContainer)1104 TEST(SpanTest, MakeSpanFromContainer) {
1105 std::vector<int> vector = {-1, -2, -3, -4, -5};
1106 span<int> span(vector);
1107 EXPECT_EQ(span, make_span(vector));
1108 static_assert(decltype(make_span(vector))::extent == dynamic_extent, "");
1109 }
1110
TEST(SpanTest,MakeSpanFromDynamicSpan)1111 TEST(SpanTest, MakeSpanFromDynamicSpan) {
1112 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1113 constexpr span<const int> span(kArray);
1114 static_assert(std::is_same<decltype(span)::element_type,
1115 decltype(make_span(span))::element_type>::value,
1116 "make_span(span) should have the same element_type as span");
1117
1118 static_assert(span.data() == make_span(span).data(),
1119 "make_span(span) should have the same data() as span");
1120
1121 static_assert(span.size() == make_span(span).size(),
1122 "make_span(span) should have the same size() as span");
1123
1124 static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
1125 "make_span(span) should have the same extent as span");
1126 }
1127
TEST(SpanTest,MakeSpanFromStaticSpan)1128 TEST(SpanTest, MakeSpanFromStaticSpan) {
1129 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1130 constexpr span<const int, 5> span(kArray);
1131 static_assert(std::is_same<decltype(span)::element_type,
1132 decltype(make_span(span))::element_type>::value,
1133 "make_span(span) should have the same element_type as span");
1134
1135 static_assert(span.data() == make_span(span).data(),
1136 "make_span(span) should have the same data() as span");
1137
1138 static_assert(span.size() == make_span(span).size(),
1139 "make_span(span) should have the same size() as span");
1140
1141 static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
1142 "make_span(span) should have the same extent as span");
1143 }
1144
TEST(SpanTest,EnsureConstexprGoodness)1145 TEST(SpanTest, EnsureConstexprGoodness) {
1146 static constexpr int kArray[] = {5, 4, 3, 2, 1};
1147 constexpr span<const int> constexpr_span(kArray);
1148 const size_t size = 2;
1149
1150 const size_t start = 1;
1151 constexpr span<const int> subspan =
1152 constexpr_span.subspan(start, start + size);
1153 for (size_t i = 0; i < subspan.size(); ++i)
1154 EXPECT_EQ(kArray[start + i], subspan[i]);
1155
1156 constexpr span<const int> firsts = constexpr_span.first(size);
1157 for (size_t i = 0; i < firsts.size(); ++i)
1158 EXPECT_EQ(kArray[i], firsts[i]);
1159
1160 constexpr span<const int> lasts = constexpr_span.last(size);
1161 for (size_t i = 0; i < lasts.size(); ++i) {
1162 const size_t j = (arraysize(kArray) - size) + i;
1163 EXPECT_EQ(kArray[j], lasts[i]);
1164 }
1165
1166 constexpr int item = constexpr_span[size];
1167 EXPECT_EQ(kArray[size], item);
1168 }
1169
1170 } // namespace base
1171