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 <iterator>
11 #include <memory>
12 #include <string>
13 #include <type_traits>
14 #include <utility>
15 #include <vector>
16
17 #include "base/containers/adapters.h"
18 #include "base/containers/checked_iterators.h"
19 #include "base/ranges/algorithm.h"
20 #include "base/strings/string_piece.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using ::testing::ElementsAre;
25 using ::testing::Eq;
26 using ::testing::Pointwise;
27
28 namespace base {
29
30 namespace {
31
32 // Tests for span(It, StrictNumeric<size_t>) deduction guide. These tests use a
33 // helper function to wrap the static_asserts, as most STL containers don't work
34 // well in a constexpr context. std::array<T, N> does, but base::span has
35 // specific overloads for std::array<T, n>, so that ends up being less helpful
36 // than it would initially appear.
37 //
38 // Another alternative would be to use std::declval, but that would be fairly
39 // verbose.
TestDeductionGuides()40 [[maybe_unused]] void TestDeductionGuides() {
41 // Tests for span(It, EndOrSize) deduction guide.
42 {
43 const std::vector<int> v;
44 static_assert(
45 std::is_same_v<decltype(span(v.cbegin(), v.size())), span<const int>>);
46 static_assert(
47 std::is_same_v<decltype(span(v.begin(), v.size())), span<const int>>);
48 static_assert(
49 std::is_same_v<decltype(span(v.data(), v.size())), span<const int>>);
50 }
51
52 {
53 std::vector<int> v;
54 static_assert(
55 std::is_same_v<decltype(span(v.cbegin(), v.size())), span<const int>>);
56 static_assert(
57 std::is_same_v<decltype(span(v.begin(), v.size())), span<int>>);
58 static_assert(
59 std::is_same_v<decltype(span(v.data(), v.size())), span<int>>);
60 }
61
62 {
63 const std::vector<int> v;
64 static_assert(
65 std::is_same_v<decltype(span(v.cbegin(), v.cend())), span<const int>>);
66 static_assert(
67 std::is_same_v<decltype(span(v.begin(), v.end())), span<const int>>);
68 }
69
70 {
71 std::vector<int> v;
72 static_assert(
73 std::is_same_v<decltype(span(v.cbegin(), v.cend())), span<const int>>);
74 static_assert(
75 std::is_same_v<decltype(span(v.begin(), v.end())), span<int>>);
76 }
77
78 // Tests for span(Range&&) deduction guide.
79 {
80 const int kArray[] = {1, 2, 3};
81 static_assert(std::is_same_v<decltype(span(kArray)), span<const int, 3>>);
82 }
83 {
84 int kArray[] = {1, 2, 3};
85 static_assert(std::is_same_v<decltype(span(kArray)), span<int, 3>>);
86 }
87
88 static_assert(
89 std::is_same_v<decltype(span(std::declval<std::array<const bool, 3>&>())),
90 span<const bool, 3>>);
91 static_assert(
92 std::is_same_v<decltype(span(std::declval<std::array<bool, 3>&>())),
93 span<bool, 3>>);
94
95 static_assert(
96 std::is_same_v<decltype(span(
97 std::declval<const std::array<const bool, 3>&>())),
98 span<const bool, 3>>);
99 static_assert(
100 std::is_same_v<decltype(span(
101 std::declval<const std::array<const bool, 3>&&>())),
102 span<const bool, 3>>);
103 static_assert(std::is_same_v<
104 decltype(span(std::declval<std::array<const bool, 3>&&>())),
105 span<const bool, 3>>);
106 static_assert(
107 std::is_same_v<decltype(span(std::declval<const std::array<bool, 3>&>())),
108 span<const bool, 3>>);
109 static_assert(std::is_same_v<
110 decltype(span(std::declval<const std::array<bool, 3>&&>())),
111 span<const bool, 3>>);
112 static_assert(
113 std::is_same_v<decltype(span(std::declval<std::array<bool, 3>&&>())),
114 span<const bool, 3>>);
115
116 static_assert(
117 std::is_same_v<decltype(span(std::declval<const std::string&>())),
118 span<const char>>);
119 static_assert(
120 std::is_same_v<decltype(span(std::declval<const std::string&&>())),
121 span<const char>>);
122 static_assert(
123 std::is_same_v<decltype(span(std::declval<std::string&>())), span<char>>);
124 static_assert(std::is_same_v<decltype(span(std::declval<std::string&&>())),
125 span<const char>>);
126 static_assert(
127 std::is_same_v<decltype(span(std::declval<const std::u16string&>())),
128 span<const char16_t>>);
129 static_assert(
130 std::is_same_v<decltype(span(std::declval<const std::u16string&&>())),
131 span<const char16_t>>);
132 static_assert(std::is_same_v<decltype(span(std::declval<std::u16string&>())),
133 span<char16_t>>);
134 static_assert(std::is_same_v<decltype(span(std::declval<std::u16string&&>())),
135 span<const char16_t>>);
136 static_assert(std::is_same_v<
137 decltype(span(std::declval<const std::array<float, 9>&>())),
138 span<const float, 9>>);
139 static_assert(std::is_same_v<
140 decltype(span(std::declval<const std::array<float, 9>&&>())),
141 span<const float, 9>>);
142 static_assert(
143 std::is_same_v<decltype(span(std::declval<std::array<float, 9>&>())),
144 span<float, 9>>);
145 static_assert(
146 std::is_same_v<decltype(span(std::declval<std::array<float, 9>&&>())),
147 span<const float, 9>>);
148 }
149
150 } // namespace
151
TEST(SpanTest,DefaultConstructor)152 TEST(SpanTest, DefaultConstructor) {
153 span<int> dynamic_span;
154 EXPECT_EQ(nullptr, dynamic_span.data());
155 EXPECT_EQ(0u, dynamic_span.size());
156
157 constexpr span<int, 0> static_span;
158 static_assert(nullptr == static_span.data(), "");
159 static_assert(0u == static_span.size(), "");
160 }
161
TEST(SpanTest,ConstructFromDataAndSize)162 TEST(SpanTest, ConstructFromDataAndSize) {
163 constexpr int* kNull = nullptr;
164 constexpr span<int> empty_span(kNull, 0u);
165 EXPECT_TRUE(empty_span.empty());
166 EXPECT_EQ(nullptr, empty_span.data());
167
168 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
169
170 span<int> dynamic_span(vector.data(), vector.size());
171 EXPECT_EQ(vector.data(), dynamic_span.data());
172 EXPECT_EQ(vector.size(), dynamic_span.size());
173
174 for (size_t i = 0; i < dynamic_span.size(); ++i)
175 EXPECT_EQ(vector[i], dynamic_span[i]);
176
177 span<int, 6> static_span(vector.data(), vector.size());
178 EXPECT_EQ(vector.data(), static_span.data());
179 EXPECT_EQ(vector.size(), static_span.size());
180
181 for (size_t i = 0; i < static_span.size(); ++i)
182 EXPECT_EQ(vector[i], static_span[i]);
183 }
184
TEST(SpanTest,ConstructFromIterAndSize)185 TEST(SpanTest, ConstructFromIterAndSize) {
186 constexpr int* kNull = nullptr;
187 constexpr span<int> empty_span(kNull, 0u);
188 EXPECT_TRUE(empty_span.empty());
189 EXPECT_EQ(nullptr, empty_span.data());
190
191 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
192
193 span<int> dynamic_span(vector.begin(), vector.size());
194 EXPECT_EQ(vector.data(), dynamic_span.data());
195 EXPECT_EQ(vector.size(), dynamic_span.size());
196
197 for (size_t i = 0; i < dynamic_span.size(); ++i)
198 EXPECT_EQ(vector[i], dynamic_span[i]);
199
200 span<int, 6> static_span(vector.begin(), vector.size());
201 EXPECT_EQ(vector.data(), static_span.data());
202 EXPECT_EQ(vector.size(), static_span.size());
203
204 for (size_t i = 0; i < static_span.size(); ++i)
205 EXPECT_EQ(vector[i], static_span[i]);
206 }
207
TEST(SpanTest,ConstructFromIterPair)208 TEST(SpanTest, ConstructFromIterPair) {
209 constexpr int* kNull = nullptr;
210 constexpr span<int> empty_span(kNull, kNull);
211 EXPECT_TRUE(empty_span.empty());
212 EXPECT_EQ(nullptr, empty_span.data());
213
214 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
215
216 span<int> dynamic_span(vector.begin(), vector.begin() + vector.size() / 2);
217 EXPECT_EQ(vector.data(), dynamic_span.data());
218 EXPECT_EQ(vector.size() / 2, dynamic_span.size());
219
220 for (size_t i = 0; i < dynamic_span.size(); ++i)
221 EXPECT_EQ(vector[i], dynamic_span[i]);
222
223 span<int, 3> static_span(vector.begin(), vector.begin() + vector.size() / 2);
224 EXPECT_EQ(vector.data(), static_span.data());
225 EXPECT_EQ(vector.size() / 2, static_span.size());
226
227 for (size_t i = 0; i < static_span.size(); ++i)
228 EXPECT_EQ(vector[i], static_span[i]);
229 }
230
TEST(SpanTest,AllowedConversionsFromStdArray)231 TEST(SpanTest, AllowedConversionsFromStdArray) {
232 // In the following assertions we use std::is_convertible_v<From, To>, which
233 // for non-void types is equivalent to checking whether the following
234 // expression is well-formed:
235 //
236 // T obj = std::declval<From>();
237 //
238 // In particular we are checking whether From is implicitly convertible to To,
239 // which also implies that To is explicitly constructible from From.
240 static_assert(
241 std::is_convertible_v<std::array<int, 3>&, base::span<int>>,
242 "Error: l-value reference to std::array<int> should be convertible to "
243 "base::span<int> with dynamic extent.");
244 static_assert(
245 std::is_convertible_v<std::array<int, 3>&, base::span<int, 3>>,
246 "Error: l-value reference to std::array<int> should be convertible to "
247 "base::span<int> with the same static extent.");
248 static_assert(
249 std::is_convertible_v<std::array<int, 3>&, base::span<const int>>,
250 "Error: l-value reference to std::array<int> should be convertible to "
251 "base::span<const int> with dynamic extent.");
252 static_assert(
253 std::is_convertible_v<std::array<int, 3>&, base::span<const int, 3>>,
254 "Error: l-value reference to std::array<int> should be convertible to "
255 "base::span<const int> with the same static extent.");
256 static_assert(
257 std::is_convertible_v<const std::array<int, 3>&, base::span<const int>>,
258 "Error: const l-value reference to std::array<int> should be "
259 "convertible to base::span<const int> with dynamic extent.");
260 static_assert(
261 std::is_convertible_v<const std::array<int, 3>&,
262 base::span<const int, 3>>,
263 "Error: const l-value reference to std::array<int> should be convertible "
264 "to base::span<const int> with the same static extent.");
265 static_assert(
266 std::is_convertible_v<std::array<const int, 3>&, base::span<const int>>,
267 "Error: l-value reference to std::array<const int> should be "
268 "convertible to base::span<const int> with dynamic extent.");
269 static_assert(
270 std::is_convertible_v<std::array<const int, 3>&,
271 base::span<const int, 3>>,
272 "Error: l-value reference to std::array<const int> should be convertible "
273 "to base::span<const int> with the same static extent.");
274 static_assert(
275 std::is_convertible_v<const std::array<const int, 3>&,
276 base::span<const int>>,
277 "Error: const l-value reference to std::array<const int> should be "
278 "convertible to base::span<const int> with dynamic extent.");
279 static_assert(
280 std::is_convertible_v<const std::array<const int, 3>&,
281 base::span<const int, 3>>,
282 "Error: const l-value reference to std::array<const int> should be "
283 "convertible to base::span<const int> with the same static extent.");
284 }
285
TEST(SpanTest,DisallowedConstructionsFromStdArray)286 TEST(SpanTest, DisallowedConstructionsFromStdArray) {
287 // In the following assertions we use !std::is_constructible_v<T, Args>, which
288 // is equivalent to checking whether the following expression is malformed:
289 //
290 // T obj(std::declval<Args>()...);
291 //
292 // In particular we are checking that T is not explicitly constructible from
293 // Args, which also implies that T is not implicitly constructible from Args
294 // as well.
295 static_assert(
296 !std::is_constructible_v<base::span<int>, const std::array<int, 3>&>,
297 "Error: base::span<int> with dynamic extent should not be constructible "
298 "from const l-value reference to std::array<int>");
299
300 static_assert(
301 !std::is_constructible_v<base::span<int>, std::array<const int, 3>&>,
302 "Error: base::span<int> with dynamic extent should not be constructible "
303 "from l-value reference to std::array<const int>");
304
305 static_assert(
306 !std::is_constructible_v<base::span<int>,
307 const std::array<const int, 3>&>,
308 "Error: base::span<int> with dynamic extent should not be constructible "
309 "const from l-value reference to std::array<const int>");
310
311 static_assert(
312 !std::is_constructible_v<base::span<int, 2>, std::array<int, 3>&>,
313 "Error: base::span<int> with static extent should not be constructible "
314 "from l-value reference to std::array<int> with different extent");
315
316 static_assert(
317 !std::is_constructible_v<base::span<int, 4>, std::array<int, 3>&>,
318 "Error: base::span<int> with dynamic extent should not be constructible "
319 "from l-value reference to std::array<int> with different extent");
320
321 static_assert(
322 !std::is_constructible_v<base::span<int>, std::array<bool, 3>&>,
323 "Error: base::span<int> with dynamic extent should not be constructible "
324 "from l-value reference to std::array<bool>");
325 }
326
TEST(SpanTest,ConstructFromConstexprArray)327 TEST(SpanTest, ConstructFromConstexprArray) {
328 static constexpr int kArray[] = {5, 4, 3, 2, 1};
329
330 constexpr span<const int> dynamic_span(kArray);
331 static_assert(kArray == dynamic_span.data(), "");
332 static_assert(std::size(kArray) == dynamic_span.size(), "");
333
334 static_assert(kArray[0] == dynamic_span[0], "");
335 static_assert(kArray[1] == dynamic_span[1], "");
336 static_assert(kArray[2] == dynamic_span[2], "");
337 static_assert(kArray[3] == dynamic_span[3], "");
338 static_assert(kArray[4] == dynamic_span[4], "");
339
340 constexpr span<const int, std::size(kArray)> static_span(kArray);
341 static_assert(kArray == static_span.data(), "");
342 static_assert(std::size(kArray) == static_span.size(), "");
343
344 static_assert(kArray[0] == static_span[0], "");
345 static_assert(kArray[1] == static_span[1], "");
346 static_assert(kArray[2] == static_span[2], "");
347 static_assert(kArray[3] == static_span[3], "");
348 static_assert(kArray[4] == static_span[4], "");
349 }
350
TEST(SpanTest,ConstructFromArray)351 TEST(SpanTest, ConstructFromArray) {
352 int array[] = {5, 4, 3, 2, 1};
353
354 span<const int> const_span(array);
355 EXPECT_EQ(array, const_span.data());
356 EXPECT_EQ(std::size(array), const_span.size());
357 for (size_t i = 0; i < const_span.size(); ++i)
358 EXPECT_EQ(array[i], const_span[i]);
359
360 span<int> dynamic_span(array);
361 EXPECT_EQ(array, dynamic_span.data());
362 EXPECT_EQ(std::size(array), dynamic_span.size());
363 for (size_t i = 0; i < dynamic_span.size(); ++i)
364 EXPECT_EQ(array[i], dynamic_span[i]);
365
366 span<int, std::size(array)> static_span(array);
367 EXPECT_EQ(array, static_span.data());
368 EXPECT_EQ(std::size(array), static_span.size());
369 for (size_t i = 0; i < static_span.size(); ++i)
370 EXPECT_EQ(array[i], static_span[i]);
371 }
372
TEST(SpanTest,ConstructFromVolatileArray)373 TEST(SpanTest, ConstructFromVolatileArray) {
374 static volatile int array[] = {5, 4, 3, 2, 1};
375
376 span<const volatile int> const_span(array);
377 static_assert(std::is_same_v<decltype(&const_span[1]), const volatile int*>);
378 static_assert(
379 std::is_same_v<decltype(const_span.data()), const volatile int*>);
380 EXPECT_EQ(array, const_span.data());
381 EXPECT_EQ(std::size(array), const_span.size());
382 for (size_t i = 0; i < const_span.size(); ++i) {
383 EXPECT_EQ(array[i], const_span[i]);
384 }
385
386 span<volatile int> dynamic_span(array);
387 static_assert(std::is_same_v<decltype(&dynamic_span[1]), volatile int*>);
388 static_assert(std::is_same_v<decltype(dynamic_span.data()), volatile int*>);
389 EXPECT_EQ(array, dynamic_span.data());
390 EXPECT_EQ(std::size(array), dynamic_span.size());
391 for (size_t i = 0; i < dynamic_span.size(); ++i) {
392 EXPECT_EQ(array[i], dynamic_span[i]);
393 }
394
395 span<volatile int, std::size(array)> static_span(array);
396 static_assert(std::is_same_v<decltype(&static_span[1]), volatile int*>);
397 static_assert(std::is_same_v<decltype(static_span.data()), volatile int*>);
398 EXPECT_EQ(array, static_span.data());
399 EXPECT_EQ(std::size(array), static_span.size());
400 for (size_t i = 0; i < static_span.size(); ++i) {
401 EXPECT_EQ(array[i], static_span[i]);
402 }
403 }
404
TEST(SpanTest,ConstructFromStdArray)405 TEST(SpanTest, ConstructFromStdArray) {
406 // Note: Constructing a constexpr span from a constexpr std::array does not
407 // work prior to C++17 due to non-constexpr std::array::data.
408 std::array<int, 5> array = {{5, 4, 3, 2, 1}};
409
410 span<const int> const_span(array);
411 EXPECT_EQ(array.data(), const_span.data());
412 EXPECT_EQ(array.size(), const_span.size());
413 for (size_t i = 0; i < const_span.size(); ++i)
414 EXPECT_EQ(array[i], const_span[i]);
415
416 span<int> dynamic_span(array);
417 EXPECT_EQ(array.data(), dynamic_span.data());
418 EXPECT_EQ(array.size(), dynamic_span.size());
419 for (size_t i = 0; i < dynamic_span.size(); ++i)
420 EXPECT_EQ(array[i], dynamic_span[i]);
421
422 span<int, std::size(array)> static_span(array);
423 EXPECT_EQ(array.data(), static_span.data());
424 EXPECT_EQ(array.size(), static_span.size());
425 for (size_t i = 0; i < static_span.size(); ++i)
426 EXPECT_EQ(array[i], static_span[i]);
427 }
428
TEST(SpanTest,ConstructFromInitializerList)429 TEST(SpanTest, ConstructFromInitializerList) {
430 std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
431
432 span<const int> const_span(il);
433 EXPECT_EQ(il.begin(), const_span.data());
434 EXPECT_EQ(il.size(), const_span.size());
435
436 for (size_t i = 0; i < const_span.size(); ++i)
437 EXPECT_EQ(il.begin()[i], const_span[i]);
438
439 span<const int, 6> static_span(il.begin(), il.end());
440 EXPECT_EQ(il.begin(), static_span.data());
441 EXPECT_EQ(il.size(), static_span.size());
442
443 for (size_t i = 0; i < static_span.size(); ++i)
444 EXPECT_EQ(il.begin()[i], static_span[i]);
445 }
446
TEST(SpanTest,ConstructFromStdString)447 TEST(SpanTest, ConstructFromStdString) {
448 std::string str = "foobar";
449
450 span<const char> const_span(str);
451 EXPECT_EQ(str.data(), const_span.data());
452 EXPECT_EQ(str.size(), const_span.size());
453
454 for (size_t i = 0; i < const_span.size(); ++i)
455 EXPECT_EQ(str[i], const_span[i]);
456
457 span<char> dynamic_span(str);
458 EXPECT_EQ(str.data(), dynamic_span.data());
459 EXPECT_EQ(str.size(), dynamic_span.size());
460
461 for (size_t i = 0; i < dynamic_span.size(); ++i)
462 EXPECT_EQ(str[i], dynamic_span[i]);
463
464 span<char, 6> static_span(data(str), str.size());
465 EXPECT_EQ(str.data(), static_span.data());
466 EXPECT_EQ(str.size(), static_span.size());
467
468 for (size_t i = 0; i < static_span.size(); ++i)
469 EXPECT_EQ(str[i], static_span[i]);
470 }
471
TEST(SpanTest,ConstructFromConstContainer)472 TEST(SpanTest, ConstructFromConstContainer) {
473 const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
474
475 span<const int> const_span(vector);
476 EXPECT_EQ(vector.data(), const_span.data());
477 EXPECT_EQ(vector.size(), const_span.size());
478
479 for (size_t i = 0; i < const_span.size(); ++i)
480 EXPECT_EQ(vector[i], const_span[i]);
481
482 span<const int, 6> static_span(vector.data(), vector.size());
483 EXPECT_EQ(vector.data(), static_span.data());
484 EXPECT_EQ(vector.size(), static_span.size());
485
486 for (size_t i = 0; i < static_span.size(); ++i)
487 EXPECT_EQ(vector[i], static_span[i]);
488 }
489
TEST(SpanTest,ConstructFromContainer)490 TEST(SpanTest, ConstructFromContainer) {
491 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
492
493 span<const int> const_span(vector);
494 EXPECT_EQ(vector.data(), const_span.data());
495 EXPECT_EQ(vector.size(), const_span.size());
496
497 for (size_t i = 0; i < const_span.size(); ++i)
498 EXPECT_EQ(vector[i], const_span[i]);
499
500 span<int> dynamic_span(vector);
501 EXPECT_EQ(vector.data(), dynamic_span.data());
502 EXPECT_EQ(vector.size(), dynamic_span.size());
503
504 for (size_t i = 0; i < dynamic_span.size(); ++i)
505 EXPECT_EQ(vector[i], dynamic_span[i]);
506
507 span<int, 6> static_span(vector.data(), vector.size());
508 EXPECT_EQ(vector.data(), static_span.data());
509 EXPECT_EQ(vector.size(), static_span.size());
510
511 for (size_t i = 0; i < static_span.size(); ++i)
512 EXPECT_EQ(vector[i], static_span[i]);
513 }
514
TEST(SpanTest,ConvertNonConstIntegralToConst)515 TEST(SpanTest, ConvertNonConstIntegralToConst) {
516 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
517
518 span<int> int_span(vector.data(), vector.size());
519 span<const int> const_span(int_span);
520 EXPECT_EQ(int_span.size(), const_span.size());
521
522 EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
523
524 span<int, 6> static_int_span(vector.data(), vector.size());
525 span<const int, 6> static_const_span(static_int_span);
526 EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
527 }
528
TEST(SpanTest,ConvertNonConstPointerToConst)529 TEST(SpanTest, ConvertNonConstPointerToConst) {
530 auto a = std::make_unique<int>(11);
531 auto b = std::make_unique<int>(22);
532 auto c = std::make_unique<int>(33);
533 std::vector<int*> vector = {a.get(), b.get(), c.get()};
534
535 span<int*> non_const_pointer_span(vector);
536 EXPECT_THAT(non_const_pointer_span, Pointwise(Eq(), vector));
537 span<int* const> const_pointer_span(non_const_pointer_span);
538 EXPECT_THAT(const_pointer_span, Pointwise(Eq(), non_const_pointer_span));
539 // Note: no test for conversion from span<int> to span<const int*>, since that
540 // would imply a conversion from int** to const int**, which is unsafe.
541 //
542 // Note: no test for conversion from span<int*> to span<const int* const>,
543 // due to CWG Defect 330:
544 // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
545
546 span<int*, 3> static_non_const_pointer_span(vector.data(), vector.size());
547 EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
548 span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
549 EXPECT_THAT(static_const_pointer_span,
550 Pointwise(Eq(), static_non_const_pointer_span));
551 }
552
TEST(SpanTest,ConvertBetweenEquivalentTypes)553 TEST(SpanTest, ConvertBetweenEquivalentTypes) {
554 std::vector<int32_t> vector = {2, 4, 8, 16, 32};
555
556 span<int32_t> int32_t_span(vector);
557 span<int> converted_span(int32_t_span);
558 EXPECT_EQ(int32_t_span.data(), converted_span.data());
559 EXPECT_EQ(int32_t_span.size(), converted_span.size());
560
561 span<int32_t, 5> static_int32_t_span(vector.data(), vector.size());
562 span<int, 5> static_converted_span(static_int32_t_span);
563 EXPECT_EQ(static_int32_t_span.data(), static_converted_span.data());
564 EXPECT_EQ(static_int32_t_span.size(), static_converted_span.size());
565 }
566
TEST(SpanTest,TemplatedFirst)567 TEST(SpanTest, TemplatedFirst) {
568 static constexpr int array[] = {1, 2, 3};
569 constexpr span<const int, 3> span(array);
570
571 {
572 constexpr auto subspan = span.first<0>();
573 static_assert(span.data() == subspan.data(), "");
574 static_assert(0u == subspan.size(), "");
575 static_assert(0u == decltype(subspan)::extent, "");
576 }
577
578 {
579 constexpr auto subspan = span.first<1>();
580 static_assert(span.data() == subspan.data(), "");
581 static_assert(1u == subspan.size(), "");
582 static_assert(1u == decltype(subspan)::extent, "");
583 static_assert(1 == subspan[0], "");
584 }
585
586 {
587 constexpr auto subspan = span.first<2>();
588 static_assert(span.data() == subspan.data(), "");
589 static_assert(2u == subspan.size(), "");
590 static_assert(2u == decltype(subspan)::extent, "");
591 static_assert(1 == subspan[0], "");
592 static_assert(2 == subspan[1], "");
593 }
594
595 {
596 constexpr auto subspan = span.first<3>();
597 static_assert(span.data() == subspan.data(), "");
598 static_assert(3u == subspan.size(), "");
599 static_assert(3u == decltype(subspan)::extent, "");
600 static_assert(1 == subspan[0], "");
601 static_assert(2 == subspan[1], "");
602 static_assert(3 == subspan[2], "");
603 }
604 }
605
TEST(SpanTest,TemplatedLast)606 TEST(SpanTest, TemplatedLast) {
607 static constexpr int array[] = {1, 2, 3};
608 constexpr span<const int, 3> span(array);
609
610 {
611 constexpr auto subspan = span.last<0>();
612 static_assert(span.data() + 3 == subspan.data(), "");
613 static_assert(0u == subspan.size(), "");
614 static_assert(0u == decltype(subspan)::extent, "");
615 }
616
617 {
618 constexpr auto subspan = span.last<1>();
619 static_assert(span.data() + 2 == subspan.data(), "");
620 static_assert(1u == subspan.size(), "");
621 static_assert(1u == decltype(subspan)::extent, "");
622 static_assert(3 == subspan[0], "");
623 }
624
625 {
626 constexpr auto subspan = span.last<2>();
627 static_assert(span.data() + 1 == subspan.data(), "");
628 static_assert(2u == subspan.size(), "");
629 static_assert(2u == decltype(subspan)::extent, "");
630 static_assert(2 == subspan[0], "");
631 static_assert(3 == subspan[1], "");
632 }
633
634 {
635 constexpr auto subspan = span.last<3>();
636 static_assert(span.data() == subspan.data(), "");
637 static_assert(3u == subspan.size(), "");
638 static_assert(3u == decltype(subspan)::extent, "");
639 static_assert(1 == subspan[0], "");
640 static_assert(2 == subspan[1], "");
641 static_assert(3 == subspan[2], "");
642 }
643 }
644
TEST(SpanTest,TemplatedSubspan)645 TEST(SpanTest, TemplatedSubspan) {
646 static constexpr int array[] = {1, 2, 3};
647 constexpr span<const int, 3> span(array);
648
649 {
650 constexpr auto subspan = span.subspan<0>();
651 static_assert(span.data() == subspan.data(), "");
652 static_assert(3u == subspan.size(), "");
653 static_assert(3u == decltype(subspan)::extent, "");
654 static_assert(1 == subspan[0], "");
655 static_assert(2 == subspan[1], "");
656 static_assert(3 == subspan[2], "");
657 }
658
659 {
660 constexpr auto subspan = span.subspan<1>();
661 static_assert(span.data() + 1 == subspan.data(), "");
662 static_assert(2u == subspan.size(), "");
663 static_assert(2u == decltype(subspan)::extent, "");
664 static_assert(2 == subspan[0], "");
665 static_assert(3 == subspan[1], "");
666 }
667
668 {
669 constexpr auto subspan = span.subspan<2>();
670 static_assert(span.data() + 2 == subspan.data(), "");
671 static_assert(1u == subspan.size(), "");
672 static_assert(1u == decltype(subspan)::extent, "");
673 static_assert(3 == subspan[0], "");
674 }
675
676 {
677 constexpr auto subspan = span.subspan<3>();
678 static_assert(span.data() + 3 == subspan.data(), "");
679 static_assert(0u == subspan.size(), "");
680 static_assert(0u == decltype(subspan)::extent, "");
681 }
682
683 {
684 constexpr auto subspan = span.subspan<0, 0>();
685 static_assert(span.data() == subspan.data(), "");
686 static_assert(0u == subspan.size(), "");
687 static_assert(0u == decltype(subspan)::extent, "");
688 }
689
690 {
691 constexpr auto subspan = span.subspan<1, 0>();
692 static_assert(span.data() + 1 == subspan.data(), "");
693 static_assert(0u == subspan.size(), "");
694 static_assert(0u == decltype(subspan)::extent, "");
695 }
696
697 {
698 constexpr auto subspan = span.subspan<2, 0>();
699 static_assert(span.data() + 2 == subspan.data(), "");
700 static_assert(0u == subspan.size(), "");
701 static_assert(0u == decltype(subspan)::extent, "");
702 }
703
704 {
705 constexpr auto subspan = span.subspan<0, 1>();
706 static_assert(span.data() == subspan.data(), "");
707 static_assert(1u == subspan.size(), "");
708 static_assert(1u == decltype(subspan)::extent, "");
709 static_assert(1 == subspan[0], "");
710 }
711
712 {
713 constexpr auto subspan = span.subspan<1, 1>();
714 static_assert(span.data() + 1 == subspan.data(), "");
715 static_assert(1u == subspan.size(), "");
716 static_assert(1u == decltype(subspan)::extent, "");
717 static_assert(2 == subspan[0], "");
718 }
719
720 {
721 constexpr auto subspan = span.subspan<2, 1>();
722 static_assert(span.data() + 2 == subspan.data(), "");
723 static_assert(1u == subspan.size(), "");
724 static_assert(1u == decltype(subspan)::extent, "");
725 static_assert(3 == subspan[0], "");
726 }
727
728 {
729 constexpr auto subspan = span.subspan<0, 2>();
730 static_assert(span.data() == subspan.data(), "");
731 static_assert(2u == subspan.size(), "");
732 static_assert(2u == decltype(subspan)::extent, "");
733 static_assert(1 == subspan[0], "");
734 static_assert(2 == subspan[1], "");
735 }
736
737 {
738 constexpr auto subspan = span.subspan<1, 2>();
739 static_assert(span.data() + 1 == subspan.data(), "");
740 static_assert(2u == subspan.size(), "");
741 static_assert(2u == decltype(subspan)::extent, "");
742 static_assert(2 == subspan[0], "");
743 static_assert(3 == subspan[1], "");
744 }
745
746 {
747 constexpr auto subspan = span.subspan<0, 3>();
748 static_assert(span.data() == subspan.data(), "");
749 static_assert(3u == subspan.size(), "");
750 static_assert(3u == decltype(subspan)::extent, "");
751 static_assert(1 == subspan[0], "");
752 static_assert(2 == subspan[1], "");
753 static_assert(3 == subspan[2], "");
754 }
755 }
756
TEST(SpanTest,SubscriptedBeginIterator)757 TEST(SpanTest, SubscriptedBeginIterator) {
758 int array[] = {1, 2, 3};
759 span<const int> const_span(array);
760 for (size_t i = 0; i < const_span.size(); ++i)
761 EXPECT_EQ(array[i], const_span.begin()[i]);
762
763 span<int> mutable_span(array);
764 for (size_t i = 0; i < mutable_span.size(); ++i)
765 EXPECT_EQ(array[i], mutable_span.begin()[i]);
766 }
767
TEST(SpanTest,TemplatedFirstOnDynamicSpan)768 TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
769 int array[] = {1, 2, 3};
770 span<const int> span(array);
771
772 {
773 auto subspan = span.first<0>();
774 EXPECT_EQ(span.data(), subspan.data());
775 EXPECT_EQ(0u, subspan.size());
776 static_assert(0u == decltype(subspan)::extent, "");
777 }
778
779 {
780 auto subspan = span.first<1>();
781 EXPECT_EQ(span.data(), subspan.data());
782 EXPECT_EQ(1u, subspan.size());
783 static_assert(1u == decltype(subspan)::extent, "");
784 EXPECT_EQ(1, subspan[0]);
785 }
786
787 {
788 auto subspan = span.first<2>();
789 EXPECT_EQ(span.data(), subspan.data());
790 EXPECT_EQ(2u, subspan.size());
791 static_assert(2u == decltype(subspan)::extent, "");
792 EXPECT_EQ(1, subspan[0]);
793 EXPECT_EQ(2, subspan[1]);
794 }
795
796 {
797 auto subspan = span.first<3>();
798 EXPECT_EQ(span.data(), subspan.data());
799 EXPECT_EQ(3u, subspan.size());
800 static_assert(3u == decltype(subspan)::extent, "");
801 EXPECT_EQ(1, subspan[0]);
802 EXPECT_EQ(2, subspan[1]);
803 EXPECT_EQ(3, subspan[2]);
804 }
805 }
806
TEST(SpanTest,TemplatedLastOnDynamicSpan)807 TEST(SpanTest, TemplatedLastOnDynamicSpan) {
808 int array[] = {1, 2, 3};
809 span<int> span(array);
810
811 {
812 auto subspan = span.last<0>();
813 EXPECT_EQ(span.data() + 3, subspan.data());
814 EXPECT_EQ(0u, subspan.size());
815 static_assert(0u == decltype(subspan)::extent, "");
816 }
817
818 {
819 auto subspan = span.last<1>();
820 EXPECT_EQ(span.data() + 2, subspan.data());
821 EXPECT_EQ(1u, subspan.size());
822 static_assert(1u == decltype(subspan)::extent, "");
823 EXPECT_EQ(3, subspan[0]);
824 }
825
826 {
827 auto subspan = span.last<2>();
828 EXPECT_EQ(span.data() + 1, subspan.data());
829 EXPECT_EQ(2u, subspan.size());
830 static_assert(2u == decltype(subspan)::extent, "");
831 EXPECT_EQ(2, subspan[0]);
832 EXPECT_EQ(3, subspan[1]);
833 }
834
835 {
836 auto subspan = span.last<3>();
837 EXPECT_EQ(span.data(), subspan.data());
838 EXPECT_EQ(3u, subspan.size());
839 static_assert(3u == decltype(subspan)::extent, "");
840 EXPECT_EQ(1, subspan[0]);
841 EXPECT_EQ(2, subspan[1]);
842 EXPECT_EQ(3, subspan[2]);
843 }
844 }
845
TEST(SpanTest,TemplatedSubspanFromDynamicSpan)846 TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
847 int array[] = {1, 2, 3};
848 span<int, 3> span(array);
849
850 {
851 auto subspan = span.subspan<0>();
852 EXPECT_EQ(span.data(), subspan.data());
853 static_assert(3u == decltype(subspan)::extent, "");
854 EXPECT_EQ(3u, subspan.size());
855 EXPECT_EQ(1, subspan[0]);
856 EXPECT_EQ(2, subspan[1]);
857 EXPECT_EQ(3, subspan[2]);
858 }
859
860 {
861 auto subspan = span.subspan<1>();
862 EXPECT_EQ(span.data() + 1, subspan.data());
863 EXPECT_EQ(2u, subspan.size());
864 static_assert(2u == decltype(subspan)::extent, "");
865 EXPECT_EQ(2, subspan[0]);
866 EXPECT_EQ(3, subspan[1]);
867 }
868
869 {
870 auto subspan = span.subspan<2>();
871 EXPECT_EQ(span.data() + 2, subspan.data());
872 EXPECT_EQ(1u, subspan.size());
873 static_assert(1u == decltype(subspan)::extent, "");
874 EXPECT_EQ(3, subspan[0]);
875 }
876
877 {
878 auto subspan = span.subspan<3>();
879 EXPECT_EQ(span.data() + 3, subspan.data());
880 EXPECT_EQ(0u, subspan.size());
881 static_assert(0u == decltype(subspan)::extent, "");
882 }
883
884 {
885 auto subspan = span.subspan<0, 0>();
886 EXPECT_EQ(span.data(), subspan.data());
887 EXPECT_EQ(0u, subspan.size());
888 static_assert(0u == decltype(subspan)::extent, "");
889 }
890
891 {
892 auto subspan = span.subspan<1, 0>();
893 EXPECT_EQ(span.data() + 1, subspan.data());
894 EXPECT_EQ(0u, subspan.size());
895 static_assert(0u == decltype(subspan)::extent, "");
896 }
897
898 {
899 auto subspan = span.subspan<2, 0>();
900 EXPECT_EQ(span.data() + 2, subspan.data());
901 EXPECT_EQ(0u, subspan.size());
902 static_assert(0u == decltype(subspan)::extent, "");
903 }
904
905 {
906 auto subspan = span.subspan<0, 1>();
907 EXPECT_EQ(span.data(), subspan.data());
908 EXPECT_EQ(1u, subspan.size());
909 static_assert(1u == decltype(subspan)::extent, "");
910 EXPECT_EQ(1, subspan[0]);
911 }
912
913 {
914 auto subspan = span.subspan<1, 1>();
915 EXPECT_EQ(span.data() + 1, subspan.data());
916 EXPECT_EQ(1u, subspan.size());
917 static_assert(1u == decltype(subspan)::extent, "");
918 EXPECT_EQ(2, subspan[0]);
919 }
920
921 {
922 auto subspan = span.subspan<2, 1>();
923 EXPECT_EQ(span.data() + 2, subspan.data());
924 EXPECT_EQ(1u, subspan.size());
925 static_assert(1u == decltype(subspan)::extent, "");
926 EXPECT_EQ(3, subspan[0]);
927 }
928
929 {
930 auto subspan = span.subspan<0, 2>();
931 EXPECT_EQ(span.data(), subspan.data());
932 EXPECT_EQ(2u, subspan.size());
933 static_assert(2u == decltype(subspan)::extent, "");
934 EXPECT_EQ(1, subspan[0]);
935 EXPECT_EQ(2, subspan[1]);
936 }
937
938 {
939 auto subspan = span.subspan<1, 2>();
940 EXPECT_EQ(span.data() + 1, subspan.data());
941 EXPECT_EQ(2u, subspan.size());
942 static_assert(2u == decltype(subspan)::extent, "");
943 EXPECT_EQ(2, subspan[0]);
944 EXPECT_EQ(3, subspan[1]);
945 }
946
947 {
948 auto subspan = span.subspan<0, 3>();
949 EXPECT_EQ(span.data(), subspan.data());
950 EXPECT_EQ(3u, subspan.size());
951 static_assert(3u == decltype(subspan)::extent, "");
952 EXPECT_EQ(1, subspan[0]);
953 EXPECT_EQ(2, subspan[1]);
954 EXPECT_EQ(3, subspan[2]);
955 }
956 }
957
TEST(SpanTest,First)958 TEST(SpanTest, First) {
959 int array[] = {1, 2, 3};
960 span<int> span(array);
961
962 {
963 auto subspan = span.first(0);
964 EXPECT_EQ(span.data(), subspan.data());
965 EXPECT_EQ(0u, subspan.size());
966 }
967
968 {
969 auto subspan = span.first(1);
970 EXPECT_EQ(span.data(), subspan.data());
971 EXPECT_EQ(1u, subspan.size());
972 EXPECT_EQ(1, subspan[0]);
973 }
974
975 {
976 auto subspan = span.first(2);
977 EXPECT_EQ(span.data(), subspan.data());
978 EXPECT_EQ(2u, subspan.size());
979 EXPECT_EQ(1, subspan[0]);
980 EXPECT_EQ(2, subspan[1]);
981 }
982
983 {
984 auto subspan = span.first(3);
985 EXPECT_EQ(span.data(), subspan.data());
986 EXPECT_EQ(3u, subspan.size());
987 EXPECT_EQ(1, subspan[0]);
988 EXPECT_EQ(2, subspan[1]);
989 EXPECT_EQ(3, subspan[2]);
990 }
991 }
992
TEST(SpanTest,Last)993 TEST(SpanTest, Last) {
994 int array[] = {1, 2, 3};
995 span<int> span(array);
996
997 {
998 auto subspan = span.last(0);
999 EXPECT_EQ(span.data() + 3, subspan.data());
1000 EXPECT_EQ(0u, subspan.size());
1001 }
1002
1003 {
1004 auto subspan = span.last(1);
1005 EXPECT_EQ(span.data() + 2, subspan.data());
1006 EXPECT_EQ(1u, subspan.size());
1007 EXPECT_EQ(3, subspan[0]);
1008 }
1009
1010 {
1011 auto subspan = span.last(2);
1012 EXPECT_EQ(span.data() + 1, subspan.data());
1013 EXPECT_EQ(2u, subspan.size());
1014 EXPECT_EQ(2, subspan[0]);
1015 EXPECT_EQ(3, subspan[1]);
1016 }
1017
1018 {
1019 auto subspan = span.last(3);
1020 EXPECT_EQ(span.data(), subspan.data());
1021 EXPECT_EQ(3u, subspan.size());
1022 EXPECT_EQ(1, subspan[0]);
1023 EXPECT_EQ(2, subspan[1]);
1024 EXPECT_EQ(3, subspan[2]);
1025 }
1026 }
1027
TEST(SpanTest,Subspan)1028 TEST(SpanTest, Subspan) {
1029 int array[] = {1, 2, 3};
1030 span<int> span(array);
1031
1032 {
1033 auto subspan = span.subspan(0);
1034 EXPECT_EQ(span.data(), subspan.data());
1035 EXPECT_EQ(3u, subspan.size());
1036 EXPECT_EQ(1, subspan[0]);
1037 EXPECT_EQ(2, subspan[1]);
1038 EXPECT_EQ(3, subspan[2]);
1039 }
1040
1041 {
1042 auto subspan = span.subspan(1);
1043 EXPECT_EQ(span.data() + 1, subspan.data());
1044 EXPECT_EQ(2u, subspan.size());
1045 EXPECT_EQ(2, subspan[0]);
1046 EXPECT_EQ(3, subspan[1]);
1047 }
1048
1049 {
1050 auto subspan = span.subspan(2);
1051 EXPECT_EQ(span.data() + 2, subspan.data());
1052 EXPECT_EQ(1u, subspan.size());
1053 EXPECT_EQ(3, subspan[0]);
1054 }
1055
1056 {
1057 auto subspan = span.subspan(3);
1058 EXPECT_EQ(span.data() + 3, subspan.data());
1059 EXPECT_EQ(0u, subspan.size());
1060 }
1061
1062 {
1063 auto subspan = span.subspan(0, 0);
1064 EXPECT_EQ(span.data(), subspan.data());
1065 EXPECT_EQ(0u, subspan.size());
1066 }
1067
1068 {
1069 auto subspan = span.subspan(1, 0);
1070 EXPECT_EQ(span.data() + 1, subspan.data());
1071 EXPECT_EQ(0u, subspan.size());
1072 }
1073
1074 {
1075 auto subspan = span.subspan(2, 0);
1076 EXPECT_EQ(span.data() + 2, subspan.data());
1077 EXPECT_EQ(0u, subspan.size());
1078 }
1079
1080 {
1081 auto subspan = span.subspan(0, 1);
1082 EXPECT_EQ(span.data(), subspan.data());
1083 EXPECT_EQ(1u, subspan.size());
1084 EXPECT_EQ(1, subspan[0]);
1085 }
1086
1087 {
1088 auto subspan = span.subspan(1, 1);
1089 EXPECT_EQ(span.data() + 1, subspan.data());
1090 EXPECT_EQ(1u, subspan.size());
1091 EXPECT_EQ(2, subspan[0]);
1092 }
1093
1094 {
1095 auto subspan = span.subspan(2, 1);
1096 EXPECT_EQ(span.data() + 2, subspan.data());
1097 EXPECT_EQ(1u, subspan.size());
1098 EXPECT_EQ(3, subspan[0]);
1099 }
1100
1101 {
1102 auto subspan = span.subspan(0, 2);
1103 EXPECT_EQ(span.data(), subspan.data());
1104 EXPECT_EQ(2u, subspan.size());
1105 EXPECT_EQ(1, subspan[0]);
1106 EXPECT_EQ(2, subspan[1]);
1107 }
1108
1109 {
1110 auto subspan = span.subspan(1, 2);
1111 EXPECT_EQ(span.data() + 1, subspan.data());
1112 EXPECT_EQ(2u, subspan.size());
1113 EXPECT_EQ(2, subspan[0]);
1114 EXPECT_EQ(3, subspan[1]);
1115 }
1116
1117 {
1118 auto subspan = span.subspan(0, 3);
1119 EXPECT_EQ(span.data(), subspan.data());
1120 EXPECT_EQ(span.size(), subspan.size());
1121 EXPECT_EQ(1, subspan[0]);
1122 EXPECT_EQ(2, subspan[1]);
1123 EXPECT_EQ(3, subspan[2]);
1124 }
1125 }
1126
TEST(SpanTest,Size)1127 TEST(SpanTest, Size) {
1128 {
1129 span<int> span;
1130 EXPECT_EQ(0u, span.size());
1131 }
1132
1133 {
1134 int array[] = {1, 2, 3};
1135 span<int> span(array);
1136 EXPECT_EQ(3u, span.size());
1137 }
1138 }
1139
TEST(SpanTest,SizeBytes)1140 TEST(SpanTest, SizeBytes) {
1141 {
1142 span<int> span;
1143 EXPECT_EQ(0u, span.size_bytes());
1144 }
1145
1146 {
1147 int array[] = {1, 2, 3};
1148 span<int> span(array);
1149 EXPECT_EQ(3u * sizeof(int), span.size_bytes());
1150 }
1151 }
1152
TEST(SpanTest,Empty)1153 TEST(SpanTest, Empty) {
1154 {
1155 span<int> span;
1156 EXPECT_TRUE(span.empty());
1157 }
1158
1159 {
1160 int array[] = {1, 2, 3};
1161 span<int> span(array);
1162 EXPECT_FALSE(span.empty());
1163 }
1164
1165 {
1166 std::vector<int> vector = {1, 2, 3};
1167 span<int> s = vector;
1168 span<int> span_of_checked_iterators = {s.end(), s.end()};
1169 EXPECT_TRUE(span_of_checked_iterators.empty());
1170 }
1171 }
1172
TEST(SpanTest,OperatorAt)1173 TEST(SpanTest, OperatorAt) {
1174 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1175 constexpr span<const int> span(kArray);
1176
1177 static_assert(&kArray[0] == &span[0],
1178 "span[0] does not refer to the same element as kArray[0]");
1179 static_assert(&kArray[1] == &span[1],
1180 "span[1] does not refer to the same element as kArray[1]");
1181 static_assert(&kArray[2] == &span[2],
1182 "span[2] does not refer to the same element as kArray[2]");
1183 static_assert(&kArray[3] == &span[3],
1184 "span[3] does not refer to the same element as kArray[3]");
1185 static_assert(&kArray[4] == &span[4],
1186 "span[4] does not refer to the same element as kArray[4]");
1187 }
1188
TEST(SpanTest,Front)1189 TEST(SpanTest, Front) {
1190 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1191 constexpr span<const int> span(kArray);
1192 static_assert(&kArray[0] == &span.front(),
1193 "span.front() does not refer to the same element as kArray[0]");
1194 }
1195
TEST(SpanTest,Back)1196 TEST(SpanTest, Back) {
1197 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1198 constexpr span<const int> span(kArray);
1199 static_assert(&kArray[4] == &span.back(),
1200 "span.back() does not refer to the same element as kArray[4]");
1201 }
1202
TEST(SpanTest,Iterator)1203 TEST(SpanTest, Iterator) {
1204 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1205 constexpr span<const int> span(kArray);
1206
1207 std::vector<int> results;
1208 for (int i : span)
1209 results.emplace_back(i);
1210 EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
1211 }
1212
TEST(SpanTest,ConstexprIterator)1213 TEST(SpanTest, ConstexprIterator) {
1214 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1215 constexpr span<const int> span(kArray);
1216
1217 static_assert(ranges::equal(kArray, span), "");
1218 static_assert(1 == span.begin()[0], "");
1219 static_assert(1 == *(span.begin() += 0), "");
1220 static_assert(6 == *(span.begin() += 1), "");
1221
1222 static_assert(1 == *((span.begin() + 1) -= 1), "");
1223 static_assert(6 == *((span.begin() + 1) -= 0), "");
1224
1225 static_assert(0 + span.begin() == span.begin() + 0);
1226 static_assert(1 + span.begin() == span.begin() + 1);
1227 }
1228
TEST(SpanTest,ReverseIterator)1229 TEST(SpanTest, ReverseIterator) {
1230 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1231 constexpr span<const int> span(kArray);
1232
1233 EXPECT_TRUE(ranges::equal(Reversed(kArray), Reversed(span)));
1234 }
1235
TEST(SpanTest,AsBytes)1236 TEST(SpanTest, AsBytes) {
1237 {
1238 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1239 span<const uint8_t, sizeof(kArray)> bytes_span =
1240 as_bytes(make_span(kArray));
1241 EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
1242 EXPECT_EQ(sizeof(kArray), bytes_span.size());
1243 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1244 }
1245
1246 {
1247 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1248 span<int> mutable_span(vec);
1249 span<const uint8_t> bytes_span = as_bytes(mutable_span);
1250 EXPECT_EQ(reinterpret_cast<const uint8_t*>(vec.data()), bytes_span.data());
1251 EXPECT_EQ(sizeof(int) * vec.size(), bytes_span.size());
1252 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1253 }
1254 }
1255
TEST(SpanTest,AsWritableBytes)1256 TEST(SpanTest, AsWritableBytes) {
1257 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1258 span<int> mutable_span(vec);
1259 span<uint8_t> writable_bytes_span = as_writable_bytes(mutable_span);
1260 EXPECT_EQ(reinterpret_cast<uint8_t*>(vec.data()), writable_bytes_span.data());
1261 EXPECT_EQ(sizeof(int) * vec.size(), writable_bytes_span.size());
1262 EXPECT_EQ(writable_bytes_span.size(), writable_bytes_span.size_bytes());
1263
1264 // Set the first entry of vec to zero while writing through the span.
1265 std::fill(writable_bytes_span.data(),
1266 writable_bytes_span.data() + sizeof(int), 0);
1267 EXPECT_EQ(0, vec[0]);
1268 }
1269
TEST(SpanTest,AsByteSpan)1270 TEST(SpanTest, AsByteSpan) {
1271 {
1272 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1273 auto byte_span = as_byte_span(kArray);
1274 static_assert(std::is_same_v<decltype(byte_span), span<const uint8_t>>);
1275 EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kArray));
1276 EXPECT_EQ(byte_span.size(), sizeof(kArray));
1277 }
1278 {
1279 int kMutArray[] = {2, 3, 5, 7};
1280 auto byte_span = as_byte_span(kMutArray);
1281 static_assert(std::is_same_v<decltype(byte_span), span<const uint8_t>>);
1282 EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kMutArray));
1283 EXPECT_EQ(byte_span.size(), sizeof(kMutArray));
1284 }
1285 }
1286
TEST(SpanTest,MakeSpanFromDataAndSize)1287 TEST(SpanTest, MakeSpanFromDataAndSize) {
1288 int* nullint = nullptr;
1289 auto empty_span = make_span(nullint, 0u);
1290 EXPECT_TRUE(empty_span.empty());
1291 EXPECT_EQ(nullptr, empty_span.data());
1292
1293 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1294 span<int> expected_span(vector.data(), vector.size());
1295 auto made_span = make_span(vector.data(), vector.size());
1296 EXPECT_EQ(expected_span.data(), made_span.data());
1297 EXPECT_EQ(expected_span.size(), made_span.size());
1298 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1299 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1300 "the type of made_span differs from expected_span!");
1301 }
1302
TEST(SpanTest,MakeSpanFromPointerPair)1303 TEST(SpanTest, MakeSpanFromPointerPair) {
1304 int* nullint = nullptr;
1305 auto empty_span = make_span(nullint, nullint);
1306 EXPECT_TRUE(empty_span.empty());
1307 EXPECT_EQ(nullptr, empty_span.data());
1308
1309 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1310 span<int> expected_span(vector.data(), vector.size());
1311 auto made_span = make_span(vector.data(), vector.data() + vector.size());
1312 EXPECT_EQ(expected_span.data(), made_span.data());
1313 EXPECT_EQ(expected_span.size(), made_span.size());
1314 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1315 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1316 "the type of made_span differs from expected_span!");
1317 }
1318
TEST(SpanTest,MakeSpanFromConstexprArray)1319 TEST(SpanTest, MakeSpanFromConstexprArray) {
1320 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1321 constexpr span<const int, 5> expected_span(kArray);
1322 constexpr auto made_span = make_span(kArray);
1323 EXPECT_EQ(expected_span.data(), made_span.data());
1324 EXPECT_EQ(expected_span.size(), made_span.size());
1325 static_assert(decltype(made_span)::extent == 5, "");
1326 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1327 "the type of made_span differs from expected_span!");
1328 }
1329
TEST(SpanTest,MakeSpanFromStdArray)1330 TEST(SpanTest, MakeSpanFromStdArray) {
1331 const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
1332 span<const int, 5> expected_span(kArray);
1333 auto made_span = make_span(kArray);
1334 EXPECT_EQ(expected_span.data(), made_span.data());
1335 EXPECT_EQ(expected_span.size(), made_span.size());
1336 static_assert(decltype(made_span)::extent == 5, "");
1337 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1338 "the type of made_span differs from expected_span!");
1339 }
1340
TEST(SpanTest,MakeSpanFromConstContainer)1341 TEST(SpanTest, MakeSpanFromConstContainer) {
1342 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1343 span<const int> expected_span(vector);
1344 auto made_span = make_span(vector);
1345 EXPECT_EQ(expected_span.data(), made_span.data());
1346 EXPECT_EQ(expected_span.size(), made_span.size());
1347 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1348 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1349 "the type of made_span differs from expected_span!");
1350 }
1351
TEST(SpanTest,MakeStaticSpanFromConstContainer)1352 TEST(SpanTest, MakeStaticSpanFromConstContainer) {
1353 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1354 span<const int, 5> expected_span(vector.data(), vector.size());
1355 auto made_span = make_span<5>(vector);
1356 EXPECT_EQ(expected_span.data(), made_span.data());
1357 EXPECT_EQ(expected_span.size(), made_span.size());
1358 static_assert(decltype(made_span)::extent == 5, "");
1359 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1360 "the type of made_span differs from expected_span!");
1361 }
1362
TEST(SpanTest,MakeSpanFromContainer)1363 TEST(SpanTest, MakeSpanFromContainer) {
1364 std::vector<int> vector = {-1, -2, -3, -4, -5};
1365 span<int> expected_span(vector);
1366 auto made_span = make_span(vector);
1367 EXPECT_EQ(expected_span.data(), made_span.data());
1368 EXPECT_EQ(expected_span.size(), made_span.size());
1369 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1370 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1371 "the type of made_span differs from expected_span!");
1372 }
1373
TEST(SpanTest,MakeStaticSpanFromContainer)1374 TEST(SpanTest, MakeStaticSpanFromContainer) {
1375 std::vector<int> vector = {-1, -2, -3, -4, -5};
1376 span<int, 5> expected_span(vector.data(), vector.size());
1377 auto made_span = make_span<5>(vector);
1378 EXPECT_EQ(expected_span.data(), make_span<5>(vector).data());
1379 EXPECT_EQ(expected_span.size(), make_span<5>(vector).size());
1380 static_assert(decltype(make_span<5>(vector))::extent == 5, "");
1381 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1382 "the type of made_span differs from expected_span!");
1383 }
1384
TEST(SpanTest,MakeStaticSpanFromConstexprContainer)1385 TEST(SpanTest, MakeStaticSpanFromConstexprContainer) {
1386 constexpr StringPiece str = "Hello, World";
1387 constexpr auto made_span = make_span<12>(str);
1388 static_assert(str.data() == made_span.data(), "Error: data() does not match");
1389 static_assert(str.size() == made_span.size(), "Error: size() does not match");
1390 static_assert(std::is_same_v<decltype(str)::value_type,
1391 decltype(made_span)::value_type>,
1392 "Error: value_type does not match");
1393 static_assert(str.size() == decltype(made_span)::extent,
1394 "Error: extent does not match");
1395 }
1396
TEST(SpanTest,MakeSpanFromRValueContainer)1397 TEST(SpanTest, MakeSpanFromRValueContainer) {
1398 std::vector<int> vector = {-1, -2, -3, -4, -5};
1399 span<const int> expected_span(vector);
1400 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1401 // std::move(foo), make_span does not actually take ownership of the passed in
1402 // container. Writing it this way makes it more obvious that we simply care
1403 // about the right behavour when passing rvalues.
1404 auto made_span = make_span(static_cast<std::vector<int>&&>(vector));
1405 EXPECT_EQ(expected_span.data(), made_span.data());
1406 EXPECT_EQ(expected_span.size(), made_span.size());
1407 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1408 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1409 "the type of made_span differs from expected_span!");
1410 }
1411
TEST(SpanTest,MakeStaticSpanFromRValueContainer)1412 TEST(SpanTest, MakeStaticSpanFromRValueContainer) {
1413 std::vector<int> vector = {-1, -2, -3, -4, -5};
1414 span<const int, 5> expected_span(vector.data(), vector.size());
1415 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1416 // std::move(foo), make_span does not actually take ownership of the passed in
1417 // container. Writing it this way makes it more obvious that we simply care
1418 // about the right behavour when passing rvalues.
1419 auto made_span = make_span<5>(static_cast<std::vector<int>&&>(vector));
1420 EXPECT_EQ(expected_span.data(), made_span.data());
1421 EXPECT_EQ(expected_span.size(), made_span.size());
1422 static_assert(decltype(made_span)::extent == 5, "");
1423 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1424 "the type of made_span differs from expected_span!");
1425 }
1426
TEST(SpanTest,MakeSpanFromDynamicSpan)1427 TEST(SpanTest, MakeSpanFromDynamicSpan) {
1428 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1429 constexpr span<const int> expected_span(kArray);
1430 constexpr auto made_span = make_span(expected_span);
1431 static_assert(std::is_same_v<decltype(expected_span)::element_type,
1432 decltype(made_span)::element_type>,
1433 "make_span(span) should have the same element_type as span");
1434
1435 static_assert(expected_span.data() == made_span.data(),
1436 "make_span(span) should have the same data() as span");
1437
1438 static_assert(expected_span.size() == made_span.size(),
1439 "make_span(span) should have the same size() as span");
1440
1441 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1442 "make_span(span) should have the same extent as span");
1443
1444 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1445 "the type of made_span differs from expected_span!");
1446 }
1447
TEST(SpanTest,MakeSpanFromStaticSpan)1448 TEST(SpanTest, MakeSpanFromStaticSpan) {
1449 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1450 constexpr span<const int, 5> expected_span(kArray);
1451 constexpr auto made_span = make_span(expected_span);
1452 static_assert(std::is_same_v<decltype(expected_span)::element_type,
1453 decltype(made_span)::element_type>,
1454 "make_span(span) should have the same element_type as span");
1455
1456 static_assert(expected_span.data() == made_span.data(),
1457 "make_span(span) should have the same data() as span");
1458
1459 static_assert(expected_span.size() == made_span.size(),
1460 "make_span(span) should have the same size() as span");
1461
1462 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1463 "make_span(span) should have the same extent as span");
1464
1465 static_assert(std::is_same_v<decltype(expected_span), decltype(made_span)>,
1466 "the type of made_span differs from expected_span!");
1467 }
1468
TEST(SpanTest,EnsureConstexprGoodness)1469 TEST(SpanTest, EnsureConstexprGoodness) {
1470 static constexpr int kArray[] = {5, 4, 3, 2, 1};
1471 constexpr span<const int> constexpr_span(kArray);
1472 const size_t size = 2;
1473
1474 const size_t start = 1;
1475 constexpr span<const int> subspan =
1476 constexpr_span.subspan(start, start + size);
1477 for (size_t i = 0; i < subspan.size(); ++i)
1478 EXPECT_EQ(kArray[start + i], subspan[i]);
1479
1480 constexpr span<const int> firsts = constexpr_span.first(size);
1481 for (size_t i = 0; i < firsts.size(); ++i)
1482 EXPECT_EQ(kArray[i], firsts[i]);
1483
1484 constexpr span<const int> lasts = constexpr_span.last(size);
1485 for (size_t i = 0; i < lasts.size(); ++i) {
1486 const size_t j = (std::size(kArray) - size) + i;
1487 EXPECT_EQ(kArray[j], lasts[i]);
1488 }
1489
1490 constexpr int item = constexpr_span[size];
1491 EXPECT_EQ(kArray[size], item);
1492 }
1493
TEST(SpanTest,OutOfBoundsDeath)1494 TEST(SpanTest, OutOfBoundsDeath) {
1495 constexpr span<int, 0> kEmptySpan;
1496 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan[0], "");
1497 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.first(1), "");
1498 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.last(1), "");
1499 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1), "");
1500
1501 constexpr span<int> kEmptyDynamicSpan;
1502 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan[0], "");
1503 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.front(), "");
1504 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.first(1), "");
1505 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.last(1), "");
1506 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.back(), "");
1507 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.subspan(1), "");
1508
1509 static constexpr int kArray[] = {0, 1, 2};
1510 constexpr span<const int> kNonEmptyDynamicSpan(kArray);
1511 EXPECT_EQ(3U, kNonEmptyDynamicSpan.size());
1512 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan[4], "");
1513 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(10), "");
1514 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(1, 7), "");
1515
1516 size_t minus_one = static_cast<size_t>(-1);
1517 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(minus_one), "");
1518 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(minus_one, minus_one),
1519 "");
1520 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(minus_one, 1), "");
1521 }
1522
TEST(SpanTest,IteratorIsRangeMoveSafe)1523 TEST(SpanTest, IteratorIsRangeMoveSafe) {
1524 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1525 const size_t kNumElements = 5;
1526 constexpr span<const int> span(kArray);
1527
1528 static constexpr int kOverlappingStartIndexes[] = {-4, 0, 3, 4};
1529 static constexpr int kNonOverlappingStartIndexes[] = {-7, -5, 5, 7};
1530
1531 // Overlapping ranges.
1532 for (const int dest_start_index : kOverlappingStartIndexes) {
1533 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1534 span.begin(), span.end(),
1535 CheckedContiguousIterator<const int>(
1536 span.data() + dest_start_index,
1537 span.data() + dest_start_index + kNumElements)));
1538 }
1539
1540 // Non-overlapping ranges.
1541 for (const int dest_start_index : kNonOverlappingStartIndexes) {
1542 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1543 span.begin(), span.end(),
1544 CheckedContiguousIterator<const int>(
1545 span.data() + dest_start_index,
1546 span.data() + dest_start_index + kNumElements)));
1547 }
1548
1549 // IsRangeMoveSafe is true if the length to be moved is 0.
1550 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1551 span.begin(), span.begin(),
1552 CheckedContiguousIterator<const int>(span.data(), span.data())));
1553
1554 // IsRangeMoveSafe is false if end < begin.
1555 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1556 span.end(), span.begin(),
1557 CheckedContiguousIterator<const int>(span.data(), span.data())));
1558 }
1559
TEST(SpanTest,Sort)1560 TEST(SpanTest, Sort) {
1561 int array[] = {5, 4, 3, 2, 1};
1562
1563 span<int> dynamic_span = array;
1564 ranges::sort(dynamic_span);
1565 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1566 std::sort(dynamic_span.rbegin(), dynamic_span.rend());
1567 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1568
1569 span<int, 5> static_span = array;
1570 std::sort(static_span.rbegin(), static_span.rend(), std::greater<>());
1571 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1572 ranges::sort(static_span, std::greater<>());
1573 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1574 }
1575
TEST(SpanTest,SpanExtentConversions)1576 TEST(SpanTest, SpanExtentConversions) {
1577 // Statically checks that various conversions between spans of dynamic and
1578 // static extent are possible or not.
1579 static_assert(std::is_constructible_v<span<int, 0>, span<int>>,
1580 "Error: static span should be constructible from dynamic span");
1581
1582 static_assert(
1583 !std::is_convertible_v<span<int>, span<int, 0>>,
1584 "Error: static span should not be convertible from dynamic span");
1585
1586 static_assert(!std::is_constructible_v<span<int, 2>, span<int, 1>>,
1587 "Error: static span should not be constructible from static "
1588 "span with different extent");
1589
1590 static_assert(std::is_convertible_v<span<int, 0>, span<int>>,
1591 "Error: static span should be convertible to dynamic span");
1592
1593 static_assert(std::is_convertible_v<span<int>, span<int>>,
1594 "Error: dynamic span should be convertible to dynamic span");
1595
1596 static_assert(std::is_convertible_v<span<int, 2>, span<int, 2>>,
1597 "Error: static span should be convertible to static span");
1598 }
1599
TEST(SpanTest,IteratorConversions)1600 TEST(SpanTest, IteratorConversions) {
1601 static_assert(
1602 std::is_convertible_v<span<int>::iterator, span<const int>::iterator>,
1603 "Error: iterator should be convertible to const iterator");
1604
1605 static_assert(
1606 !std::is_convertible_v<span<const int>::iterator, span<int>::iterator>,
1607 "Error: const iterator should not be convertible to iterator");
1608 }
1609
TEST(SpanTest,ExtentMacro)1610 TEST(SpanTest, ExtentMacro) {
1611 constexpr size_t kSize = 10;
1612 std::array<uint8_t, kSize> array;
1613 static_assert(EXTENT(array) == kSize, "EXTENT broken");
1614
1615 const std::array<uint8_t, kSize>& reference = array;
1616 static_assert(EXTENT(reference) == kSize, "EXTENT broken for references");
1617
1618 const std::array<uint8_t, kSize>* pointer = nullptr;
1619 static_assert(EXTENT(*pointer) == kSize, "EXTENT broken for pointers");
1620
1621 uint8_t plain_array[kSize] = {0};
1622 static_assert(EXTENT(plain_array) == kSize, "EXTENT broken for plain arrays");
1623 }
1624
1625 } // namespace base
1626