1 // Copyright 2017 The Chromium Authors
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 <concepts>
11 #include <iterator>
12 #include <memory>
13 #include <span>
14 #include <string>
15 #include <string_view>
16 #include <type_traits>
17 #include <utility>
18 #include <vector>
19
20 #include "base/containers/adapters.h"
21 #include "base/containers/checked_iterators.h"
22 #include "base/ranges/algorithm.h"
23 #include "base/test/gtest_util.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 using ::testing::ElementsAre;
28 using ::testing::Eq;
29 using ::testing::Pointwise;
30
31 namespace base {
32
33 namespace {
34
35 // Tests for span(It, StrictNumeric<size_t>) deduction guide. These tests use a
36 // helper function to wrap the static_asserts, as most STL containers don't work
37 // well in a constexpr context. std::array<T, N> does, but base::span has
38 // specific overloads for std::array<T, n>, so that ends up being less helpful
39 // than it would initially appear.
40 //
41 // Another alternative would be to use std::declval, but that would be fairly
42 // verbose.
TestDeductionGuides()43 [[maybe_unused]] void TestDeductionGuides() {
44 // Tests for span(It, EndOrSize) deduction guide.
45 {
46 const std::vector<int> v;
47 static_assert(
48 std::is_same_v<decltype(span(v.cbegin(), v.size())), span<const int>>);
49 static_assert(
50 std::is_same_v<decltype(span(v.begin(), v.size())), span<const int>>);
51 static_assert(
52 std::is_same_v<decltype(span(v.data(), v.size())), span<const int>>);
53 }
54
55 {
56 std::vector<int> v;
57 static_assert(
58 std::is_same_v<decltype(span(v.cbegin(), v.size())), span<const int>>);
59 static_assert(
60 std::is_same_v<decltype(span(v.begin(), v.size())), span<int>>);
61 static_assert(
62 std::is_same_v<decltype(span(v.data(), v.size())), span<int>>);
63 }
64
65 {
66 const std::vector<int> v;
67 static_assert(
68 std::is_same_v<decltype(span(v.cbegin(), v.cend())), span<const int>>);
69 static_assert(
70 std::is_same_v<decltype(span(v.begin(), v.end())), span<const int>>);
71 }
72
73 {
74 std::vector<int> v;
75 static_assert(
76 std::is_same_v<decltype(span(v.cbegin(), v.cend())), span<const int>>);
77 static_assert(
78 std::is_same_v<decltype(span(v.begin(), v.end())), span<int>>);
79 }
80
81 // Tests for span(Range&&) deduction guide.
82 {
83 const int kArray[] = {1, 2, 3};
84 static_assert(std::is_same_v<decltype(span(kArray)), span<const int, 3>>);
85 }
86 {
87 int kArray[] = {1, 2, 3};
88 static_assert(std::is_same_v<decltype(span(kArray)), span<int, 3>>);
89 }
90 // We also deduce an rvalue array to make a fixed-span over const values,
91 // which matches the span<const T> constructor from an array.
92 static_assert(std::is_same_v<decltype(span({1, 2, 3})), span<const int, 3>>);
93
94 static_assert(
95 std::is_same_v<decltype(span(std::declval<std::array<const bool, 3>&>())),
96 span<const bool, 3>>);
97 static_assert(
98 std::is_same_v<decltype(span(std::declval<std::array<bool, 3>&>())),
99 span<bool, 3>>);
100
101 static_assert(
102 std::is_same_v<decltype(span(
103 std::declval<const std::array<const bool, 3>&>())),
104 span<const bool, 3>>);
105 static_assert(
106 std::is_same_v<decltype(span(
107 std::declval<const std::array<const bool, 3>&&>())),
108 span<const bool, 3>>);
109 static_assert(std::is_same_v<
110 decltype(span(std::declval<std::array<const bool, 3>&&>())),
111 span<const bool, 3>>);
112 static_assert(
113 std::is_same_v<decltype(span(std::declval<const std::array<bool, 3>&>())),
114 span<const bool, 3>>);
115 static_assert(std::is_same_v<
116 decltype(span(std::declval<const std::array<bool, 3>&&>())),
117 span<const bool, 3>>);
118 static_assert(
119 std::is_same_v<decltype(span(std::declval<std::array<bool, 3>&&>())),
120 span<const bool, 3>>);
121
122 static_assert(
123 std::is_same_v<decltype(span(std::declval<const std::string&>())),
124 span<const char>>);
125 static_assert(
126 std::is_same_v<decltype(span(std::declval<const std::string&&>())),
127 span<const char>>);
128 static_assert(
129 std::is_same_v<decltype(span(std::declval<std::string&>())), span<char>>);
130 static_assert(std::is_same_v<decltype(span(std::declval<std::string&&>())),
131 span<const char>>);
132 static_assert(
133 std::is_same_v<decltype(span(std::declval<const std::u16string&>())),
134 span<const char16_t>>);
135 static_assert(
136 std::is_same_v<decltype(span(std::declval<const std::u16string&&>())),
137 span<const char16_t>>);
138 static_assert(std::is_same_v<decltype(span(std::declval<std::u16string&>())),
139 span<char16_t>>);
140 static_assert(std::is_same_v<decltype(span(std::declval<std::u16string&&>())),
141 span<const char16_t>>);
142 static_assert(std::is_same_v<
143 decltype(span(std::declval<const std::array<float, 9>&>())),
144 span<const float, 9>>);
145 static_assert(std::is_same_v<
146 decltype(span(std::declval<const std::array<float, 9>&&>())),
147 span<const float, 9>>);
148 static_assert(
149 std::is_same_v<decltype(span(std::declval<std::array<float, 9>&>())),
150 span<float, 9>>);
151 static_assert(
152 std::is_same_v<decltype(span(std::declval<std::array<float, 9>&&>())),
153 span<const float, 9>>);
154 }
155
156 } // namespace
157
TEST(SpanTest,DefaultConstructor)158 TEST(SpanTest, DefaultConstructor) {
159 span<int> dynamic_span;
160 EXPECT_EQ(nullptr, dynamic_span.data());
161 EXPECT_EQ(0u, dynamic_span.size());
162
163 constexpr span<int, 0> static_span;
164 static_assert(nullptr == static_span.data(), "");
165 static_assert(0u == static_span.size(), "");
166 }
167
TEST(SpanTest,ConstructFromDataAndSize)168 TEST(SpanTest, ConstructFromDataAndSize) {
169 constexpr int* kNull = nullptr;
170 constexpr span<int> empty_span(kNull, 0u);
171 EXPECT_TRUE(empty_span.empty());
172 EXPECT_EQ(nullptr, empty_span.data());
173
174 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
175
176 span<int> dynamic_span(vector.data(), vector.size());
177 EXPECT_EQ(vector.data(), dynamic_span.data());
178 EXPECT_EQ(vector.size(), dynamic_span.size());
179
180 for (size_t i = 0; i < dynamic_span.size(); ++i) {
181 EXPECT_EQ(vector[i], dynamic_span[i]);
182 }
183
184 span<int, 6> static_span(vector.data(), vector.size());
185 EXPECT_EQ(vector.data(), static_span.data());
186 EXPECT_EQ(vector.size(), static_span.size());
187
188 for (size_t i = 0; i < static_span.size(); ++i) {
189 EXPECT_EQ(vector[i], static_span[i]);
190 }
191 }
192
TEST(SpanTest,ConstructFromIterAndSize)193 TEST(SpanTest, ConstructFromIterAndSize) {
194 constexpr int* kNull = nullptr;
195 constexpr span<int> empty_span(kNull, 0u);
196 EXPECT_TRUE(empty_span.empty());
197 EXPECT_EQ(nullptr, empty_span.data());
198
199 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
200
201 span<int> dynamic_span(vector.begin(), vector.size());
202 EXPECT_EQ(vector.data(), dynamic_span.data());
203 EXPECT_EQ(vector.size(), dynamic_span.size());
204
205 for (size_t i = 0; i < dynamic_span.size(); ++i) {
206 EXPECT_EQ(vector[i], dynamic_span[i]);
207 }
208
209 span<int, 6> static_span(vector.begin(), vector.size());
210 EXPECT_EQ(vector.data(), static_span.data());
211 EXPECT_EQ(vector.size(), static_span.size());
212
213 for (size_t i = 0; i < static_span.size(); ++i) {
214 EXPECT_EQ(vector[i], static_span[i]);
215 }
216 }
217
TEST(SpanTest,ConstructFromIterPair)218 TEST(SpanTest, ConstructFromIterPair) {
219 constexpr int* kNull = nullptr;
220 constexpr span<int> empty_span(kNull, kNull);
221 EXPECT_TRUE(empty_span.empty());
222 EXPECT_EQ(nullptr, empty_span.data());
223
224 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
225
226 span<int> dynamic_span(vector.begin(), vector.begin() + vector.size() / 2);
227 EXPECT_EQ(vector.data(), dynamic_span.data());
228 EXPECT_EQ(vector.size() / 2, dynamic_span.size());
229
230 for (size_t i = 0; i < dynamic_span.size(); ++i) {
231 EXPECT_EQ(vector[i], dynamic_span[i]);
232 }
233
234 span<int, 3> static_span(vector.begin(), vector.begin() + vector.size() / 2);
235 EXPECT_EQ(vector.data(), static_span.data());
236 EXPECT_EQ(vector.size() / 2, static_span.size());
237
238 for (size_t i = 0; i < static_span.size(); ++i) {
239 EXPECT_EQ(vector[i], static_span[i]);
240 }
241 }
242
TEST(SpanTest,AllowedConversionsFromStdArray)243 TEST(SpanTest, AllowedConversionsFromStdArray) {
244 // In the following assertions we use std::is_convertible_v<From, To>, which
245 // for non-void types is equivalent to checking whether the following
246 // expression is well-formed:
247 //
248 // T obj = std::declval<From>();
249 //
250 // In particular we are checking whether From is implicitly convertible to To,
251 // which also implies that To is explicitly constructible from From.
252 static_assert(
253 std::is_convertible_v<std::array<int, 3>&, base::span<int>>,
254 "Error: l-value reference to std::array<int> should be convertible to "
255 "base::span<int> with dynamic extent.");
256 static_assert(
257 std::is_convertible_v<std::array<int, 3>&, base::span<int, 3>>,
258 "Error: l-value reference to std::array<int> should be convertible to "
259 "base::span<int> with the same static extent.");
260 static_assert(
261 std::is_convertible_v<std::array<int, 3>&, base::span<const int>>,
262 "Error: l-value reference to std::array<int> should be convertible to "
263 "base::span<const int> with dynamic extent.");
264 static_assert(
265 std::is_convertible_v<std::array<int, 3>&, base::span<const int, 3>>,
266 "Error: l-value reference to std::array<int> should be convertible to "
267 "base::span<const int> with the same static extent.");
268 static_assert(
269 std::is_convertible_v<const std::array<int, 3>&, base::span<const int>>,
270 "Error: const l-value reference to std::array<int> should be "
271 "convertible to base::span<const int> with dynamic extent.");
272 static_assert(
273 std::is_convertible_v<const std::array<int, 3>&,
274 base::span<const int, 3>>,
275 "Error: const l-value reference to std::array<int> should be convertible "
276 "to base::span<const int> with the same static extent.");
277 static_assert(
278 std::is_convertible_v<std::array<const int, 3>&, base::span<const int>>,
279 "Error: l-value reference to std::array<const int> should be "
280 "convertible to base::span<const int> with dynamic extent.");
281 static_assert(
282 std::is_convertible_v<std::array<const int, 3>&,
283 base::span<const int, 3>>,
284 "Error: l-value reference to std::array<const int> should be convertible "
285 "to base::span<const int> with the same static extent.");
286 static_assert(
287 std::is_convertible_v<const std::array<const int, 3>&,
288 base::span<const int>>,
289 "Error: const l-value reference to std::array<const int> should be "
290 "convertible to base::span<const int> with dynamic extent.");
291 static_assert(
292 std::is_convertible_v<const std::array<const int, 3>&,
293 base::span<const int, 3>>,
294 "Error: const l-value reference to std::array<const int> should be "
295 "convertible to base::span<const int> with the same static extent.");
296 }
297
TEST(SpanTest,DisallowedConstructionsFromStdArray)298 TEST(SpanTest, DisallowedConstructionsFromStdArray) {
299 // In the following assertions we use !std::is_constructible_v<T, Args>, which
300 // is equivalent to checking whether the following expression is malformed:
301 //
302 // T obj(std::declval<Args>()...);
303 //
304 // In particular we are checking that T is not explicitly constructible from
305 // Args, which also implies that T is not implicitly constructible from Args
306 // as well.
307 static_assert(
308 !std::is_constructible_v<base::span<int>, const std::array<int, 3>&>,
309 "Error: base::span<int> with dynamic extent should not be constructible "
310 "from const l-value reference to std::array<int>");
311
312 static_assert(
313 !std::is_constructible_v<base::span<int>, std::array<const int, 3>&>,
314 "Error: base::span<int> with dynamic extent should not be constructible "
315 "from l-value reference to std::array<const int>");
316
317 static_assert(
318 !std::is_constructible_v<base::span<int>,
319 const std::array<const int, 3>&>,
320 "Error: base::span<int> with dynamic extent should not be constructible "
321 "const from l-value reference to std::array<const int>");
322
323 static_assert(
324 !std::is_constructible_v<base::span<int, 2>, std::array<int, 3>&>,
325 "Error: base::span<int> with static extent should not be constructible "
326 "from l-value reference to std::array<int> with different extent");
327
328 static_assert(
329 !std::is_constructible_v<base::span<int, 4>, std::array<int, 3>&>,
330 "Error: base::span<int> with dynamic extent should not be constructible "
331 "from l-value reference to std::array<int> with different extent");
332
333 static_assert(
334 !std::is_constructible_v<base::span<int>, std::array<bool, 3>&>,
335 "Error: base::span<int> with dynamic extent should not be constructible "
336 "from l-value reference to std::array<bool>");
337 }
338
TEST(SpanTest,ConstructFromConstexprArray)339 TEST(SpanTest, ConstructFromConstexprArray) {
340 static constexpr int kArray[] = {5, 4, 3, 2, 1};
341
342 constexpr span<const int> dynamic_span(kArray);
343 static_assert(kArray == dynamic_span.data(), "");
344 static_assert(std::size(kArray) == dynamic_span.size(), "");
345
346 static_assert(kArray[0] == dynamic_span[0], "");
347 static_assert(kArray[1] == dynamic_span[1], "");
348 static_assert(kArray[2] == dynamic_span[2], "");
349 static_assert(kArray[3] == dynamic_span[3], "");
350 static_assert(kArray[4] == dynamic_span[4], "");
351
352 constexpr span<const int, std::size(kArray)> static_span(kArray);
353 static_assert(kArray == static_span.data(), "");
354 static_assert(std::size(kArray) == static_span.size(), "");
355
356 static_assert(kArray[0] == static_span[0], "");
357 static_assert(kArray[1] == static_span[1], "");
358 static_assert(kArray[2] == static_span[2], "");
359 static_assert(kArray[3] == static_span[3], "");
360 static_assert(kArray[4] == static_span[4], "");
361 }
362
TEST(SpanTest,ConstructFromArray)363 TEST(SpanTest, ConstructFromArray) {
364 int array[] = {5, 4, 3, 2, 1};
365
366 span<const int> const_span = array;
367 EXPECT_EQ(array, const_span.data());
368 EXPECT_EQ(std::size(array), const_span.size());
369 for (size_t i = 0; i < const_span.size(); ++i) {
370 EXPECT_EQ(array[i], const_span[i]);
371 }
372
373 span<int> dynamic_span = array;
374 EXPECT_EQ(array, dynamic_span.data());
375 EXPECT_EQ(std::size(array), dynamic_span.size());
376 for (size_t i = 0; i < dynamic_span.size(); ++i) {
377 EXPECT_EQ(array[i], dynamic_span[i]);
378 }
379
380 span<int, std::size(array)> static_span = array;
381 EXPECT_EQ(array, static_span.data());
382 EXPECT_EQ(std::size(array), static_span.size());
383 for (size_t i = 0; i < static_span.size(); ++i) {
384 EXPECT_EQ(array[i], static_span[i]);
385 }
386
387 [](span<const int> dynamic_span) {
388 EXPECT_EQ(dynamic_span.size(), 5u);
389 EXPECT_EQ(dynamic_span[0u], 5);
390 EXPECT_EQ(dynamic_span[4u], 1);
391 }({{5, 4, 3, 2, 1}});
392
393 [](span<const int, 5u> static_span) {
394 EXPECT_EQ(static_span.size(), 5u);
395 EXPECT_EQ(static_span[0u], 5);
396 EXPECT_EQ(static_span[4u], 1);
397 }({{5, 4, 3, 2, 1}});
398 }
399
TEST(SpanTest,ConstructFromVolatileArray)400 TEST(SpanTest, ConstructFromVolatileArray) {
401 static volatile int array[] = {5, 4, 3, 2, 1};
402
403 span<const volatile int> const_span(array);
404 static_assert(std::is_same_v<decltype(&const_span[1]), const volatile int*>);
405 static_assert(
406 std::is_same_v<decltype(const_span.data()), const volatile int*>);
407 EXPECT_EQ(array, const_span.data());
408 EXPECT_EQ(std::size(array), const_span.size());
409 for (size_t i = 0; i < const_span.size(); ++i) {
410 EXPECT_EQ(array[i], const_span[i]);
411 }
412
413 span<volatile int> dynamic_span(array);
414 static_assert(std::is_same_v<decltype(&dynamic_span[1]), volatile int*>);
415 static_assert(std::is_same_v<decltype(dynamic_span.data()), volatile int*>);
416 EXPECT_EQ(array, dynamic_span.data());
417 EXPECT_EQ(std::size(array), dynamic_span.size());
418 for (size_t i = 0; i < dynamic_span.size(); ++i) {
419 EXPECT_EQ(array[i], dynamic_span[i]);
420 }
421
422 span<volatile int, std::size(array)> static_span(array);
423 static_assert(std::is_same_v<decltype(&static_span[1]), volatile int*>);
424 static_assert(std::is_same_v<decltype(static_span.data()), volatile int*>);
425 EXPECT_EQ(array, static_span.data());
426 EXPECT_EQ(std::size(array), static_span.size());
427 for (size_t i = 0; i < static_span.size(); ++i) {
428 EXPECT_EQ(array[i], static_span[i]);
429 }
430 }
431
TEST(SpanTest,ConstructFromStdArray)432 TEST(SpanTest, ConstructFromStdArray) {
433 // Note: Constructing a constexpr span from a constexpr std::array does not
434 // work prior to C++17 due to non-constexpr std::array::data.
435 std::array<int, 5> array = {{5, 4, 3, 2, 1}};
436
437 span<const int> const_span(array);
438 EXPECT_EQ(array.data(), const_span.data());
439 EXPECT_EQ(array.size(), const_span.size());
440 for (size_t i = 0; i < const_span.size(); ++i) {
441 EXPECT_EQ(array[i], const_span[i]);
442 }
443
444 span<int> dynamic_span(array);
445 EXPECT_EQ(array.data(), dynamic_span.data());
446 EXPECT_EQ(array.size(), dynamic_span.size());
447 for (size_t i = 0; i < dynamic_span.size(); ++i) {
448 EXPECT_EQ(array[i], dynamic_span[i]);
449 }
450
451 span<int, std::size(array)> static_span(array);
452 EXPECT_EQ(array.data(), static_span.data());
453 EXPECT_EQ(array.size(), static_span.size());
454 for (size_t i = 0; i < static_span.size(); ++i) {
455 EXPECT_EQ(array[i], static_span[i]);
456 }
457 }
458
TEST(SpanTest,ConstructFromInitializerList)459 TEST(SpanTest, ConstructFromInitializerList) {
460 std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
461
462 span<const int> const_span(il);
463 EXPECT_EQ(il.begin(), const_span.data());
464 EXPECT_EQ(il.size(), const_span.size());
465
466 for (size_t i = 0; i < const_span.size(); ++i) {
467 EXPECT_EQ(il.begin()[i], const_span[i]);
468 }
469
470 span<const int, 6> static_span(il.begin(), il.end());
471 EXPECT_EQ(il.begin(), static_span.data());
472 EXPECT_EQ(il.size(), static_span.size());
473
474 for (size_t i = 0; i < static_span.size(); ++i) {
475 EXPECT_EQ(il.begin()[i], static_span[i]);
476 }
477 }
478
TEST(SpanTest,ConstructFromStdString)479 TEST(SpanTest, ConstructFromStdString) {
480 std::string str = "foobar";
481
482 span<const char> const_span(str);
483 EXPECT_EQ(str.data(), const_span.data());
484 EXPECT_EQ(str.size(), const_span.size());
485
486 for (size_t i = 0; i < const_span.size(); ++i) {
487 EXPECT_EQ(str[i], const_span[i]);
488 }
489
490 span<char> dynamic_span(str);
491 EXPECT_EQ(str.data(), dynamic_span.data());
492 EXPECT_EQ(str.size(), dynamic_span.size());
493
494 for (size_t i = 0; i < dynamic_span.size(); ++i) {
495 EXPECT_EQ(str[i], dynamic_span[i]);
496 }
497
498 span<char, 6> static_span(data(str), str.size());
499 EXPECT_EQ(str.data(), static_span.data());
500 EXPECT_EQ(str.size(), static_span.size());
501
502 for (size_t i = 0; i < static_span.size(); ++i) {
503 EXPECT_EQ(str[i], static_span[i]);
504 }
505 }
506
TEST(SpanTest,ConstructFromConstContainer)507 TEST(SpanTest, ConstructFromConstContainer) {
508 const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
509
510 span<const int> const_span(vector);
511 EXPECT_EQ(vector.data(), const_span.data());
512 EXPECT_EQ(vector.size(), const_span.size());
513
514 for (size_t i = 0; i < const_span.size(); ++i) {
515 EXPECT_EQ(vector[i], const_span[i]);
516 }
517
518 span<const int, 6> static_span(vector.data(), vector.size());
519 EXPECT_EQ(vector.data(), static_span.data());
520 EXPECT_EQ(vector.size(), static_span.size());
521
522 for (size_t i = 0; i < static_span.size(); ++i) {
523 EXPECT_EQ(vector[i], static_span[i]);
524 }
525 }
526
TEST(SpanTest,ConstructFromContainer)527 TEST(SpanTest, ConstructFromContainer) {
528 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
529
530 span<const int> const_span(vector);
531 EXPECT_EQ(vector.data(), const_span.data());
532 EXPECT_EQ(vector.size(), const_span.size());
533
534 for (size_t i = 0; i < const_span.size(); ++i) {
535 EXPECT_EQ(vector[i], const_span[i]);
536 }
537
538 span<int> dynamic_span(vector);
539 EXPECT_EQ(vector.data(), dynamic_span.data());
540 EXPECT_EQ(vector.size(), dynamic_span.size());
541
542 for (size_t i = 0; i < dynamic_span.size(); ++i) {
543 EXPECT_EQ(vector[i], dynamic_span[i]);
544 }
545
546 span<int, 6> static_span(vector.data(), vector.size());
547 EXPECT_EQ(vector.data(), static_span.data());
548 EXPECT_EQ(vector.size(), static_span.size());
549
550 for (size_t i = 0; i < static_span.size(); ++i) {
551 EXPECT_EQ(vector[i], static_span[i]);
552 }
553 }
554
TEST(SpanTest,ConstructFromRange)555 TEST(SpanTest, ConstructFromRange) {
556 struct Range {
557 using iterator = base::span<const int>::iterator;
558 iterator begin() const { return base::span(arr_).begin(); }
559 iterator end() const { return base::span(arr_).end(); }
560
561 std::array<const int, 3u> arr_ = {1, 2, 3};
562 };
563 static_assert(std::ranges::contiguous_range<Range>);
564 {
565 Range r;
566 auto s = base::span(r);
567 static_assert(std::same_as<decltype(s), base::span<const int>>);
568 EXPECT_EQ(s, base::span({1, 2, 3}));
569 }
570
571 struct LegacyRange {
572 const int* data() const { return arr_.data(); }
573 size_t size() const { return arr_.size(); }
574
575 std::array<const int, 3u> arr_ = {1, 2, 3};
576 };
577 static_assert(!std::ranges::contiguous_range<LegacyRange>);
578 static_assert(base::internal::LegacyRange<LegacyRange>);
579 {
580 LegacyRange r;
581 auto s = base::span(r);
582 static_assert(std::same_as<decltype(s), base::span<const int>>);
583 EXPECT_EQ(s, base::span({1, 2, 3}));
584 }
585 }
586
TEST(SpanTest,FromRefOfMutableStackVariable)587 TEST(SpanTest, FromRefOfMutableStackVariable) {
588 int x = 123;
589
590 auto s = span_from_ref(x);
591 static_assert(std::is_same_v<decltype(s), span<int, 1u>>);
592 EXPECT_EQ(&x, s.data());
593 EXPECT_EQ(1u, s.size());
594 EXPECT_EQ(sizeof(int), s.size_bytes());
595 EXPECT_EQ(123, s[0]);
596
597 s[0] = 456;
598 EXPECT_EQ(456, x);
599 EXPECT_EQ(456, s[0]);
600
601 auto b = byte_span_from_ref(x);
602 static_assert(std::is_same_v<decltype(b), span<uint8_t, sizeof(int)>>);
603 EXPECT_EQ(reinterpret_cast<uint8_t*>(&x), b.data());
604 EXPECT_EQ(sizeof(int), b.size());
605 }
606
TEST(SpanTest,FromRefOfConstStackVariable)607 TEST(SpanTest, FromRefOfConstStackVariable) {
608 const int x = 123;
609
610 auto s = span_from_ref(x);
611 static_assert(std::is_same_v<decltype(s), span<const int, 1u>>);
612 EXPECT_EQ(&x, s.data());
613 EXPECT_EQ(1u, s.size());
614 EXPECT_EQ(sizeof(int), s.size_bytes());
615 EXPECT_EQ(123, s[0]);
616
617 auto b = byte_span_from_ref(x);
618 static_assert(std::is_same_v<decltype(b), span<const uint8_t, sizeof(int)>>);
619 EXPECT_EQ(reinterpret_cast<const uint8_t*>(&x), b.data());
620 EXPECT_EQ(sizeof(int), b.size());
621 }
622
TEST(SpanTest,FromCString)623 TEST(SpanTest, FromCString) {
624 // No terminating null, size known at compile time.
625 {
626 auto s = base::span_from_cstring("hello");
627 static_assert(std::same_as<decltype(s), span<const char, 5u>>);
628 EXPECT_EQ(s[0u], 'h');
629 EXPECT_EQ(s[1u], 'e');
630 EXPECT_EQ(s[4u], 'o');
631 }
632 // No terminating null, size not known at compile time. string_view loses
633 // the size.
634 {
635 auto s = base::span(std::string_view("hello"));
636 static_assert(std::same_as<decltype(s), span<const char>>);
637 EXPECT_EQ(s[0u], 'h');
638 EXPECT_EQ(s[1u], 'e');
639 EXPECT_EQ(s[4u], 'o');
640 EXPECT_EQ(s.size(), 5u);
641 }
642 // Includes the terminating null, size known at compile time.
643 {
644 auto s = base::span("hello");
645 static_assert(std::same_as<decltype(s), span<const char, 6u>>);
646 EXPECT_EQ(s[0u], 'h');
647 EXPECT_EQ(s[1u], 'e');
648 EXPECT_EQ(s[4u], 'o');
649 EXPECT_EQ(s[5u], '\0');
650 }
651
652 // No terminating null, size known at compile time. Converted to a span of
653 // uint8_t bytes.
654 {
655 auto s = base::byte_span_from_cstring("hello");
656 static_assert(std::same_as<decltype(s), span<const uint8_t, 5u>>);
657 EXPECT_EQ(s[0u], 'h');
658 EXPECT_EQ(s[1u], 'e');
659 EXPECT_EQ(s[4u], 'o');
660 }
661 }
662
TEST(SpanTest,ConvertNonConstIntegralToConst)663 TEST(SpanTest, ConvertNonConstIntegralToConst) {
664 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
665
666 span<int> int_span(vector.data(), vector.size());
667 span<const int> const_span(int_span);
668 EXPECT_EQ(int_span.size(), const_span.size());
669
670 EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
671
672 span<int, 6> static_int_span(vector.data(), vector.size());
673 span<const int, 6> static_const_span(static_int_span);
674 EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
675 }
676
TEST(SpanTest,ConvertNonConstPointerToConst)677 TEST(SpanTest, ConvertNonConstPointerToConst) {
678 auto a = std::make_unique<int>(11);
679 auto b = std::make_unique<int>(22);
680 auto c = std::make_unique<int>(33);
681 std::vector<int*> vector = {a.get(), b.get(), c.get()};
682
683 span<int*> non_const_pointer_span(vector);
684 EXPECT_THAT(non_const_pointer_span, Pointwise(Eq(), vector));
685 span<int* const> const_pointer_span(non_const_pointer_span);
686 EXPECT_THAT(const_pointer_span, Pointwise(Eq(), non_const_pointer_span));
687 // Note: no test for conversion from span<int> to span<const int*>, since that
688 // would imply a conversion from int** to const int**, which is unsafe.
689 //
690 // Note: no test for conversion from span<int*> to span<const int* const>,
691 // due to CWG Defect 330:
692 // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
693
694 span<int*, 3> static_non_const_pointer_span(vector.data(), vector.size());
695 EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
696 span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
697 EXPECT_THAT(static_const_pointer_span,
698 Pointwise(Eq(), static_non_const_pointer_span));
699 }
700
TEST(SpanTest,ConvertBetweenEquivalentTypes)701 TEST(SpanTest, ConvertBetweenEquivalentTypes) {
702 std::vector<int32_t> vector = {2, 4, 8, 16, 32};
703
704 span<int32_t> int32_t_span(vector);
705 span<int> converted_span(int32_t_span);
706 EXPECT_EQ(int32_t_span.data(), converted_span.data());
707 EXPECT_EQ(int32_t_span.size(), converted_span.size());
708
709 span<int32_t, 5> static_int32_t_span(vector.data(), vector.size());
710 span<int, 5> static_converted_span(static_int32_t_span);
711 EXPECT_EQ(static_int32_t_span.data(), static_converted_span.data());
712 EXPECT_EQ(static_int32_t_span.size(), static_converted_span.size());
713 }
714
TEST(SpanTest,TemplatedFirst)715 TEST(SpanTest, TemplatedFirst) {
716 static constexpr int array[] = {1, 2, 3};
717 constexpr span<const int, 3> span(array);
718
719 {
720 constexpr auto subspan = span.first<0>();
721 static_assert(span.data() == subspan.data(), "");
722 static_assert(0u == subspan.size(), "");
723 static_assert(0u == decltype(subspan)::extent, "");
724 }
725
726 {
727 constexpr auto subspan = span.first<1>();
728 static_assert(span.data() == subspan.data(), "");
729 static_assert(1u == subspan.size(), "");
730 static_assert(1u == decltype(subspan)::extent, "");
731 static_assert(1 == subspan[0], "");
732 }
733
734 {
735 constexpr auto subspan = span.first<2>();
736 static_assert(span.data() == subspan.data(), "");
737 static_assert(2u == subspan.size(), "");
738 static_assert(2u == decltype(subspan)::extent, "");
739 static_assert(1 == subspan[0], "");
740 static_assert(2 == subspan[1], "");
741 }
742
743 {
744 constexpr auto subspan = span.first<3>();
745 static_assert(span.data() == subspan.data(), "");
746 static_assert(3u == subspan.size(), "");
747 static_assert(3u == decltype(subspan)::extent, "");
748 static_assert(1 == subspan[0], "");
749 static_assert(2 == subspan[1], "");
750 static_assert(3 == subspan[2], "");
751 }
752 }
753
TEST(SpanTest,TemplatedLast)754 TEST(SpanTest, TemplatedLast) {
755 static constexpr int array[] = {1, 2, 3};
756 constexpr span<const int, 3> span(array);
757
758 {
759 constexpr auto subspan = span.last<0>();
760 static_assert(span.data() + 3 == subspan.data(), "");
761 static_assert(0u == subspan.size(), "");
762 static_assert(0u == decltype(subspan)::extent, "");
763 }
764
765 {
766 constexpr auto subspan = span.last<1>();
767 static_assert(span.data() + 2 == subspan.data(), "");
768 static_assert(1u == subspan.size(), "");
769 static_assert(1u == decltype(subspan)::extent, "");
770 static_assert(3 == subspan[0], "");
771 }
772
773 {
774 constexpr auto subspan = span.last<2>();
775 static_assert(span.data() + 1 == subspan.data(), "");
776 static_assert(2u == subspan.size(), "");
777 static_assert(2u == decltype(subspan)::extent, "");
778 static_assert(2 == subspan[0], "");
779 static_assert(3 == subspan[1], "");
780 }
781
782 {
783 constexpr auto subspan = span.last<3>();
784 static_assert(span.data() == subspan.data(), "");
785 static_assert(3u == subspan.size(), "");
786 static_assert(3u == decltype(subspan)::extent, "");
787 static_assert(1 == subspan[0], "");
788 static_assert(2 == subspan[1], "");
789 static_assert(3 == subspan[2], "");
790 }
791 }
792
TEST(SpanTest,TemplatedSubspan)793 TEST(SpanTest, TemplatedSubspan) {
794 static constexpr int array[] = {1, 2, 3};
795 constexpr span<const int, 3> span(array);
796
797 {
798 constexpr auto subspan = span.subspan<0>();
799 static_assert(span.data() == subspan.data(), "");
800 static_assert(3u == subspan.size(), "");
801 static_assert(3u == decltype(subspan)::extent, "");
802 static_assert(1 == subspan[0], "");
803 static_assert(2 == subspan[1], "");
804 static_assert(3 == subspan[2], "");
805 }
806
807 {
808 constexpr auto subspan = span.subspan<1>();
809 static_assert(span.data() + 1 == subspan.data(), "");
810 static_assert(2u == subspan.size(), "");
811 static_assert(2u == decltype(subspan)::extent, "");
812 static_assert(2 == subspan[0], "");
813 static_assert(3 == subspan[1], "");
814 }
815
816 {
817 constexpr auto subspan = span.subspan<2>();
818 static_assert(span.data() + 2 == subspan.data(), "");
819 static_assert(1u == subspan.size(), "");
820 static_assert(1u == decltype(subspan)::extent, "");
821 static_assert(3 == subspan[0], "");
822 }
823
824 {
825 constexpr auto subspan = span.subspan<3>();
826 static_assert(span.data() + 3 == subspan.data(), "");
827 static_assert(0u == subspan.size(), "");
828 static_assert(0u == decltype(subspan)::extent, "");
829 }
830
831 {
832 constexpr auto subspan = span.subspan<0, 0>();
833 static_assert(span.data() == subspan.data(), "");
834 static_assert(0u == subspan.size(), "");
835 static_assert(0u == decltype(subspan)::extent, "");
836 }
837
838 {
839 constexpr auto subspan = span.subspan<1, 0>();
840 static_assert(span.data() + 1 == subspan.data(), "");
841 static_assert(0u == subspan.size(), "");
842 static_assert(0u == decltype(subspan)::extent, "");
843 }
844
845 {
846 constexpr auto subspan = span.subspan<2, 0>();
847 static_assert(span.data() + 2 == subspan.data(), "");
848 static_assert(0u == subspan.size(), "");
849 static_assert(0u == decltype(subspan)::extent, "");
850 }
851
852 {
853 constexpr auto subspan = span.subspan<0, 1>();
854 static_assert(span.data() == subspan.data(), "");
855 static_assert(1u == subspan.size(), "");
856 static_assert(1u == decltype(subspan)::extent, "");
857 static_assert(1 == subspan[0], "");
858 }
859
860 {
861 constexpr auto subspan = span.subspan<1, 1>();
862 static_assert(span.data() + 1 == subspan.data(), "");
863 static_assert(1u == subspan.size(), "");
864 static_assert(1u == decltype(subspan)::extent, "");
865 static_assert(2 == subspan[0], "");
866 }
867
868 {
869 constexpr auto subspan = span.subspan<2, 1>();
870 static_assert(span.data() + 2 == subspan.data(), "");
871 static_assert(1u == subspan.size(), "");
872 static_assert(1u == decltype(subspan)::extent, "");
873 static_assert(3 == subspan[0], "");
874 }
875
876 {
877 constexpr auto subspan = span.subspan<0, 2>();
878 static_assert(span.data() == subspan.data(), "");
879 static_assert(2u == subspan.size(), "");
880 static_assert(2u == decltype(subspan)::extent, "");
881 static_assert(1 == subspan[0], "");
882 static_assert(2 == subspan[1], "");
883 }
884
885 {
886 constexpr auto subspan = span.subspan<1, 2>();
887 static_assert(span.data() + 1 == subspan.data(), "");
888 static_assert(2u == subspan.size(), "");
889 static_assert(2u == decltype(subspan)::extent, "");
890 static_assert(2 == subspan[0], "");
891 static_assert(3 == subspan[1], "");
892 }
893
894 {
895 constexpr auto subspan = span.subspan<0, 3>();
896 static_assert(span.data() == subspan.data(), "");
897 static_assert(3u == subspan.size(), "");
898 static_assert(3u == decltype(subspan)::extent, "");
899 static_assert(1 == subspan[0], "");
900 static_assert(2 == subspan[1], "");
901 static_assert(3 == subspan[2], "");
902 }
903 }
904
TEST(SpanTest,SubscriptedBeginIterator)905 TEST(SpanTest, SubscriptedBeginIterator) {
906 int array[] = {1, 2, 3};
907 span<const int> const_span(array);
908 for (size_t i = 0; i < const_span.size(); ++i) {
909 EXPECT_EQ(array[i], const_span.begin()[i]);
910 }
911
912 span<int> mutable_span(array);
913 for (size_t i = 0; i < mutable_span.size(); ++i) {
914 EXPECT_EQ(array[i], mutable_span.begin()[i]);
915 }
916 }
917
TEST(SpanTest,TemplatedFirstOnDynamicSpan)918 TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
919 int array[] = {1, 2, 3};
920 span<const int> span(array);
921
922 {
923 auto subspan = span.first<0>();
924 EXPECT_EQ(span.data(), subspan.data());
925 EXPECT_EQ(0u, subspan.size());
926 static_assert(0u == decltype(subspan)::extent, "");
927 }
928
929 {
930 auto subspan = span.first<1>();
931 EXPECT_EQ(span.data(), subspan.data());
932 EXPECT_EQ(1u, subspan.size());
933 static_assert(1u == decltype(subspan)::extent, "");
934 EXPECT_EQ(1, subspan[0]);
935 }
936
937 {
938 auto subspan = span.first<2>();
939 EXPECT_EQ(span.data(), subspan.data());
940 EXPECT_EQ(2u, subspan.size());
941 static_assert(2u == decltype(subspan)::extent, "");
942 EXPECT_EQ(1, subspan[0]);
943 EXPECT_EQ(2, subspan[1]);
944 }
945
946 {
947 auto subspan = span.first<3>();
948 EXPECT_EQ(span.data(), subspan.data());
949 EXPECT_EQ(3u, subspan.size());
950 static_assert(3u == decltype(subspan)::extent, "");
951 EXPECT_EQ(1, subspan[0]);
952 EXPECT_EQ(2, subspan[1]);
953 EXPECT_EQ(3, subspan[2]);
954 }
955 }
956
TEST(SpanTest,TemplatedLastOnDynamicSpan)957 TEST(SpanTest, TemplatedLastOnDynamicSpan) {
958 int array[] = {1, 2, 3};
959 span<int> span(array);
960
961 {
962 auto subspan = span.last<0>();
963 EXPECT_EQ(span.data() + 3, subspan.data());
964 EXPECT_EQ(0u, subspan.size());
965 static_assert(0u == decltype(subspan)::extent, "");
966 }
967
968 {
969 auto subspan = span.last<1>();
970 EXPECT_EQ(span.data() + 2, subspan.data());
971 EXPECT_EQ(1u, subspan.size());
972 static_assert(1u == decltype(subspan)::extent, "");
973 EXPECT_EQ(3, subspan[0]);
974 }
975
976 {
977 auto subspan = span.last<2>();
978 EXPECT_EQ(span.data() + 1, subspan.data());
979 EXPECT_EQ(2u, subspan.size());
980 static_assert(2u == decltype(subspan)::extent, "");
981 EXPECT_EQ(2, subspan[0]);
982 EXPECT_EQ(3, subspan[1]);
983 }
984
985 {
986 auto subspan = span.last<3>();
987 EXPECT_EQ(span.data(), subspan.data());
988 EXPECT_EQ(3u, subspan.size());
989 static_assert(3u == decltype(subspan)::extent, "");
990 EXPECT_EQ(1, subspan[0]);
991 EXPECT_EQ(2, subspan[1]);
992 EXPECT_EQ(3, subspan[2]);
993 }
994 }
995
TEST(SpanTest,TemplatedSubspanFromDynamicSpan)996 TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
997 int array[] = {1, 2, 3};
998 span<int, 3> span(array);
999
1000 {
1001 auto subspan = span.subspan<0>();
1002 EXPECT_EQ(span.data(), subspan.data());
1003 static_assert(3u == decltype(subspan)::extent, "");
1004 EXPECT_EQ(3u, subspan.size());
1005 EXPECT_EQ(1, subspan[0]);
1006 EXPECT_EQ(2, subspan[1]);
1007 EXPECT_EQ(3, subspan[2]);
1008 }
1009
1010 {
1011 auto subspan = span.subspan<1>();
1012 EXPECT_EQ(span.data() + 1, subspan.data());
1013 EXPECT_EQ(2u, subspan.size());
1014 static_assert(2u == decltype(subspan)::extent, "");
1015 EXPECT_EQ(2, subspan[0]);
1016 EXPECT_EQ(3, subspan[1]);
1017 }
1018
1019 {
1020 auto subspan = span.subspan<2>();
1021 EXPECT_EQ(span.data() + 2, subspan.data());
1022 EXPECT_EQ(1u, subspan.size());
1023 static_assert(1u == decltype(subspan)::extent, "");
1024 EXPECT_EQ(3, subspan[0]);
1025 }
1026
1027 {
1028 auto subspan = span.subspan<3>();
1029 EXPECT_EQ(span.data() + 3, subspan.data());
1030 EXPECT_EQ(0u, subspan.size());
1031 static_assert(0u == decltype(subspan)::extent, "");
1032 }
1033
1034 {
1035 auto subspan = span.subspan<0, 0>();
1036 EXPECT_EQ(span.data(), subspan.data());
1037 EXPECT_EQ(0u, subspan.size());
1038 static_assert(0u == decltype(subspan)::extent, "");
1039 }
1040
1041 {
1042 auto subspan = span.subspan<1, 0>();
1043 EXPECT_EQ(span.data() + 1, subspan.data());
1044 EXPECT_EQ(0u, subspan.size());
1045 static_assert(0u == decltype(subspan)::extent, "");
1046 }
1047
1048 {
1049 auto subspan = span.subspan<2, 0>();
1050 EXPECT_EQ(span.data() + 2, subspan.data());
1051 EXPECT_EQ(0u, subspan.size());
1052 static_assert(0u == decltype(subspan)::extent, "");
1053 }
1054
1055 {
1056 auto subspan = span.subspan<0, 1>();
1057 EXPECT_EQ(span.data(), subspan.data());
1058 EXPECT_EQ(1u, subspan.size());
1059 static_assert(1u == decltype(subspan)::extent, "");
1060 EXPECT_EQ(1, subspan[0]);
1061 }
1062
1063 {
1064 auto subspan = span.subspan<1, 1>();
1065 EXPECT_EQ(span.data() + 1, subspan.data());
1066 EXPECT_EQ(1u, subspan.size());
1067 static_assert(1u == decltype(subspan)::extent, "");
1068 EXPECT_EQ(2, subspan[0]);
1069 }
1070
1071 {
1072 auto subspan = span.subspan<2, 1>();
1073 EXPECT_EQ(span.data() + 2, subspan.data());
1074 EXPECT_EQ(1u, subspan.size());
1075 static_assert(1u == decltype(subspan)::extent, "");
1076 EXPECT_EQ(3, subspan[0]);
1077 }
1078
1079 {
1080 auto subspan = span.subspan<0, 2>();
1081 EXPECT_EQ(span.data(), subspan.data());
1082 EXPECT_EQ(2u, subspan.size());
1083 static_assert(2u == decltype(subspan)::extent, "");
1084 EXPECT_EQ(1, subspan[0]);
1085 EXPECT_EQ(2, subspan[1]);
1086 }
1087
1088 {
1089 auto subspan = span.subspan<1, 2>();
1090 EXPECT_EQ(span.data() + 1, subspan.data());
1091 EXPECT_EQ(2u, subspan.size());
1092 static_assert(2u == decltype(subspan)::extent, "");
1093 EXPECT_EQ(2, subspan[0]);
1094 EXPECT_EQ(3, subspan[1]);
1095 }
1096
1097 {
1098 auto subspan = span.subspan<0, 3>();
1099 EXPECT_EQ(span.data(), subspan.data());
1100 EXPECT_EQ(3u, subspan.size());
1101 static_assert(3u == decltype(subspan)::extent, "");
1102 EXPECT_EQ(1, subspan[0]);
1103 EXPECT_EQ(2, subspan[1]);
1104 EXPECT_EQ(3, subspan[2]);
1105 }
1106 }
1107
TEST(SpanTest,First)1108 TEST(SpanTest, First) {
1109 int array[] = {1, 2, 3};
1110 span<int> span(array);
1111
1112 {
1113 auto subspan = span.first(0u);
1114 EXPECT_EQ(span.data(), subspan.data());
1115 EXPECT_EQ(0u, subspan.size());
1116 }
1117
1118 {
1119 auto subspan = span.first(1u);
1120 EXPECT_EQ(span.data(), subspan.data());
1121 EXPECT_EQ(1u, subspan.size());
1122 EXPECT_EQ(1, subspan[0]);
1123 }
1124
1125 {
1126 auto subspan = span.first(2u);
1127 EXPECT_EQ(span.data(), subspan.data());
1128 EXPECT_EQ(2u, subspan.size());
1129 EXPECT_EQ(1, subspan[0]);
1130 EXPECT_EQ(2, subspan[1]);
1131 }
1132
1133 {
1134 auto subspan = span.first(3u);
1135 EXPECT_EQ(span.data(), subspan.data());
1136 EXPECT_EQ(3u, subspan.size());
1137 EXPECT_EQ(1, subspan[0]);
1138 EXPECT_EQ(2, subspan[1]);
1139 EXPECT_EQ(3, subspan[2]);
1140 }
1141 }
1142
TEST(SpanTest,Last)1143 TEST(SpanTest, Last) {
1144 int array[] = {1, 2, 3};
1145 span<int> span(array);
1146
1147 {
1148 auto subspan = span.last(0u);
1149 EXPECT_EQ(span.data() + 3, subspan.data());
1150 EXPECT_EQ(0u, subspan.size());
1151 }
1152
1153 {
1154 auto subspan = span.last(1u);
1155 EXPECT_EQ(span.data() + 2, subspan.data());
1156 EXPECT_EQ(1u, subspan.size());
1157 EXPECT_EQ(3, subspan[0]);
1158 }
1159
1160 {
1161 auto subspan = span.last(2u);
1162 EXPECT_EQ(span.data() + 1, subspan.data());
1163 EXPECT_EQ(2u, subspan.size());
1164 EXPECT_EQ(2, subspan[0]);
1165 EXPECT_EQ(3, subspan[1]);
1166 }
1167
1168 {
1169 auto subspan = span.last(3u);
1170 EXPECT_EQ(span.data(), subspan.data());
1171 EXPECT_EQ(3u, subspan.size());
1172 EXPECT_EQ(1, subspan[0]);
1173 EXPECT_EQ(2, subspan[1]);
1174 EXPECT_EQ(3, subspan[2]);
1175 }
1176 }
1177
TEST(SpanTest,Subspan)1178 TEST(SpanTest, Subspan) {
1179 int array[] = {1, 2, 3};
1180 span<int> span(array);
1181
1182 {
1183 auto subspan = span.subspan(0);
1184 EXPECT_EQ(span.data(), subspan.data());
1185 EXPECT_EQ(3u, subspan.size());
1186 EXPECT_EQ(1, subspan[0]);
1187 EXPECT_EQ(2, subspan[1]);
1188 EXPECT_EQ(3, subspan[2]);
1189 }
1190
1191 {
1192 auto subspan = span.subspan(1);
1193 EXPECT_EQ(span.data() + 1, subspan.data());
1194 EXPECT_EQ(2u, subspan.size());
1195 EXPECT_EQ(2, subspan[0]);
1196 EXPECT_EQ(3, subspan[1]);
1197 }
1198
1199 {
1200 auto subspan = span.subspan(2);
1201 EXPECT_EQ(span.data() + 2, subspan.data());
1202 EXPECT_EQ(1u, subspan.size());
1203 EXPECT_EQ(3, subspan[0]);
1204 }
1205
1206 {
1207 auto subspan = span.subspan(3);
1208 EXPECT_EQ(span.data() + 3, subspan.data());
1209 EXPECT_EQ(0u, subspan.size());
1210 }
1211
1212 {
1213 auto subspan = span.subspan(0, 0);
1214 EXPECT_EQ(span.data(), subspan.data());
1215 EXPECT_EQ(0u, subspan.size());
1216 }
1217
1218 {
1219 auto subspan = span.subspan(1, 0);
1220 EXPECT_EQ(span.data() + 1, subspan.data());
1221 EXPECT_EQ(0u, subspan.size());
1222 }
1223
1224 {
1225 auto subspan = span.subspan(2, 0);
1226 EXPECT_EQ(span.data() + 2, subspan.data());
1227 EXPECT_EQ(0u, subspan.size());
1228 }
1229
1230 {
1231 auto subspan = span.subspan(0, 1);
1232 EXPECT_EQ(span.data(), subspan.data());
1233 EXPECT_EQ(1u, subspan.size());
1234 EXPECT_EQ(1, subspan[0]);
1235 }
1236
1237 {
1238 auto subspan = span.subspan(1, 1);
1239 EXPECT_EQ(span.data() + 1, subspan.data());
1240 EXPECT_EQ(1u, subspan.size());
1241 EXPECT_EQ(2, subspan[0]);
1242 }
1243
1244 {
1245 auto subspan = span.subspan(2, 1);
1246 EXPECT_EQ(span.data() + 2, subspan.data());
1247 EXPECT_EQ(1u, subspan.size());
1248 EXPECT_EQ(3, subspan[0]);
1249 }
1250
1251 {
1252 auto subspan = span.subspan(0, 2);
1253 EXPECT_EQ(span.data(), subspan.data());
1254 EXPECT_EQ(2u, subspan.size());
1255 EXPECT_EQ(1, subspan[0]);
1256 EXPECT_EQ(2, subspan[1]);
1257 }
1258
1259 {
1260 auto subspan = span.subspan(1, 2);
1261 EXPECT_EQ(span.data() + 1, subspan.data());
1262 EXPECT_EQ(2u, subspan.size());
1263 EXPECT_EQ(2, subspan[0]);
1264 EXPECT_EQ(3, subspan[1]);
1265 }
1266
1267 {
1268 auto subspan = span.subspan(0, 3);
1269 EXPECT_EQ(span.data(), subspan.data());
1270 EXPECT_EQ(span.size(), subspan.size());
1271 EXPECT_EQ(1, subspan[0]);
1272 EXPECT_EQ(2, subspan[1]);
1273 EXPECT_EQ(3, subspan[2]);
1274 }
1275 }
1276
TEST(SpanTest,Size)1277 TEST(SpanTest, Size) {
1278 {
1279 span<int> span;
1280 EXPECT_EQ(0u, span.size());
1281 }
1282
1283 {
1284 int array[] = {1, 2, 3};
1285 span<int> span(array);
1286 EXPECT_EQ(3u, span.size());
1287 }
1288 }
1289
TEST(SpanTest,SizeBytes)1290 TEST(SpanTest, SizeBytes) {
1291 {
1292 span<int> span;
1293 EXPECT_EQ(0u, span.size_bytes());
1294 }
1295
1296 {
1297 int array[] = {1, 2, 3};
1298 span<int> span(array);
1299 EXPECT_EQ(3u * sizeof(int), span.size_bytes());
1300 }
1301 }
1302
TEST(SpanTest,Empty)1303 TEST(SpanTest, Empty) {
1304 {
1305 span<int> span;
1306 EXPECT_TRUE(span.empty());
1307 }
1308
1309 {
1310 int array[] = {1, 2, 3};
1311 span<int> span(array);
1312 EXPECT_FALSE(span.empty());
1313 }
1314
1315 {
1316 std::vector<int> vector = {1, 2, 3};
1317 span<int> s = vector;
1318 span<int> span_of_checked_iterators = {s.end(), s.end()};
1319 EXPECT_TRUE(span_of_checked_iterators.empty());
1320 }
1321 }
1322
TEST(SpanTest,OperatorAt)1323 TEST(SpanTest, OperatorAt) {
1324 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1325 constexpr span<const int> span(kArray);
1326
1327 static_assert(&kArray[0] == &span[0],
1328 "span[0] does not refer to the same element as kArray[0]");
1329 static_assert(&kArray[1] == &span[1],
1330 "span[1] does not refer to the same element as kArray[1]");
1331 static_assert(&kArray[2] == &span[2],
1332 "span[2] does not refer to the same element as kArray[2]");
1333 static_assert(&kArray[3] == &span[3],
1334 "span[3] does not refer to the same element as kArray[3]");
1335 static_assert(&kArray[4] == &span[4],
1336 "span[4] does not refer to the same element as kArray[4]");
1337 }
1338
TEST(SpanTest,Front)1339 TEST(SpanTest, Front) {
1340 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1341 constexpr span<const int> span(kArray);
1342 static_assert(&kArray[0] == &span.front(),
1343 "span.front() does not refer to the same element as kArray[0]");
1344 }
1345
TEST(SpanTest,Back)1346 TEST(SpanTest, Back) {
1347 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1348 constexpr span<const int> span(kArray);
1349 static_assert(&kArray[4] == &span.back(),
1350 "span.back() does not refer to the same element as kArray[4]");
1351 }
1352
TEST(SpanTest,Iterator)1353 TEST(SpanTest, Iterator) {
1354 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1355 constexpr span<const int> span(kArray);
1356
1357 std::vector<int> results;
1358 for (int i : span) {
1359 results.emplace_back(i);
1360 }
1361 EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
1362 }
1363
TEST(SpanTest,ConstexprIterator)1364 TEST(SpanTest, ConstexprIterator) {
1365 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1366 constexpr span<const int> span(kArray);
1367
1368 static_assert(ranges::equal(kArray, span), "");
1369 static_assert(1 == span.begin()[0], "");
1370 static_assert(1 == *(span.begin() += 0), "");
1371 static_assert(6 == *(span.begin() += 1), "");
1372
1373 static_assert(1 == *((span.begin() + 1) -= 1), "");
1374 static_assert(6 == *((span.begin() + 1) -= 0), "");
1375
1376 static_assert(0 + span.begin() == span.begin() + 0);
1377 static_assert(1 + span.begin() == span.begin() + 1);
1378 }
1379
TEST(SpanTest,ReverseIterator)1380 TEST(SpanTest, ReverseIterator) {
1381 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1382 constexpr span<const int> span(kArray);
1383
1384 EXPECT_TRUE(ranges::equal(Reversed(kArray), Reversed(span)));
1385 }
1386
TEST(SpanTest,AsBytes)1387 TEST(SpanTest, AsBytes) {
1388 {
1389 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1390 auto bytes_span = as_bytes(make_span(kArray));
1391 static_assert(std::is_same_v<decltype(bytes_span),
1392 base::span<const uint8_t, sizeof(kArray)>>);
1393 EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
1394 EXPECT_EQ(sizeof(kArray), bytes_span.size());
1395 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1396 }
1397 {
1398 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1399 span<int> mutable_span(vec);
1400 auto bytes_span = as_bytes(mutable_span);
1401 static_assert(
1402 std::is_same_v<decltype(bytes_span), base::span<const uint8_t>>);
1403 EXPECT_EQ(reinterpret_cast<const uint8_t*>(vec.data()), bytes_span.data());
1404 EXPECT_EQ(sizeof(int) * vec.size(), bytes_span.size());
1405 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1406 }
1407 }
1408
TEST(SpanTest,AsWritableBytes)1409 TEST(SpanTest, AsWritableBytes) {
1410 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1411 span<int> mutable_span(vec);
1412 auto writable_bytes_span = as_writable_bytes(mutable_span);
1413 static_assert(
1414 std::is_same_v<decltype(writable_bytes_span), base::span<uint8_t>>);
1415 EXPECT_EQ(reinterpret_cast<uint8_t*>(vec.data()), writable_bytes_span.data());
1416 EXPECT_EQ(sizeof(int) * vec.size(), writable_bytes_span.size());
1417 EXPECT_EQ(writable_bytes_span.size(), writable_bytes_span.size_bytes());
1418
1419 // Set the first entry of vec by writing through the span.
1420 std::fill(writable_bytes_span.data(),
1421 writable_bytes_span.data() + sizeof(int), 'a');
1422 static_assert(sizeof(int) == 4u); // Otherwise char literal wrong below.
1423 EXPECT_EQ('aaaa', vec[0]);
1424 }
1425
TEST(SpanTest,AsChars)1426 TEST(SpanTest, AsChars) {
1427 {
1428 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1429 auto chars_span = as_chars(make_span(kArray));
1430 static_assert(std::is_same_v<decltype(chars_span),
1431 base::span<const char, sizeof(kArray)>>);
1432 EXPECT_EQ(reinterpret_cast<const char*>(kArray), chars_span.data());
1433 EXPECT_EQ(sizeof(kArray), chars_span.size());
1434 EXPECT_EQ(chars_span.size(), chars_span.size_bytes());
1435 }
1436 {
1437 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1438 span<int> mutable_span(vec);
1439 auto chars_span = as_chars(mutable_span);
1440 static_assert(std::is_same_v<decltype(chars_span), base::span<const char>>);
1441 EXPECT_EQ(reinterpret_cast<const char*>(vec.data()), chars_span.data());
1442 EXPECT_EQ(sizeof(int) * vec.size(), chars_span.size());
1443 EXPECT_EQ(chars_span.size(), chars_span.size_bytes());
1444 }
1445 }
1446
TEST(SpanTest,AsWritableChars)1447 TEST(SpanTest, AsWritableChars) {
1448 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1449 span<int> mutable_span(vec);
1450 auto writable_chars_span = as_writable_chars(mutable_span);
1451 static_assert(
1452 std::is_same_v<decltype(writable_chars_span), base::span<char>>);
1453 EXPECT_EQ(reinterpret_cast<char*>(vec.data()), writable_chars_span.data());
1454 EXPECT_EQ(sizeof(int) * vec.size(), writable_chars_span.size());
1455 EXPECT_EQ(writable_chars_span.size(), writable_chars_span.size_bytes());
1456
1457 // Set the first entry of vec by writing through the span.
1458 std::fill(writable_chars_span.data(),
1459 writable_chars_span.data() + sizeof(int), 'a');
1460 static_assert(sizeof(int) == 4u); // Otherwise char literal wrong below.
1461 EXPECT_EQ('aaaa', vec[0]);
1462 }
1463
TEST(SpanTest,AsByteSpan)1464 TEST(SpanTest, AsByteSpan) {
1465 {
1466 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1467 auto byte_span = as_byte_span(kArray);
1468 static_assert(std::is_same_v<decltype(byte_span),
1469 span<const uint8_t, 6u * sizeof(int)>>);
1470 EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kArray));
1471 EXPECT_EQ(byte_span.size(), sizeof(kArray));
1472 }
1473 {
1474 const std::vector<int> kVec({2, 3, 5, 7, 11, 13});
1475 auto byte_span = as_byte_span(kVec);
1476 static_assert(std::is_same_v<decltype(byte_span), span<const uint8_t>>);
1477 EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kVec.data()));
1478 EXPECT_EQ(byte_span.size(), kVec.size() * sizeof(int));
1479 }
1480 {
1481 int kMutArray[] = {2, 3, 5, 7};
1482 auto byte_span = as_byte_span(kMutArray);
1483 static_assert(std::is_same_v<decltype(byte_span),
1484 span<const uint8_t, 4u * sizeof(int)>>);
1485 EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kMutArray));
1486 EXPECT_EQ(byte_span.size(), sizeof(kMutArray));
1487 }
1488 {
1489 std::vector<int> kMutVec({2, 3, 5, 7});
1490 auto byte_span = as_byte_span(kMutVec);
1491 static_assert(std::is_same_v<decltype(byte_span), span<const uint8_t>>);
1492 EXPECT_EQ(byte_span.data(),
1493 reinterpret_cast<const uint8_t*>(kMutVec.data()));
1494 EXPECT_EQ(byte_span.size(), kMutVec.size() * sizeof(int));
1495 }
1496 // Rvalue input.
1497 {
1498 [](auto byte_span) {
1499 static_assert(std::is_same_v<decltype(byte_span),
1500 span<const uint8_t, 6u * sizeof(int)>>);
1501 EXPECT_EQ(byte_span.size(), 6u * sizeof(int));
1502 // Little endian puts the low bits in the first byte.
1503 EXPECT_EQ(byte_span[0u], 2);
1504 }(as_byte_span({2, 3, 5, 7, 11, 13}));
1505 }
1506 }
1507
TEST(SpanTest,AsWritableByteSpan)1508 TEST(SpanTest, AsWritableByteSpan) {
1509 {
1510 int kMutArray[] = {2, 3, 5, 7};
1511 auto byte_span = as_writable_byte_span(kMutArray);
1512 static_assert(
1513 std::is_same_v<decltype(byte_span), span<uint8_t, 4u * sizeof(int)>>);
1514 EXPECT_EQ(byte_span.data(), reinterpret_cast<uint8_t*>(kMutArray));
1515 EXPECT_EQ(byte_span.size(), sizeof(kMutArray));
1516 }
1517 {
1518 std::vector<int> kMutVec({2, 3, 5, 7});
1519 auto byte_span = as_writable_byte_span(kMutVec);
1520 static_assert(std::is_same_v<decltype(byte_span), span<uint8_t>>);
1521 EXPECT_EQ(byte_span.data(), reinterpret_cast<uint8_t*>(kMutVec.data()));
1522 EXPECT_EQ(byte_span.size(), kMutVec.size() * sizeof(int));
1523 }
1524 // Rvalue input.
1525 {
1526 [](auto byte_span) {
1527 static_assert(
1528 std::is_same_v<decltype(byte_span), span<uint8_t, 6u * sizeof(int)>>);
1529 EXPECT_EQ(byte_span.size(), 6u * sizeof(int));
1530 // Little endian puts the low bits in the first byte.
1531 EXPECT_EQ(byte_span[0u], 2);
1532 }(as_writable_byte_span({2, 3, 5, 7, 11, 13}));
1533 }
1534 }
1535
TEST(SpanTest,AsStringView)1536 TEST(SpanTest, AsStringView) {
1537 {
1538 constexpr uint8_t kArray[] = {'h', 'e', 'l', 'l', 'o'};
1539 // Fixed size span.
1540 auto s = as_string_view(kArray);
1541 static_assert(std::is_same_v<decltype(s), std::string_view>);
1542 EXPECT_EQ(s.data(), reinterpret_cast<const char*>(&kArray[0u]));
1543 EXPECT_EQ(s.size(), std::size(kArray));
1544
1545 // Dynamic size span.
1546 auto s2 = as_string_view(base::span<const uint8_t>(kArray));
1547 static_assert(std::is_same_v<decltype(s2), std::string_view>);
1548 EXPECT_EQ(s2.data(), reinterpret_cast<const char*>(&kArray[0u]));
1549 EXPECT_EQ(s2.size(), std::size(kArray));
1550 }
1551 {
1552 constexpr char kArray[] = {'h', 'e', 'l', 'l', 'o'};
1553 // Fixed size span.
1554 auto s = as_string_view(kArray);
1555 static_assert(std::is_same_v<decltype(s), std::string_view>);
1556 EXPECT_EQ(s.data(), &kArray[0u]);
1557 EXPECT_EQ(s.size(), std::size(kArray));
1558
1559 // Dynamic size span.
1560 auto s2 = as_string_view(base::span<const char>(kArray));
1561 static_assert(std::is_same_v<decltype(s2), std::string_view>);
1562 EXPECT_EQ(s2.data(), &kArray[0u]);
1563 EXPECT_EQ(s2.size(), std::size(kArray));
1564 }
1565 }
1566
TEST(SpanTest,MakeSpanFromDataAndSize)1567 TEST(SpanTest, MakeSpanFromDataAndSize) {
1568 int* nullint = nullptr;
1569 auto empty_span = make_span(nullint, 0u);
1570 EXPECT_TRUE(empty_span.empty());
1571 EXPECT_EQ(nullptr, empty_span.data());
1572
1573 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1574 span<int> expected_span(vector.data(), vector.size());
1575 auto made_span = make_span(vector.data(), vector.size());
1576 EXPECT_EQ(expected_span.data(), made_span.data());
1577 EXPECT_EQ(expected_span.size(), made_span.size());
1578 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1579 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1580 "the type of made_span differs from expected_span!");
1581 }
1582
TEST(SpanTest,MakeSpanFromPointerPair)1583 TEST(SpanTest, MakeSpanFromPointerPair) {
1584 int* nullint = nullptr;
1585 auto empty_span = make_span(nullint, nullint);
1586 EXPECT_TRUE(empty_span.empty());
1587 EXPECT_EQ(nullptr, empty_span.data());
1588
1589 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1590 span<int> expected_span(vector.data(), vector.size());
1591 auto made_span = make_span(vector.data(), vector.data() + vector.size());
1592 EXPECT_EQ(expected_span.data(), made_span.data());
1593 EXPECT_EQ(expected_span.size(), made_span.size());
1594 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1595 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1596 "the type of made_span differs from expected_span!");
1597 }
1598
TEST(SpanTest,MakeSpanFromConstexprArray)1599 TEST(SpanTest, MakeSpanFromConstexprArray) {
1600 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1601 constexpr span<const int, 5> expected_span(kArray);
1602 constexpr auto made_span = make_span(kArray);
1603 EXPECT_EQ(expected_span.data(), made_span.data());
1604 EXPECT_EQ(expected_span.size(), made_span.size());
1605 static_assert(decltype(made_span)::extent == 5, "");
1606 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1607 "the type of made_span differs from expected_span!");
1608 }
1609
TEST(SpanTest,MakeSpanFromStdArray)1610 TEST(SpanTest, MakeSpanFromStdArray) {
1611 const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
1612 span<const int, 5> expected_span(kArray);
1613 auto made_span = make_span(kArray);
1614 EXPECT_EQ(expected_span.data(), made_span.data());
1615 EXPECT_EQ(expected_span.size(), made_span.size());
1616 static_assert(decltype(made_span)::extent == 5, "");
1617 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1618 "the type of made_span differs from expected_span!");
1619 }
1620
TEST(SpanTest,MakeSpanFromConstContainer)1621 TEST(SpanTest, MakeSpanFromConstContainer) {
1622 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1623 span<const int> expected_span(vector);
1624 auto made_span = make_span(vector);
1625 EXPECT_EQ(expected_span.data(), made_span.data());
1626 EXPECT_EQ(expected_span.size(), made_span.size());
1627 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1628 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1629 "the type of made_span differs from expected_span!");
1630 }
1631
TEST(SpanTest,MakeStaticSpanFromConstContainer)1632 TEST(SpanTest, MakeStaticSpanFromConstContainer) {
1633 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1634 span<const int, 5> expected_span(vector.data(), vector.size());
1635 auto made_span = make_span<5>(vector);
1636 EXPECT_EQ(expected_span.data(), made_span.data());
1637 EXPECT_EQ(expected_span.size(), made_span.size());
1638 static_assert(decltype(made_span)::extent == 5, "");
1639 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1640 "the type of made_span differs from expected_span!");
1641 }
1642
TEST(SpanTest,MakeSpanFromContainer)1643 TEST(SpanTest, MakeSpanFromContainer) {
1644 std::vector<int> vector = {-1, -2, -3, -4, -5};
1645 span<int> expected_span(vector);
1646 auto made_span = make_span(vector);
1647 EXPECT_EQ(expected_span.data(), made_span.data());
1648 EXPECT_EQ(expected_span.size(), made_span.size());
1649 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1650 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1651 "the type of made_span differs from expected_span!");
1652 }
1653
TEST(SpanTest,MakeStaticSpanFromContainer)1654 TEST(SpanTest, MakeStaticSpanFromContainer) {
1655 std::vector<int> vector = {-1, -2, -3, -4, -5};
1656 span<int, 5> expected_span(vector.data(), vector.size());
1657 auto made_span = make_span<5>(vector);
1658 EXPECT_EQ(expected_span.data(), make_span<5>(vector).data());
1659 EXPECT_EQ(expected_span.size(), make_span<5>(vector).size());
1660 static_assert(decltype(make_span<5>(vector))::extent == 5, "");
1661 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1662 "the type of made_span differs from expected_span!");
1663 }
1664
TEST(SpanTest,MakeStaticSpanFromConstexprContainer)1665 TEST(SpanTest, MakeStaticSpanFromConstexprContainer) {
1666 constexpr std::string_view str = "Hello, World";
1667 constexpr auto made_span = make_span<12>(str);
1668 static_assert(str.data() == made_span.data(), "Error: data() does not match");
1669 static_assert(str.size() == made_span.size(), "Error: size() does not match");
1670 static_assert(std::is_same_v<decltype(str)::value_type,
1671 decltype(made_span)::value_type>,
1672 "Error: value_type does not match");
1673 static_assert(str.size() == decltype(made_span)::extent,
1674 "Error: extent does not match");
1675 }
1676
TEST(SpanTest,MakeSpanFromRValueContainer)1677 TEST(SpanTest, MakeSpanFromRValueContainer) {
1678 std::vector<int> vector = {-1, -2, -3, -4, -5};
1679 span<const int> expected_span(vector);
1680 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1681 // std::move(foo), make_span does not actually take ownership of the passed in
1682 // container. Writing it this way makes it more obvious that we simply care
1683 // about the right behavour when passing rvalues.
1684 auto made_span = make_span(static_cast<std::vector<int>&&>(vector));
1685 EXPECT_EQ(expected_span.data(), made_span.data());
1686 EXPECT_EQ(expected_span.size(), made_span.size());
1687 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1688 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1689 "the type of made_span differs from expected_span!");
1690 }
1691
TEST(SpanTest,MakeStaticSpanFromRValueContainer)1692 TEST(SpanTest, MakeStaticSpanFromRValueContainer) {
1693 std::vector<int> vector = {-1, -2, -3, -4, -5};
1694 span<const int, 5> expected_span(vector.data(), vector.size());
1695 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1696 // std::move(foo), make_span does not actually take ownership of the passed in
1697 // container. Writing it this way makes it more obvious that we simply care
1698 // about the right behavour when passing rvalues.
1699 auto made_span = make_span<5>(static_cast<std::vector<int>&&>(vector));
1700 EXPECT_EQ(expected_span.data(), made_span.data());
1701 EXPECT_EQ(expected_span.size(), made_span.size());
1702 static_assert(decltype(made_span)::extent == 5, "");
1703 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1704 "the type of made_span differs from expected_span!");
1705 }
1706
TEST(SpanTest,MakeSpanFromDynamicSpan)1707 TEST(SpanTest, MakeSpanFromDynamicSpan) {
1708 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1709 constexpr span<const int> expected_span(kArray);
1710 constexpr auto made_span = make_span(expected_span);
1711 static_assert(std::is_same_v<decltype(expected_span)::element_type,
1712 decltype(made_span)::element_type>,
1713 "make_span(span) should have the same element_type as span");
1714
1715 static_assert(expected_span.data() == made_span.data(),
1716 "make_span(span) should have the same data() as span");
1717
1718 static_assert(expected_span.size() == made_span.size(),
1719 "make_span(span) should have the same size() as span");
1720
1721 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1722 "make_span(span) should have the same extent as span");
1723
1724 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1725 "the type of made_span differs from expected_span!");
1726 }
1727
TEST(SpanTest,MakeSpanFromStaticSpan)1728 TEST(SpanTest, MakeSpanFromStaticSpan) {
1729 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1730 constexpr span<const int, 5> expected_span(kArray);
1731 constexpr auto made_span = make_span(expected_span);
1732 static_assert(std::is_same_v<decltype(expected_span)::element_type,
1733 decltype(made_span)::element_type>,
1734 "make_span(span) should have the same element_type as span");
1735
1736 static_assert(expected_span.data() == made_span.data(),
1737 "make_span(span) should have the same data() as span");
1738
1739 static_assert(expected_span.size() == made_span.size(),
1740 "make_span(span) should have the same size() as span");
1741
1742 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1743 "make_span(span) should have the same extent as span");
1744
1745 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1746 "the type of made_span differs from expected_span!");
1747 }
1748
TEST(SpanTest,EnsureConstexprGoodness)1749 TEST(SpanTest, EnsureConstexprGoodness) {
1750 static constexpr int kArray[] = {5, 4, 3, 2, 1};
1751 constexpr span<const int> constexpr_span(kArray);
1752 const size_t size = 2;
1753
1754 const size_t start = 1;
1755 constexpr span<const int> subspan =
1756 constexpr_span.subspan(start, start + size);
1757 for (size_t i = 0; i < subspan.size(); ++i) {
1758 EXPECT_EQ(kArray[start + i], subspan[i]);
1759 }
1760
1761 constexpr span<const int> firsts = constexpr_span.first(size);
1762 for (size_t i = 0; i < firsts.size(); ++i) {
1763 EXPECT_EQ(kArray[i], firsts[i]);
1764 }
1765
1766 constexpr span<const int> lasts = constexpr_span.last(size);
1767 for (size_t i = 0; i < lasts.size(); ++i) {
1768 const size_t j = (std::size(kArray) - size) + i;
1769 EXPECT_EQ(kArray[j], lasts[i]);
1770 }
1771
1772 constexpr int item = constexpr_span[size];
1773 EXPECT_EQ(kArray[size], item);
1774 }
1775
TEST(SpanTest,OutOfBoundsDeath)1776 TEST(SpanTest, OutOfBoundsDeath) {
1777 constexpr span<int, 0> kEmptySpan;
1778 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan[0], "");
1779 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.first(1u), "");
1780 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.last(1u), "");
1781 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1u), "");
1782
1783 constexpr span<int> kEmptyDynamicSpan;
1784 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan[0], "");
1785 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.front(), "");
1786 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.first(1u), "");
1787 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.last(1u), "");
1788 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.back(), "");
1789 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.subspan(1), "");
1790
1791 static constexpr int kArray[] = {0, 1, 2};
1792 constexpr span<const int> kNonEmptyDynamicSpan(kArray);
1793 EXPECT_EQ(3U, kNonEmptyDynamicSpan.size());
1794 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan[4], "");
1795 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(10), "");
1796 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(1, 7), "");
1797
1798 size_t minus_one = static_cast<size_t>(-1);
1799 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(minus_one), "");
1800 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(minus_one, minus_one),
1801 "");
1802 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(minus_one, 1), "");
1803
1804 // Span's iterators should be checked. To confirm the crashes come from the
1805 // iterator checks and not stray memory accesses, we create spans that are
1806 // backed by larger arrays.
1807 int array1[] = {1, 2, 3, 4};
1808 int array2[] = {1, 2, 3, 4};
1809 span<int> span_len2 = span(array1).first(2u);
1810 span<int> span_len3 = span(array2).first(3u);
1811 ASSERT_DEATH_IF_SUPPORTED(*span_len2.end(), "");
1812 ASSERT_DEATH_IF_SUPPORTED(span_len2.begin()[2], "");
1813 ASSERT_DEATH_IF_SUPPORTED(span_len2.begin() + 3, "");
1814 ASSERT_DEATH_IF_SUPPORTED(span_len2.begin() - 1, "");
1815 ASSERT_DEATH_IF_SUPPORTED(span_len2.end() + 1, "");
1816
1817 // When STL functions take explicit end iterators, bounds checking happens
1818 // at the caller, when end iterator is created. However, some APIs take only a
1819 // begin iterator and determine end implicitly. In that case, bounds checking
1820 // happens inside the STL. However, the STL sometimes specializes operations
1821 // on contiguous iterators. These death ensures this specialization does not
1822 // lose hardening.
1823 //
1824 // Note that these tests are necessary, but not sufficient, to demonstrate
1825 // that iterators are suitably checked. The output iterator is currently
1826 // checked too late due to https://crbug.com/1520041.
1827
1828 // Copying more values than fit in the destination.
1829 ASSERT_DEATH_IF_SUPPORTED(
1830 std::copy(span_len3.begin(), span_len3.end(), span_len2.begin()), "");
1831 ASSERT_DEATH_IF_SUPPORTED(std::ranges::copy(span_len3, span_len2.begin()),
1832 "");
1833 ASSERT_DEATH_IF_SUPPORTED(
1834 std::copy_n(span_len3.begin(), 3, span_len2.begin()), "");
1835
1836 // Copying more values than exist in the source.
1837 ASSERT_DEATH_IF_SUPPORTED(
1838 std::copy_n(span_len2.begin(), 3, span_len3.begin()), "");
1839 }
1840
TEST(SpanTest,IteratorIsRangeMoveSafe)1841 TEST(SpanTest, IteratorIsRangeMoveSafe) {
1842 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1843 const size_t kNumElements = 5;
1844 constexpr span<const int> span(kArray);
1845
1846 static constexpr int kOverlappingStartIndexes[] = {-4, 0, 3, 4};
1847 static constexpr int kNonOverlappingStartIndexes[] = {-7, -5, 5, 7};
1848
1849 // Overlapping ranges.
1850 for (const int dest_start_index : kOverlappingStartIndexes) {
1851 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1852 span.begin(), span.end(),
1853 CheckedContiguousIterator<const int>(
1854 span.data() + dest_start_index,
1855 span.data() + dest_start_index + kNumElements)));
1856 }
1857
1858 // Non-overlapping ranges.
1859 for (const int dest_start_index : kNonOverlappingStartIndexes) {
1860 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1861 span.begin(), span.end(),
1862 CheckedContiguousIterator<const int>(
1863 span.data() + dest_start_index,
1864 span.data() + dest_start_index + kNumElements)));
1865 }
1866
1867 // IsRangeMoveSafe is true if the length to be moved is 0.
1868 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1869 span.begin(), span.begin(),
1870 CheckedContiguousIterator<const int>(span.data(), span.data())));
1871
1872 // IsRangeMoveSafe is false if end < begin.
1873 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1874 span.end(), span.begin(),
1875 CheckedContiguousIterator<const int>(span.data(), span.data())));
1876 }
1877
TEST(SpanTest,Sort)1878 TEST(SpanTest, Sort) {
1879 int array[] = {5, 4, 3, 2, 1};
1880
1881 span<int> dynamic_span = array;
1882 ranges::sort(dynamic_span);
1883 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1884 std::sort(dynamic_span.rbegin(), dynamic_span.rend());
1885 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1886
1887 span<int, 5> static_span = array;
1888 std::sort(static_span.rbegin(), static_span.rend(), std::greater<>());
1889 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1890 ranges::sort(static_span, std::greater<>());
1891 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1892 }
1893
TEST(SpanTest,SpanExtentConversions)1894 TEST(SpanTest, SpanExtentConversions) {
1895 // Statically checks that various conversions between spans of dynamic and
1896 // static extent are possible or not.
1897 static_assert(std::is_constructible_v<span<int, 0>, span<int>>,
1898 "Error: static span should be constructible from dynamic span");
1899
1900 static_assert(
1901 !std::is_convertible_v<span<int>, span<int, 0>>,
1902 "Error: static span should not be convertible from dynamic span");
1903
1904 static_assert(!std::is_constructible_v<span<int, 2>, span<int, 1>>,
1905 "Error: static span should not be constructible from static "
1906 "span with different extent");
1907
1908 static_assert(std::is_convertible_v<span<int, 0>, span<int>>,
1909 "Error: static span should be convertible to dynamic span");
1910
1911 static_assert(std::is_convertible_v<span<int>, span<int>>,
1912 "Error: dynamic span should be convertible to dynamic span");
1913
1914 static_assert(std::is_convertible_v<span<int, 2>, span<int, 2>>,
1915 "Error: static span should be convertible to static span");
1916 }
1917
TEST(SpanTest,IteratorConversions)1918 TEST(SpanTest, IteratorConversions) {
1919 static_assert(
1920 std::is_convertible_v<span<int>::iterator, span<const int>::iterator>,
1921 "Error: iterator should be convertible to const iterator");
1922
1923 static_assert(
1924 !std::is_convertible_v<span<const int>::iterator, span<int>::iterator>,
1925 "Error: const iterator should not be convertible to iterator");
1926 }
1927
TEST(SpanTest,ExtentMacro)1928 TEST(SpanTest, ExtentMacro) {
1929 constexpr size_t kSize = 10;
1930 std::array<uint8_t, kSize> array;
1931 static_assert(EXTENT(array) == kSize, "EXTENT broken");
1932
1933 const std::array<uint8_t, kSize>& reference = array;
1934 static_assert(EXTENT(reference) == kSize, "EXTENT broken for references");
1935
1936 const std::array<uint8_t, kSize>* pointer = nullptr;
1937 static_assert(EXTENT(*pointer) == kSize, "EXTENT broken for pointers");
1938
1939 uint8_t plain_array[kSize] = {0};
1940 static_assert(EXTENT(plain_array) == kSize, "EXTENT broken for plain arrays");
1941 }
1942
TEST(SpanTest,CopyFrom)1943 TEST(SpanTest, CopyFrom) {
1944 int arr[] = {1, 2, 3};
1945 span<int, 0> empty_static_span;
1946 span<int, 3> static_span = base::make_span(arr);
1947
1948 std::vector<int> vec = {4, 5, 6};
1949 span<int> empty_dynamic_span;
1950 span<int> dynamic_span = base::make_span(vec);
1951
1952 // Handle empty cases gracefully.
1953 // Dynamic size to static size requires an explicit conversion.
1954 empty_static_span.copy_from(make_span<0u>(empty_dynamic_span));
1955 empty_dynamic_span.copy_from(empty_static_span);
1956 static_span.first(empty_static_span.size()).copy_from(empty_static_span);
1957 dynamic_span.first(empty_dynamic_span.size()).copy_from(empty_dynamic_span);
1958 EXPECT_THAT(arr, ElementsAre(1, 2, 3));
1959 EXPECT_THAT(vec, ElementsAre(4, 5, 6));
1960
1961 // Test too small destinations.
1962 EXPECT_DEATH_IF_SUPPORTED(empty_dynamic_span.copy_from(static_span), "");
1963 EXPECT_DEATH_IF_SUPPORTED(empty_dynamic_span.copy_from(dynamic_span), "");
1964 EXPECT_DEATH_IF_SUPPORTED(dynamic_span.last(2u).copy_from(static_span), "");
1965
1966 std::vector<int> source = {7, 8, 9};
1967
1968 static_span.first(2u).copy_from(span(source).last(2u));
1969 EXPECT_THAT(arr, ElementsAre(8, 9, 3));
1970
1971 dynamic_span.first(2u).copy_from(span(source).last(2u));
1972 EXPECT_THAT(vec, ElementsAre(8, 9, 6));
1973
1974 static_span.first(1u).copy_from(span(source).last(1u));
1975 EXPECT_THAT(arr, ElementsAre(9, 9, 3));
1976
1977 dynamic_span.first(1u).copy_from(span(source).last(1u));
1978 EXPECT_THAT(vec, ElementsAre(9, 9, 6));
1979 }
1980
TEST(SpanTest,CopyFromConversion)1981 TEST(SpanTest, CopyFromConversion) {
1982 int arr[] = {1, 2, 3};
1983 span<int, 3> static_span = base::make_span(arr);
1984
1985 std::vector<int> vec = {4, 5, 6};
1986 span<int> dynamic_span = base::make_span(vec);
1987
1988 std::vector convert_from = {7, 8, 9};
1989 // Dynamic size to static size requires an explicit conversion.
1990 static_span.copy_from(make_span<3u>(convert_from));
1991 dynamic_span.copy_from(convert_from);
1992 EXPECT_THAT(static_span, ElementsAre(7, 8, 9));
1993 EXPECT_THAT(dynamic_span, ElementsAre(7, 8, 9));
1994
1995 std::array<int, 3u> convert_from_fixed = {4, 5, 6};
1996 static_span.copy_from(convert_from_fixed);
1997 dynamic_span.copy_from(convert_from_fixed);
1998 EXPECT_THAT(static_span, ElementsAre(4, 5, 6));
1999 EXPECT_THAT(dynamic_span, ElementsAre(4, 5, 6));
2000
2001 int convert_from_array[] = {1, 2, 3};
2002 static_span.copy_from(convert_from_array);
2003 dynamic_span.copy_from(convert_from_array);
2004 EXPECT_THAT(static_span, ElementsAre(1, 2, 3));
2005 EXPECT_THAT(dynamic_span, ElementsAre(1, 2, 3));
2006
2007 int convert_from_const_array[] = {-1, -2, -3};
2008 static_span.copy_from(convert_from_const_array);
2009 dynamic_span.copy_from(convert_from_const_array);
2010 EXPECT_THAT(static_span, ElementsAre(-1, -2, -3));
2011 EXPECT_THAT(dynamic_span, ElementsAre(-1, -2, -3));
2012 }
2013
TEST(SpanTest,SplitAt)2014 TEST(SpanTest, SplitAt) {
2015 int arr[] = {1, 2, 3};
2016 span<int, 0> empty_static_span;
2017 span<int, 3> static_span = base::make_span(arr);
2018
2019 std::vector<int> vec = {4, 5, 6};
2020 span<int> empty_dynamic_span;
2021 span<int> dynamic_span = base::make_span(vec);
2022
2023 {
2024 auto [left, right] = empty_static_span.split_at(0u);
2025 EXPECT_EQ(left.size(), 0u);
2026 EXPECT_EQ(right.size(), 0u);
2027 }
2028 {
2029 auto [left, right] = empty_dynamic_span.split_at(0u);
2030 EXPECT_EQ(left.size(), 0u);
2031 EXPECT_EQ(right.size(), 0u);
2032 }
2033
2034 {
2035 auto [left, right] = static_span.split_at(0u);
2036 EXPECT_EQ(left.size(), 0u);
2037 EXPECT_EQ(right.size(), 3u);
2038 EXPECT_EQ(right.front(), 1);
2039 }
2040 {
2041 auto [left, right] = static_span.split_at(3u);
2042 EXPECT_EQ(left.size(), 3u);
2043 EXPECT_EQ(right.size(), 0u);
2044 EXPECT_EQ(left.front(), 1);
2045 }
2046 {
2047 auto [left, right] = static_span.split_at(1u);
2048 EXPECT_EQ(left.size(), 1u);
2049 EXPECT_EQ(right.size(), 2u);
2050 EXPECT_EQ(left.front(), 1);
2051 EXPECT_EQ(right.front(), 2);
2052 }
2053
2054 {
2055 auto [left, right] = dynamic_span.split_at(0u);
2056 EXPECT_EQ(left.size(), 0u);
2057 EXPECT_EQ(right.size(), 3u);
2058 EXPECT_EQ(right.front(), 4);
2059 }
2060 {
2061 auto [left, right] = dynamic_span.split_at(3u);
2062 EXPECT_EQ(left.size(), 3u);
2063 EXPECT_EQ(right.size(), 0u);
2064 EXPECT_EQ(left.front(), 4);
2065 }
2066 {
2067 auto [left, right] = dynamic_span.split_at(1u);
2068 EXPECT_EQ(left.size(), 1u);
2069 EXPECT_EQ(right.size(), 2u);
2070 EXPECT_EQ(left.front(), 4);
2071 EXPECT_EQ(right.front(), 5);
2072 }
2073
2074 // Fixed-size splits.
2075 {
2076 auto [left, right] = static_span.split_at<0u>();
2077 static_assert(std::same_as<decltype(left), span<int, 0u>>);
2078 static_assert(std::same_as<decltype(right), span<int, 3u>>);
2079 EXPECT_EQ(left.data(), static_span.data());
2080 EXPECT_EQ(right.data(), static_span.data());
2081 }
2082 {
2083 auto [left, right] = static_span.split_at<1u>();
2084 static_assert(std::same_as<decltype(left), span<int, 1u>>);
2085 static_assert(std::same_as<decltype(right), span<int, 2u>>);
2086 EXPECT_EQ(left.data(), static_span.data());
2087 EXPECT_EQ(right.data(), static_span.data() + 1u);
2088 }
2089 {
2090 auto [left, right] = static_span.split_at<3u>();
2091 static_assert(std::same_as<decltype(left), span<int, 3u>>);
2092 static_assert(std::same_as<decltype(right), span<int, 0u>>);
2093 EXPECT_EQ(left.data(), static_span.data());
2094 EXPECT_EQ(right.data(), static_span.data() + 3u);
2095 }
2096 {
2097 auto [left, right] = dynamic_span.split_at<0u>();
2098 static_assert(std::same_as<decltype(left), span<int, 0u>>);
2099 static_assert(std::same_as<decltype(right), span<int>>);
2100 EXPECT_EQ(left.data(), dynamic_span.data());
2101 EXPECT_EQ(right.data(), dynamic_span.data());
2102 EXPECT_EQ(right.size(), 3u);
2103 }
2104 {
2105 auto [left, right] = dynamic_span.split_at<1u>();
2106 static_assert(std::same_as<decltype(left), span<int, 1u>>);
2107 static_assert(std::same_as<decltype(right), span<int>>);
2108 EXPECT_EQ(left.data(), dynamic_span.data());
2109 EXPECT_EQ(right.data(), dynamic_span.data() + 1u);
2110 EXPECT_EQ(right.size(), 2u);
2111 }
2112 {
2113 auto [left, right] = dynamic_span.split_at<3u>();
2114 static_assert(std::same_as<decltype(left), span<int, 3u>>);
2115 static_assert(std::same_as<decltype(right), span<int>>);
2116 EXPECT_EQ(left.data(), dynamic_span.data());
2117 EXPECT_EQ(right.data(), dynamic_span.data() + 3u);
2118 EXPECT_EQ(right.size(), 0u);
2119 }
2120 // Invalid fixed-size split from dynamic will fail at runtime.
2121 EXPECT_CHECK_DEATH({ dynamic_span.split_at<4u>(); });
2122 }
2123
TEST(SpanTest,Compare)2124 TEST(SpanTest, Compare) {
2125 static_assert(std::equality_comparable<int>);
2126 int32_t arr2[] = {1, 2};
2127 int32_t arr3[] = {1, 2, 3};
2128 int32_t rra3[] = {3, 2, 1};
2129 constexpr const int32_t arr2_c[] = {1, 2};
2130 constexpr const int32_t arr3_c[] = {1, 2, 3};
2131 constexpr const int32_t rra3_c[] = {3, 2, 1};
2132
2133 // Comparing empty spans that are fixed and dynamic size.
2134 EXPECT_TRUE((span<int32_t>() == span<int32_t>()));
2135 EXPECT_TRUE((span<int32_t, 0u>() == span<int32_t>()));
2136 EXPECT_TRUE((span<int32_t>() == span<int32_t, 0u>()));
2137 EXPECT_TRUE((span<int32_t, 0u>() == span<int32_t, 0u>()));
2138 // Non-null data pointer, but both are empty.
2139 EXPECT_TRUE(span(arr2).first(0u) == span(arr2).last(0u));
2140 EXPECT_TRUE(span(arr2).first<0u>() == span(arr2).last<0u>());
2141
2142 // Spans of different dynamic sizes.
2143 EXPECT_TRUE(span(arr2).first(2u) != span(arr3).first(3u));
2144 // Spans of same dynamic size and same values.
2145 EXPECT_TRUE(span(arr2).first(2u) == span(arr3).first(2u));
2146 // Spans of same dynamic size but different values.
2147 EXPECT_TRUE(span(arr2).first(2u) != span(rra3).first(2u));
2148
2149 // Spans of different sizes (one dynamic one fixed).
2150 EXPECT_TRUE(span(arr2).first<2u>() != span(arr3).first(3u));
2151 EXPECT_TRUE(span(arr2).first(2u) != span(arr3).first<3u>());
2152 // Spans of same size and same values.
2153 EXPECT_TRUE(span(arr2).first<2u>() == span(arr3).first(2u));
2154 EXPECT_TRUE(span(arr2).first(2u) == span(arr3).first<2u>());
2155 // Spans of same size but different values.
2156 EXPECT_TRUE(span(arr2).first<2u>() != span(rra3).first(2u));
2157 EXPECT_TRUE(span(arr2).first(2u) != span(rra3).first<2u>());
2158
2159 // Spans of different fixed sizes do not compile (as in Rust)
2160 // https://godbolt.org/z/MrnbPeozr and are covered in nocompile tests.
2161
2162 // Comparing const and non-const. Same tests as above otherwise.
2163
2164 EXPECT_TRUE((span<const int32_t>() == span<int32_t>()));
2165 EXPECT_TRUE((span<const int32_t, 0u>() == span<int32_t>()));
2166 EXPECT_TRUE((span<const int32_t>() == span<int32_t, 0u>()));
2167 EXPECT_TRUE((span<const int32_t, 0u>() == span<int32_t, 0u>()));
2168
2169 EXPECT_TRUE((span<int32_t>() == span<const int32_t>()));
2170 EXPECT_TRUE((span<int32_t, 0u>() == span<const int32_t>()));
2171 EXPECT_TRUE((span<int32_t>() == span<const int32_t, 0u>()));
2172 EXPECT_TRUE((span<int32_t, 0u>() == span<const int32_t, 0u>()));
2173
2174 EXPECT_TRUE(span(arr2_c).first(0u) == span(arr2).last(0u));
2175 EXPECT_TRUE(span(arr2_c).first<0u>() == span(arr2).last<0u>());
2176
2177 EXPECT_TRUE(span(arr2).first(0u) == span(arr2_c).last(0u));
2178 EXPECT_TRUE(span(arr2).first<0u>() == span(arr2_c).last<0u>());
2179
2180 EXPECT_TRUE(span(arr2_c).first(2u) != span(arr3).first(3u));
2181 EXPECT_TRUE(span(arr2_c).first(2u) == span(arr3).first(2u));
2182 EXPECT_TRUE(span(arr2_c).first(2u) != span(rra3).first(2u));
2183
2184 EXPECT_TRUE(span(arr2).first(2u) != span(arr3_c).first(3u));
2185 EXPECT_TRUE(span(arr2).first(2u) == span(arr3_c).first(2u));
2186 EXPECT_TRUE(span(arr2).first(2u) != span(rra3_c).first(2u));
2187
2188 EXPECT_TRUE(span(arr2_c).first<2u>() != span(arr3).first(3u));
2189 EXPECT_TRUE(span(arr2_c).first(2u) != span(arr3).first<3u>());
2190 EXPECT_TRUE(span(arr2_c).first<2u>() == span(arr3).first(2u));
2191 EXPECT_TRUE(span(arr2_c).first(2u) == span(arr3).first<2u>());
2192 EXPECT_TRUE(span(arr2_c).first<2u>() != span(rra3).first(2u));
2193 EXPECT_TRUE(span(arr2_c).first(2u) != span(rra3).first<2u>());
2194
2195 EXPECT_TRUE(span(arr2).first<2u>() != span(arr3_c).first(3u));
2196 EXPECT_TRUE(span(arr2).first(2u) != span(arr3_c).first<3u>());
2197 EXPECT_TRUE(span(arr2).first<2u>() == span(arr3_c).first(2u));
2198 EXPECT_TRUE(span(arr2).first(2u) == span(arr3_c).first<2u>());
2199 EXPECT_TRUE(span(arr2).first<2u>() != span(rra3_c).first(2u));
2200 EXPECT_TRUE(span(arr2).first(2u) != span(rra3_c).first<2u>());
2201
2202 // Comparing different types which are comparable. Same tests as above
2203 // otherwise.
2204
2205 static_assert(std::equality_comparable_with<int32_t, int64_t>);
2206 int64_t arr2_l[] = {1, 2};
2207 int64_t arr3_l[] = {1, 2, 3};
2208 int64_t rra3_l[] = {3, 2, 1};
2209
2210 EXPECT_TRUE((span<int32_t>() == span<int64_t>()));
2211 EXPECT_TRUE((span<int32_t, 0u>() == span<int64_t>()));
2212 EXPECT_TRUE((span<int32_t>() == span<int64_t, 0u>()));
2213 EXPECT_TRUE((span<int32_t, 0u>() == span<int64_t, 0u>()));
2214
2215 EXPECT_TRUE((span<int32_t>() == span<int64_t>()));
2216 EXPECT_TRUE((span<int32_t, 0u>() == span<int64_t>()));
2217 EXPECT_TRUE((span<int32_t>() == span<int64_t, 0u>()));
2218 EXPECT_TRUE((span<int32_t, 0u>() == span<int64_t, 0u>()));
2219
2220 EXPECT_TRUE(span(arr2_l).first(0u) == span(arr2).last(0u));
2221 EXPECT_TRUE(span(arr2_l).first<0u>() == span(arr2).last<0u>());
2222
2223 EXPECT_TRUE(span(arr2).first(0u) == span(arr2_l).last(0u));
2224 EXPECT_TRUE(span(arr2).first<0u>() == span(arr2_l).last<0u>());
2225
2226 EXPECT_TRUE(span(arr2_l).first(2u) != span(arr3).first(3u));
2227 EXPECT_TRUE(span(arr2_l).first(2u) == span(arr3).first(2u));
2228 EXPECT_TRUE(span(arr2_l).first(2u) != span(rra3).first(2u));
2229
2230 EXPECT_TRUE(span(arr2).first(2u) != span(arr3_l).first(3u));
2231 EXPECT_TRUE(span(arr2).first(2u) == span(arr3_l).first(2u));
2232 EXPECT_TRUE(span(arr2).first(2u) != span(rra3_l).first(2u));
2233
2234 EXPECT_TRUE(span(arr2_l).first<2u>() != span(arr3).first(3u));
2235 EXPECT_TRUE(span(arr2_l).first(2u) != span(arr3).first<3u>());
2236 EXPECT_TRUE(span(arr2_l).first<2u>() == span(arr3).first(2u));
2237 EXPECT_TRUE(span(arr2_l).first(2u) == span(arr3).first<2u>());
2238 EXPECT_TRUE(span(arr2_l).first<2u>() != span(rra3).first(2u));
2239 EXPECT_TRUE(span(arr2_l).first(2u) != span(rra3).first<2u>());
2240
2241 EXPECT_TRUE(span(arr2).first<2u>() != span(arr3_l).first(3u));
2242 EXPECT_TRUE(span(arr2).first(2u) != span(arr3_l).first<3u>());
2243 EXPECT_TRUE(span(arr2).first<2u>() == span(arr3_l).first(2u));
2244 EXPECT_TRUE(span(arr2).first(2u) == span(arr3_l).first<2u>());
2245 EXPECT_TRUE(span(arr2).first<2u>() != span(rra3_l).first(2u));
2246 EXPECT_TRUE(span(arr2).first(2u) != span(rra3_l).first<2u>());
2247
2248 // Comparing different types and different const-ness at the same time.
2249
2250 constexpr const int64_t arr2_lc[] = {1, 2};
2251 constexpr const int64_t arr3_lc[] = {1, 2, 3};
2252 constexpr const int64_t rra3_lc[] = {3, 2, 1};
2253
2254 EXPECT_TRUE((span<const int32_t>() == span<int64_t>()));
2255 EXPECT_TRUE((span<const int32_t, 0u>() == span<int64_t>()));
2256 EXPECT_TRUE((span<const int32_t>() == span<int64_t, 0u>()));
2257 EXPECT_TRUE((span<const int32_t, 0u>() == span<int64_t, 0u>()));
2258
2259 EXPECT_TRUE((span<int32_t>() == span<const int64_t>()));
2260 EXPECT_TRUE((span<int32_t, 0u>() == span<const int64_t>()));
2261 EXPECT_TRUE((span<int32_t>() == span<const int64_t, 0u>()));
2262 EXPECT_TRUE((span<int32_t, 0u>() == span<const int64_t, 0u>()));
2263
2264 EXPECT_TRUE(span(arr2_lc).first(0u) == span(arr2).last(0u));
2265 EXPECT_TRUE(span(arr2_lc).first<0u>() == span(arr2).last<0u>());
2266
2267 EXPECT_TRUE(span(arr2).first(0u) == span(arr2_lc).last(0u));
2268 EXPECT_TRUE(span(arr2).first<0u>() == span(arr2_lc).last<0u>());
2269
2270 EXPECT_TRUE(span(arr2_lc).first(2u) != span(arr3).first(3u));
2271 EXPECT_TRUE(span(arr2_lc).first(2u) == span(arr3).first(2u));
2272 EXPECT_TRUE(span(arr2_lc).first(2u) != span(rra3).first(2u));
2273
2274 EXPECT_TRUE(span(arr2).first(2u) != span(arr3_lc).first(3u));
2275 EXPECT_TRUE(span(arr2).first(2u) == span(arr3_lc).first(2u));
2276 EXPECT_TRUE(span(arr2).first(2u) != span(rra3_lc).first(2u));
2277
2278 EXPECT_TRUE(span(arr2_lc).first<2u>() != span(arr3).first(3u));
2279 EXPECT_TRUE(span(arr2_lc).first(2u) != span(arr3).first<3u>());
2280 EXPECT_TRUE(span(arr2_lc).first<2u>() == span(arr3).first(2u));
2281 EXPECT_TRUE(span(arr2_lc).first(2u) == span(arr3).first<2u>());
2282 EXPECT_TRUE(span(arr2_lc).first<2u>() != span(rra3).first(2u));
2283 EXPECT_TRUE(span(arr2_lc).first(2u) != span(rra3).first<2u>());
2284
2285 EXPECT_TRUE(span(arr2).first<2u>() != span(arr3_lc).first(3u));
2286 EXPECT_TRUE(span(arr2).first(2u) != span(arr3_lc).first<3u>());
2287 EXPECT_TRUE(span(arr2).first<2u>() == span(arr3_lc).first(2u));
2288 EXPECT_TRUE(span(arr2).first(2u) == span(arr3_lc).first<2u>());
2289 EXPECT_TRUE(span(arr2).first<2u>() != span(rra3_lc).first(2u));
2290 EXPECT_TRUE(span(arr2).first(2u) != span(rra3_lc).first<2u>());
2291
2292 // Comparing with an implicit conversion to span. This only works if the span
2293 // types actually match (i.e. not for any comparable types) since otherwise
2294 // the type can not be deduced. Implicit conversion from mutable to const
2295 // can be inferred though.
2296
2297 EXPECT_TRUE(arr2 != span(arr3).first(3u));
2298 EXPECT_TRUE(arr2 == span(arr3).first(2u));
2299 EXPECT_TRUE(arr2 != span(rra3).first(2u));
2300
2301 EXPECT_TRUE(arr2 != span(arr3_c).first(3u));
2302 EXPECT_TRUE(arr2 == span(arr3_c).first(2u));
2303 EXPECT_TRUE(arr2 != span(rra3_c).first(2u));
2304
2305 EXPECT_TRUE(arr2_c != span(arr3).first(3u));
2306 EXPECT_TRUE(arr2_c == span(arr3).first(2u));
2307 EXPECT_TRUE(arr2_c != span(rra3).first(2u));
2308
2309 // Constexpr comparison.
2310 static_assert(span<int>() == span<int, 0u>());
2311 static_assert(span(arr2_c) == span(arr3_c).first(2u));
2312 static_assert(span(arr2_c) == span(arr3_lc).first(2u));
2313 }
2314
2315 } // namespace base
2316
2317 // Test for compatibility with std::span<>, in case some third-party
2318 // API decides to use it. The size() and data() convention should mean
2319 // that everyone's spans are compatible with each other.
TEST(SpanTest,FromStdSpan)2320 TEST(SpanTest, FromStdSpan) {
2321 int kData[] = {10, 11, 12};
2322 std::span<const int> std_span(kData);
2323 std::span<int> mut_std_span(kData);
2324 std::span<const int, 3u> fixed_std_span(kData);
2325 std::span<int, 3u> mut_fixed_std_span(kData);
2326
2327 // Tests *implicit* conversions through assignment construction.
2328 {
2329 base::span<const int> base_span = std_span;
2330 EXPECT_EQ(base_span.size(), 3u);
2331 EXPECT_EQ(base_span.data(), kData);
2332 }
2333 {
2334 base::span<const int> base_span = mut_std_span;
2335 EXPECT_EQ(base_span.size(), 3u);
2336 EXPECT_EQ(base_span.data(), kData);
2337 }
2338 {
2339 base::span<const int> base_span = fixed_std_span;
2340 EXPECT_EQ(base_span.size(), 3u);
2341 EXPECT_EQ(base_span.data(), kData);
2342 }
2343 {
2344 base::span<const int> base_span = mut_fixed_std_span;
2345 EXPECT_EQ(base_span.size(), 3u);
2346 EXPECT_EQ(base_span.data(), kData);
2347 }
2348
2349 {
2350 base::span<const int, 3u> base_span = fixed_std_span;
2351 EXPECT_EQ(base_span.size(), 3u);
2352 EXPECT_EQ(base_span.data(), kData);
2353 }
2354 {
2355 base::span<const int, 3u> base_span = mut_fixed_std_span;
2356 EXPECT_EQ(base_span.size(), 3u);
2357 EXPECT_EQ(base_span.data(), kData);
2358 }
2359 {
2360 base::span<int, 3u> base_span = mut_fixed_std_span;
2361 EXPECT_EQ(base_span.size(), 3u);
2362 EXPECT_EQ(base_span.data(), kData);
2363 }
2364
2365 {
2366 auto base_made_span = base::make_span(std_span);
2367 EXPECT_EQ(base_made_span.size(), 3u);
2368 EXPECT_EQ(base_made_span.data(), kData);
2369 }
2370 {
2371 auto base_byte_span = base::as_byte_span(std_span);
2372 EXPECT_EQ(base_byte_span.size(), sizeof(int) * 3u);
2373 EXPECT_EQ(base_byte_span.data(), reinterpret_cast<const uint8_t*>(kData));
2374 }
2375 }
2376
TEST(SpanTest,ToStdSpan)2377 TEST(SpanTest, ToStdSpan) {
2378 int kData[] = {10, 11, 12};
2379 base::span<const int> base_span(kData);
2380 base::span<int> mut_base_span(kData);
2381 base::span<const int, 3u> fixed_base_span(kData);
2382 base::span<int, 3u> mut_fixed_base_span(kData);
2383
2384 // Tests *implicit* conversions through assignment construction.
2385 {
2386 std::span<const int> std_span = base_span;
2387 EXPECT_EQ(std_span.size(), 3u);
2388 EXPECT_EQ(std_span.data(), kData);
2389 }
2390 {
2391 std::span<const int> std_span = mut_base_span;
2392 EXPECT_EQ(std_span.size(), 3u);
2393 EXPECT_EQ(std_span.data(), kData);
2394 }
2395 {
2396 std::span<const int> std_span = fixed_base_span;
2397 EXPECT_EQ(std_span.size(), 3u);
2398 EXPECT_EQ(std_span.data(), kData);
2399 }
2400 {
2401 std::span<const int> std_span = mut_fixed_base_span;
2402 EXPECT_EQ(std_span.size(), 3u);
2403 EXPECT_EQ(std_span.data(), kData);
2404 }
2405
2406 {
2407 std::span<const int, 3u> std_span = fixed_base_span;
2408 EXPECT_EQ(std_span.size(), 3u);
2409 EXPECT_EQ(std_span.data(), kData);
2410 }
2411 {
2412 std::span<const int, 3u> std_span = mut_fixed_base_span;
2413 EXPECT_EQ(std_span.size(), 3u);
2414 EXPECT_EQ(std_span.data(), kData);
2415 }
2416 {
2417 std::span<int, 3u> std_span = mut_fixed_base_span;
2418 EXPECT_EQ(std_span.size(), 3u);
2419 EXPECT_EQ(std_span.data(), kData);
2420 }
2421
2422 // no make_span() or as_byte_span() in std::span.
2423 }
2424