blob: f4770f623210bea7d1c869241f8d2b9275334881 [file] [log] [blame]
Wyatt Hepler64c165e2020-01-13 10:21:08 -08001// Copyright 2020 The Pigweed Authors
Wyatt Hepler77105652019-11-06 17:50:03 -08002//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
Wyatt Hepler1a960942019-11-26 14:13:38 -08004// use this file except in compliance with the License. You may obtain a copy of
5// the License at
Wyatt Hepler77105652019-11-06 17:50:03 -08006//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
Wyatt Hepler1a960942019-11-26 14:13:38 -080012// License for the specific language governing permissions and limitations under
13// the License.
Wyatt Hepler77105652019-11-06 17:50:03 -080014
15// This is the base::span unit test from Chromium, with small modifications.
16// Modifications are noted with "Pigweed:" comments.
17//
18// Original file:
Wyatt Hepler64c165e2020-01-13 10:21:08 -080019// https://chromium.googlesource.com/chromium/src/+/ef71f9c29f0dc6eddae474879c4ca5232ca93a6c/base/containers/span_unittest.cc
Wyatt Hepler77105652019-11-06 17:50:03 -080020//
Wyatt Hepler64c165e2020-01-13 10:21:08 -080021// In order to minimize changes from the original, this file does NOT fully
22// adhere to Pigweed's style guide.
Wyatt Hepler77105652019-11-06 17:50:03 -080023#include "pw_span/span.h"
24
25#include <algorithm>
26#include <cstdint>
27#include <memory>
28#include <string>
29#include <type_traits>
30#include <vector>
31
32#include "gtest/gtest.h"
33
34// Pigweed: gMock matchers are not yet supported.
35#if 0
36using ::testing::ElementsAre;
37using ::testing::Eq;
38using ::testing::Pointwise;
39#endif // 0
40
41namespace pw {
42
43namespace {
44
45// constexpr implementation of std::equal's 4 argument overload.
46template <class InputIterator1, class InputIterator2>
47constexpr bool constexpr_equal(InputIterator1 first1,
48 InputIterator1 last1,
49 InputIterator2 first2,
50 InputIterator2 last2) {
51 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
52 if (*first1 != *first2)
53 return false;
54 }
55
56 return first1 == last1 && first2 == last2;
57}
58
59} // namespace
60
Wyatt Hepler83d42482019-11-19 15:17:33 -080061// Pigweed: Test deducing from std::string_view.
62TEST(SpanTest, DeductionGuides_MutableArray) {
63 char array[] = {'a', 'b', 'c', 'd', '\0'};
64
65 auto the_span = span(array);
66 static_assert(the_span.extent == 5u);
67 static_assert(the_span.size() == 5u);
68
69 the_span[0] = '!';
70 EXPECT_STREQ(the_span.data(), "!bcd");
71}
72
73TEST(SpanTest, DeductionGuides_ConstArray) {
74 static constexpr char array[] = {'a', 'b', 'c', 'd', '\0'};
75
76 constexpr auto the_span = span(array);
77 static_assert(the_span.extent == 5u);
78 static_assert(the_span.size() == 5u);
79
80 EXPECT_STREQ(the_span.data(), "abcd");
81}
82
83TEST(SpanTest, DeductionGuides_MutableStdArray) {
84 std::array<char, 5> array{'a', 'b', 'c', 'd'};
85
86 auto the_span = span(array);
87 static_assert(the_span.extent == 5u);
88 static_assert(the_span.size() == 5u);
89
90 the_span[0] = '?';
91 EXPECT_STREQ(the_span.data(), "?bcd");
92}
93
94TEST(SpanTest, DeductionGuides_ConstStdArray) {
95 static constexpr std::array<char, 5> array{'a', 'b', 'c', 'd'};
96
97 constexpr auto the_span = span(array);
98 static_assert(the_span.extent == 5u);
99 static_assert(the_span.size() == 5u);
100
101 EXPECT_STREQ(the_span.data(), "abcd");
102}
103
104TEST(SpanTest, DeductionGuides_MutableContainer) {
105 std::vector<int> foo = {3456};
106
107 auto the_span = span(foo);
108 static_assert(the_span.extent == dynamic_extent);
109
110 EXPECT_EQ(foo[0], the_span[0]);
111 EXPECT_EQ(foo.size(), the_span.size());
112
113 the_span[0] = 9876;
114 EXPECT_EQ(9876, foo[0]);
115}
116
117TEST(SpanTest, DeductionGuides_ConstContainer) {
118 auto the_span = span(std::string_view("Hello"));
119 static_assert(the_span.extent == dynamic_extent);
120
121 EXPECT_STREQ("Hello", the_span.data());
122 EXPECT_EQ(5u, the_span.size());
123}
124
Wyatt Hepler77105652019-11-06 17:50:03 -0800125TEST(SpanTest, DefaultConstructor) {
126 span<int> dynamic_span;
127 EXPECT_EQ(nullptr, dynamic_span.data());
128 EXPECT_EQ(0u, dynamic_span.size());
129
130 constexpr span<int, 0> static_span;
131 static_assert(nullptr == static_span.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800132 static_assert(static_span.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800133}
134
135TEST(SpanTest, ConstructFromDataAndSize) {
136 constexpr span<int> empty_span(nullptr, 0);
137 EXPECT_TRUE(empty_span.empty());
138 EXPECT_EQ(nullptr, empty_span.data());
139
140 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
141
142 span<int> dynamic_span(vector.data(), vector.size());
143 EXPECT_EQ(vector.data(), dynamic_span.data());
144 EXPECT_EQ(vector.size(), dynamic_span.size());
145
146 for (size_t i = 0; i < dynamic_span.size(); ++i)
147 EXPECT_EQ(vector[i], dynamic_span[i]);
148
149 span<int, 6> static_span(vector.data(), vector.size());
150 EXPECT_EQ(vector.data(), static_span.data());
151 EXPECT_EQ(vector.size(), static_span.size());
152
153 for (size_t i = 0; i < static_span.size(); ++i)
154 EXPECT_EQ(vector[i], static_span[i]);
155}
156
157TEST(SpanTest, ConstructFromPointerPair) {
158 constexpr span<int> empty_span(nullptr, nullptr);
159 EXPECT_TRUE(empty_span.empty());
160 EXPECT_EQ(nullptr, empty_span.data());
161
162 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
163
164 span<int> dynamic_span(vector.data(), vector.data() + vector.size() / 2);
165 EXPECT_EQ(vector.data(), dynamic_span.data());
166 EXPECT_EQ(vector.size() / 2, dynamic_span.size());
167
168 for (size_t i = 0; i < dynamic_span.size(); ++i)
169 EXPECT_EQ(vector[i], dynamic_span[i]);
170
171 span<int, 3> static_span(vector.data(), vector.data() + vector.size() / 2);
172 EXPECT_EQ(vector.data(), static_span.data());
173 EXPECT_EQ(vector.size() / 2, static_span.size());
174
175 for (size_t i = 0; i < static_span.size(); ++i)
176 EXPECT_EQ(vector[i], static_span[i]);
177}
178
179TEST(SpanTest, ConstructFromConstexprArray) {
180 static constexpr int kArray[] = {5, 4, 3, 2, 1};
181
182 constexpr span<const int> dynamic_span(kArray);
183 static_assert(kArray == dynamic_span.data(), "");
184 static_assert(std::size(kArray) == dynamic_span.size(), "");
185
186 static_assert(kArray[0] == dynamic_span[0], "");
187 static_assert(kArray[1] == dynamic_span[1], "");
188 static_assert(kArray[2] == dynamic_span[2], "");
189 static_assert(kArray[3] == dynamic_span[3], "");
190 static_assert(kArray[4] == dynamic_span[4], "");
191
192 constexpr span<const int, std::size(kArray)> static_span(kArray);
193 static_assert(kArray == static_span.data(), "");
194 static_assert(std::size(kArray) == static_span.size(), "");
195
196 static_assert(kArray[0] == static_span[0], "");
197 static_assert(kArray[1] == static_span[1], "");
198 static_assert(kArray[2] == static_span[2], "");
199 static_assert(kArray[3] == static_span[3], "");
200 static_assert(kArray[4] == static_span[4], "");
201}
202
203TEST(SpanTest, ConstructFromArray) {
204 int array[] = {5, 4, 3, 2, 1};
205
206 span<const int> const_span(array);
207 EXPECT_EQ(array, const_span.data());
208 EXPECT_EQ(std::size(array), const_span.size());
209 for (size_t i = 0; i < const_span.size(); ++i)
210 EXPECT_EQ(array[i], const_span[i]);
211
212 span<int> dynamic_span(array);
213 EXPECT_EQ(array, dynamic_span.data());
214 EXPECT_EQ(std::size(array), dynamic_span.size());
215 for (size_t i = 0; i < dynamic_span.size(); ++i)
216 EXPECT_EQ(array[i], dynamic_span[i]);
217
218 span<int, std::size(array)> static_span(array);
219 EXPECT_EQ(array, static_span.data());
220 EXPECT_EQ(std::size(array), static_span.size());
221 for (size_t i = 0; i < static_span.size(); ++i)
222 EXPECT_EQ(array[i], static_span[i]);
223}
224
225TEST(SpanTest, ConstructFromStdArray) {
226 // Note: Constructing a constexpr span from a constexpr std::array does not
227 // work prior to C++17 due to non-constexpr std::array::data.
228 std::array<int, 5> array = {{5, 4, 3, 2, 1}};
229
230 span<const int> const_span(array);
231 EXPECT_EQ(array.data(), const_span.data());
232 EXPECT_EQ(array.size(), const_span.size());
233 for (size_t i = 0; i < const_span.size(); ++i)
234 EXPECT_EQ(array[i], const_span[i]);
235
236 span<int> dynamic_span(array);
237 EXPECT_EQ(array.data(), dynamic_span.data());
238 EXPECT_EQ(array.size(), dynamic_span.size());
239 for (size_t i = 0; i < dynamic_span.size(); ++i)
240 EXPECT_EQ(array[i], dynamic_span[i]);
241
242 span<int, std::size(array)> static_span(array);
243 EXPECT_EQ(array.data(), static_span.data());
244 EXPECT_EQ(array.size(), static_span.size());
245 for (size_t i = 0; i < static_span.size(); ++i)
246 EXPECT_EQ(array[i], static_span[i]);
247}
248
249TEST(SpanTest, ConstructFromInitializerList) {
250 std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
251
252 span<const int> const_span(il);
253 EXPECT_EQ(il.begin(), const_span.data());
254 EXPECT_EQ(il.size(), const_span.size());
255
256 for (size_t i = 0; i < const_span.size(); ++i)
257 EXPECT_EQ(il.begin()[i], const_span[i]);
258
259 span<const int, 6> static_span(il.begin(), il.end());
260 EXPECT_EQ(il.begin(), static_span.data());
261 EXPECT_EQ(il.size(), static_span.size());
262
263 for (size_t i = 0; i < static_span.size(); ++i)
264 EXPECT_EQ(il.begin()[i], static_span[i]);
265}
266
267TEST(SpanTest, ConstructFromStdString) {
268 std::string str = "foobar";
269
270 span<const char> const_span(str);
271 EXPECT_EQ(str.data(), const_span.data());
272 EXPECT_EQ(str.size(), const_span.size());
273
274 for (size_t i = 0; i < const_span.size(); ++i)
275 EXPECT_EQ(str[i], const_span[i]);
276
277 span<char> dynamic_span(str);
278 EXPECT_EQ(str.data(), dynamic_span.data());
279 EXPECT_EQ(str.size(), dynamic_span.size());
280
281 for (size_t i = 0; i < dynamic_span.size(); ++i)
282 EXPECT_EQ(str[i], dynamic_span[i]);
283
284 span<char, 6> static_span(data(str), str.size());
285 EXPECT_EQ(str.data(), static_span.data());
286 EXPECT_EQ(str.size(), static_span.size());
287
288 for (size_t i = 0; i < static_span.size(); ++i)
289 EXPECT_EQ(str[i], static_span[i]);
290}
291
292TEST(SpanTest, ConstructFromConstContainer) {
293 const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
294
295 span<const int> const_span(vector);
296 EXPECT_EQ(vector.data(), const_span.data());
297 EXPECT_EQ(vector.size(), const_span.size());
298
299 for (size_t i = 0; i < const_span.size(); ++i)
300 EXPECT_EQ(vector[i], const_span[i]);
301
302 span<const int, 6> static_span(vector.data(), vector.size());
303 EXPECT_EQ(vector.data(), static_span.data());
304 EXPECT_EQ(vector.size(), static_span.size());
305
306 for (size_t i = 0; i < static_span.size(); ++i)
307 EXPECT_EQ(vector[i], static_span[i]);
308}
309
310TEST(SpanTest, ConstructFromContainer) {
311 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
312
313 span<const int> const_span(vector);
314 EXPECT_EQ(vector.data(), const_span.data());
315 EXPECT_EQ(vector.size(), const_span.size());
316
317 for (size_t i = 0; i < const_span.size(); ++i)
318 EXPECT_EQ(vector[i], const_span[i]);
319
320 span<int> dynamic_span(vector);
321 EXPECT_EQ(vector.data(), dynamic_span.data());
322 EXPECT_EQ(vector.size(), dynamic_span.size());
323
324 for (size_t i = 0; i < dynamic_span.size(); ++i)
325 EXPECT_EQ(vector[i], dynamic_span[i]);
326
327 span<int, 6> static_span(vector.data(), vector.size());
328 EXPECT_EQ(vector.data(), static_span.data());
329 EXPECT_EQ(vector.size(), static_span.size());
330
331 for (size_t i = 0; i < static_span.size(); ++i)
332 EXPECT_EQ(vector[i], static_span[i]);
333}
334
335#if 0
336
337// Pigweed: gMock matchers are not yet supported.
338TEST(SpanTest, ConvertNonConstIntegralToConst) {
339 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
340
341 span<int> int_span(vector.data(), vector.size());
342 span<const int> const_span(int_span);
343 EXPECT_EQ(int_span.size(), const_span.size());
344
345 EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
346
347 span<int, 6> static_int_span(vector.data(), vector.size());
348 span<const int, 6> static_const_span(static_int_span);
349 EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
350}
351
352// Pigweed: gMock matchers are not yet supported.
353TEST(SpanTest, ConvertNonConstPointerToConst) {
354 auto a = std::make_unique<int>(11);
355 auto b = std::make_unique<int>(22);
356 auto c = std::make_unique<int>(33);
357 std::vector<int*> vector = {a.get(), b.get(), c.get()};
358
359 span<int*> non_const_pointer_span(vector);
360 EXPECT_THAT(non_const_pointer_span, Pointwise(Eq(), vector));
361 span<int* const> const_pointer_span(non_const_pointer_span);
362 EXPECT_THAT(const_pointer_span, Pointwise(Eq(), non_const_pointer_span));
363 // Note: no test for conversion from span<int> to span<const int*>, since that
364 // would imply a conversion from int** to const int**, which is unsafe.
365 //
366 // Note: no test for conversion from span<int*> to span<const int* const>,
367 // due to CWG Defect 330:
368 // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
369
370 span<int*, 3> static_non_const_pointer_span(vector.data(), vector.size());
371 EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
372 span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
373 EXPECT_THAT(static_const_pointer_span,
374 Pointwise(Eq(), static_non_const_pointer_span));
375}
376
377// Pigweed: This test does not work on platforms where int32_t is long int.
378TEST(SpanTest, ConvertBetweenEquivalentTypes) {
379 std::vector<int32_t> vector = {2, 4, 8, 16, 32};
380
381 span<int32_t> int32_t_span(vector);
382 span<int> converted_span(int32_t_span);
383 EXPECT_EQ(int32_t_span.data(), converted_span.data());
384 EXPECT_EQ(int32_t_span.size(), converted_span.size());
385
386 span<int32_t, 5> static_int32_t_span(vector.data(), vector.size());
387 span<int, 5> static_converted_span(static_int32_t_span);
388 EXPECT_EQ(static_int32_t_span.data(), static_converted_span.data());
389 EXPECT_EQ(static_int32_t_span.size(), static_converted_span.size());
390}
391
392#endif // 0
393
394TEST(SpanTest, TemplatedFirst) {
395 static constexpr int array[] = {1, 2, 3};
396 constexpr span<const int, 3> span(array);
397
398 {
399 constexpr auto subspan = span.first<0>();
400 static_assert(span.data() == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800401 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800402 static_assert(0u == decltype(subspan)::extent, "");
403 }
404
405 {
406 constexpr auto subspan = span.first<1>();
407 static_assert(span.data() == subspan.data(), "");
408 static_assert(1u == subspan.size(), "");
409 static_assert(1u == decltype(subspan)::extent, "");
410 static_assert(1 == subspan[0], "");
411 }
412
413 {
414 constexpr auto subspan = span.first<2>();
415 static_assert(span.data() == subspan.data(), "");
416 static_assert(2u == subspan.size(), "");
417 static_assert(2u == decltype(subspan)::extent, "");
418 static_assert(1 == subspan[0], "");
419 static_assert(2 == subspan[1], "");
420 }
421
422 {
423 constexpr auto subspan = span.first<3>();
424 static_assert(span.data() == subspan.data(), "");
425 static_assert(3u == subspan.size(), "");
426 static_assert(3u == decltype(subspan)::extent, "");
427 static_assert(1 == subspan[0], "");
428 static_assert(2 == subspan[1], "");
429 static_assert(3 == subspan[2], "");
430 }
431}
432
433TEST(SpanTest, TemplatedLast) {
434 static constexpr int array[] = {1, 2, 3};
435 constexpr span<const int, 3> span(array);
436
437 {
438 constexpr auto subspan = span.last<0>();
439 static_assert(span.data() + 3 == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800440 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800441 static_assert(0u == decltype(subspan)::extent, "");
442 }
443
444 {
445 constexpr auto subspan = span.last<1>();
446 static_assert(span.data() + 2 == subspan.data(), "");
447 static_assert(1u == subspan.size(), "");
448 static_assert(1u == decltype(subspan)::extent, "");
449 static_assert(3 == subspan[0], "");
450 }
451
452 {
453 constexpr auto subspan = span.last<2>();
454 static_assert(span.data() + 1 == subspan.data(), "");
455 static_assert(2u == subspan.size(), "");
456 static_assert(2u == decltype(subspan)::extent, "");
457 static_assert(2 == subspan[0], "");
458 static_assert(3 == subspan[1], "");
459 }
460
461 {
462 constexpr auto subspan = span.last<3>();
463 static_assert(span.data() == subspan.data(), "");
464 static_assert(3u == subspan.size(), "");
465 static_assert(3u == decltype(subspan)::extent, "");
466 static_assert(1 == subspan[0], "");
467 static_assert(2 == subspan[1], "");
468 static_assert(3 == subspan[2], "");
469 }
470}
471
472TEST(SpanTest, TemplatedSubspan) {
473 static constexpr int array[] = {1, 2, 3};
474 constexpr span<const int, 3> span(array);
475
476 {
477 constexpr auto subspan = span.subspan<0>();
478 static_assert(span.data() == subspan.data(), "");
479 static_assert(3u == subspan.size(), "");
480 static_assert(3u == decltype(subspan)::extent, "");
481 static_assert(1 == subspan[0], "");
482 static_assert(2 == subspan[1], "");
483 static_assert(3 == subspan[2], "");
484 }
485
486 {
487 constexpr auto subspan = span.subspan<1>();
488 static_assert(span.data() + 1 == subspan.data(), "");
489 static_assert(2u == subspan.size(), "");
490 static_assert(2u == decltype(subspan)::extent, "");
491 static_assert(2 == subspan[0], "");
492 static_assert(3 == subspan[1], "");
493 }
494
495 {
496 constexpr auto subspan = span.subspan<2>();
497 static_assert(span.data() + 2 == subspan.data(), "");
498 static_assert(1u == subspan.size(), "");
499 static_assert(1u == decltype(subspan)::extent, "");
500 static_assert(3 == subspan[0], "");
501 }
502
503 {
504 constexpr auto subspan = span.subspan<3>();
505 static_assert(span.data() + 3 == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800506 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800507 static_assert(0u == decltype(subspan)::extent, "");
508 }
509
510 {
511 constexpr auto subspan = span.subspan<0, 0>();
512 static_assert(span.data() == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800513 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800514 static_assert(0u == decltype(subspan)::extent, "");
515 }
516
517 {
518 constexpr auto subspan = span.subspan<1, 0>();
519 static_assert(span.data() + 1 == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800520 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800521 static_assert(0u == decltype(subspan)::extent, "");
522 }
523
524 {
525 constexpr auto subspan = span.subspan<2, 0>();
526 static_assert(span.data() + 2 == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800527 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800528 static_assert(0u == decltype(subspan)::extent, "");
529 }
530
531 {
532 constexpr auto subspan = span.subspan<0, 1>();
533 static_assert(span.data() == subspan.data(), "");
534 static_assert(1u == subspan.size(), "");
535 static_assert(1u == decltype(subspan)::extent, "");
536 static_assert(1 == subspan[0], "");
537 }
538
539 {
540 constexpr auto subspan = span.subspan<1, 1>();
541 static_assert(span.data() + 1 == subspan.data(), "");
542 static_assert(1u == subspan.size(), "");
543 static_assert(1u == decltype(subspan)::extent, "");
544 static_assert(2 == subspan[0], "");
545 }
546
547 {
548 constexpr auto subspan = span.subspan<2, 1>();
549 static_assert(span.data() + 2 == subspan.data(), "");
550 static_assert(1u == subspan.size(), "");
551 static_assert(1u == decltype(subspan)::extent, "");
552 static_assert(3 == subspan[0], "");
553 }
554
555 {
556 constexpr auto subspan = span.subspan<0, 2>();
557 static_assert(span.data() == subspan.data(), "");
558 static_assert(2u == subspan.size(), "");
559 static_assert(2u == decltype(subspan)::extent, "");
560 static_assert(1 == subspan[0], "");
561 static_assert(2 == subspan[1], "");
562 }
563
564 {
565 constexpr auto subspan = span.subspan<1, 2>();
566 static_assert(span.data() + 1 == subspan.data(), "");
567 static_assert(2u == subspan.size(), "");
568 static_assert(2u == decltype(subspan)::extent, "");
569 static_assert(2 == subspan[0], "");
570 static_assert(3 == subspan[1], "");
571 }
572
573 {
574 constexpr auto subspan = span.subspan<0, 3>();
575 static_assert(span.data() == subspan.data(), "");
576 static_assert(3u == subspan.size(), "");
577 static_assert(3u == decltype(subspan)::extent, "");
578 static_assert(1 == subspan[0], "");
579 static_assert(2 == subspan[1], "");
580 static_assert(3 == subspan[2], "");
581 }
582}
583
584TEST(SpanTest, SubscriptedBeginIterator) {
585 int array[] = {1, 2, 3};
586 span<const int> const_span(array);
587 for (size_t i = 0; i < const_span.size(); ++i)
588 EXPECT_EQ(array[i], const_span.begin()[i]);
589
590 span<int> mutable_span(array);
591 for (size_t i = 0; i < mutable_span.size(); ++i)
592 EXPECT_EQ(array[i], mutable_span.begin()[i]);
593}
594
595TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
596 int array[] = {1, 2, 3};
597 span<const int> span(array);
598
599 {
600 auto subspan = span.first<0>();
601 EXPECT_EQ(span.data(), subspan.data());
602 EXPECT_EQ(0u, subspan.size());
603 static_assert(0u == decltype(subspan)::extent, "");
604 }
605
606 {
607 auto subspan = span.first<1>();
608 EXPECT_EQ(span.data(), subspan.data());
609 EXPECT_EQ(1u, subspan.size());
610 static_assert(1u == decltype(subspan)::extent, "");
611 EXPECT_EQ(1, subspan[0]);
612 }
613
614 {
615 auto subspan = span.first<2>();
616 EXPECT_EQ(span.data(), subspan.data());
617 EXPECT_EQ(2u, subspan.size());
618 static_assert(2u == decltype(subspan)::extent, "");
619 EXPECT_EQ(1, subspan[0]);
620 EXPECT_EQ(2, subspan[1]);
621 }
622
623 {
624 auto subspan = span.first<3>();
625 EXPECT_EQ(span.data(), subspan.data());
626 EXPECT_EQ(3u, subspan.size());
627 static_assert(3u == decltype(subspan)::extent, "");
628 EXPECT_EQ(1, subspan[0]);
629 EXPECT_EQ(2, subspan[1]);
630 EXPECT_EQ(3, subspan[2]);
631 }
632}
633
634TEST(SpanTest, TemplatedLastOnDynamicSpan) {
635 int array[] = {1, 2, 3};
636 span<int> span(array);
637
638 {
639 auto subspan = span.last<0>();
640 EXPECT_EQ(span.data() + 3, subspan.data());
641 EXPECT_EQ(0u, subspan.size());
642 static_assert(0u == decltype(subspan)::extent, "");
643 }
644
645 {
646 auto subspan = span.last<1>();
647 EXPECT_EQ(span.data() + 2, subspan.data());
648 EXPECT_EQ(1u, subspan.size());
649 static_assert(1u == decltype(subspan)::extent, "");
650 EXPECT_EQ(3, subspan[0]);
651 }
652
653 {
654 auto subspan = span.last<2>();
655 EXPECT_EQ(span.data() + 1, subspan.data());
656 EXPECT_EQ(2u, subspan.size());
657 static_assert(2u == decltype(subspan)::extent, "");
658 EXPECT_EQ(2, subspan[0]);
659 EXPECT_EQ(3, subspan[1]);
660 }
661
662 {
663 auto subspan = span.last<3>();
664 EXPECT_EQ(span.data(), subspan.data());
665 EXPECT_EQ(3u, subspan.size());
666 static_assert(3u == decltype(subspan)::extent, "");
667 EXPECT_EQ(1, subspan[0]);
668 EXPECT_EQ(2, subspan[1]);
669 EXPECT_EQ(3, subspan[2]);
670 }
671}
672
673TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
674 int array[] = {1, 2, 3};
675 span<int, 3> span(array);
676
677 {
678 auto subspan = span.subspan<0>();
679 EXPECT_EQ(span.data(), subspan.data());
680 static_assert(3u == decltype(subspan)::extent, "");
681 EXPECT_EQ(3u, subspan.size());
682 EXPECT_EQ(1, subspan[0]);
683 EXPECT_EQ(2, subspan[1]);
684 EXPECT_EQ(3, subspan[2]);
685 }
686
687 {
688 auto subspan = span.subspan<1>();
689 EXPECT_EQ(span.data() + 1, subspan.data());
690 EXPECT_EQ(2u, subspan.size());
691 static_assert(2u == decltype(subspan)::extent, "");
692 EXPECT_EQ(2, subspan[0]);
693 EXPECT_EQ(3, subspan[1]);
694 }
695
696 {
697 auto subspan = span.subspan<2>();
698 EXPECT_EQ(span.data() + 2, subspan.data());
699 EXPECT_EQ(1u, subspan.size());
700 static_assert(1u == decltype(subspan)::extent, "");
701 EXPECT_EQ(3, subspan[0]);
702 }
703
704 {
705 auto subspan = span.subspan<3>();
706 EXPECT_EQ(span.data() + 3, subspan.data());
707 EXPECT_EQ(0u, subspan.size());
708 static_assert(0u == decltype(subspan)::extent, "");
709 }
710
711 {
712 auto subspan = span.subspan<0, 0>();
713 EXPECT_EQ(span.data(), subspan.data());
714 EXPECT_EQ(0u, subspan.size());
715 static_assert(0u == decltype(subspan)::extent, "");
716 }
717
718 {
719 auto subspan = span.subspan<1, 0>();
720 EXPECT_EQ(span.data() + 1, subspan.data());
721 EXPECT_EQ(0u, subspan.size());
722 static_assert(0u == decltype(subspan)::extent, "");
723 }
724
725 {
726 auto subspan = span.subspan<2, 0>();
727 EXPECT_EQ(span.data() + 2, subspan.data());
728 EXPECT_EQ(0u, subspan.size());
729 static_assert(0u == decltype(subspan)::extent, "");
730 }
731
732 {
733 auto subspan = span.subspan<0, 1>();
734 EXPECT_EQ(span.data(), subspan.data());
735 EXPECT_EQ(1u, subspan.size());
736 static_assert(1u == decltype(subspan)::extent, "");
737 EXPECT_EQ(1, subspan[0]);
738 }
739
740 {
741 auto subspan = span.subspan<1, 1>();
742 EXPECT_EQ(span.data() + 1, subspan.data());
743 EXPECT_EQ(1u, subspan.size());
744 static_assert(1u == decltype(subspan)::extent, "");
745 EXPECT_EQ(2, subspan[0]);
746 }
747
748 {
749 auto subspan = span.subspan<2, 1>();
750 EXPECT_EQ(span.data() + 2, subspan.data());
751 EXPECT_EQ(1u, subspan.size());
752 static_assert(1u == decltype(subspan)::extent, "");
753 EXPECT_EQ(3, subspan[0]);
754 }
755
756 {
757 auto subspan = span.subspan<0, 2>();
758 EXPECT_EQ(span.data(), subspan.data());
759 EXPECT_EQ(2u, subspan.size());
760 static_assert(2u == decltype(subspan)::extent, "");
761 EXPECT_EQ(1, subspan[0]);
762 EXPECT_EQ(2, subspan[1]);
763 }
764
765 {
766 auto subspan = span.subspan<1, 2>();
767 EXPECT_EQ(span.data() + 1, subspan.data());
768 EXPECT_EQ(2u, subspan.size());
769 static_assert(2u == decltype(subspan)::extent, "");
770 EXPECT_EQ(2, subspan[0]);
771 EXPECT_EQ(3, subspan[1]);
772 }
773
774 {
775 auto subspan = span.subspan<0, 3>();
776 EXPECT_EQ(span.data(), subspan.data());
777 EXPECT_EQ(3u, subspan.size());
778 static_assert(3u == decltype(subspan)::extent, "");
779 EXPECT_EQ(1, subspan[0]);
780 EXPECT_EQ(2, subspan[1]);
781 EXPECT_EQ(3, subspan[2]);
782 }
783}
784
785TEST(SpanTest, First) {
786 int array[] = {1, 2, 3};
787 span<int> span(array);
788
789 {
790 auto subspan = span.first(0);
791 EXPECT_EQ(span.data(), subspan.data());
792 EXPECT_EQ(0u, subspan.size());
793 }
794
795 {
796 auto subspan = span.first(1);
797 EXPECT_EQ(span.data(), subspan.data());
798 EXPECT_EQ(1u, subspan.size());
799 EXPECT_EQ(1, subspan[0]);
800 }
801
802 {
803 auto subspan = span.first(2);
804 EXPECT_EQ(span.data(), subspan.data());
805 EXPECT_EQ(2u, subspan.size());
806 EXPECT_EQ(1, subspan[0]);
807 EXPECT_EQ(2, subspan[1]);
808 }
809
810 {
811 auto subspan = span.first(3);
812 EXPECT_EQ(span.data(), subspan.data());
813 EXPECT_EQ(3u, subspan.size());
814 EXPECT_EQ(1, subspan[0]);
815 EXPECT_EQ(2, subspan[1]);
816 EXPECT_EQ(3, subspan[2]);
817 }
818}
819
820TEST(SpanTest, Last) {
821 int array[] = {1, 2, 3};
822 span<int> span(array);
823
824 {
825 auto subspan = span.last(0);
826 EXPECT_EQ(span.data() + 3, subspan.data());
827 EXPECT_EQ(0u, subspan.size());
828 }
829
830 {
831 auto subspan = span.last(1);
832 EXPECT_EQ(span.data() + 2, subspan.data());
833 EXPECT_EQ(1u, subspan.size());
834 EXPECT_EQ(3, subspan[0]);
835 }
836
837 {
838 auto subspan = span.last(2);
839 EXPECT_EQ(span.data() + 1, subspan.data());
840 EXPECT_EQ(2u, subspan.size());
841 EXPECT_EQ(2, subspan[0]);
842 EXPECT_EQ(3, subspan[1]);
843 }
844
845 {
846 auto subspan = span.last(3);
847 EXPECT_EQ(span.data(), subspan.data());
848 EXPECT_EQ(3u, subspan.size());
849 EXPECT_EQ(1, subspan[0]);
850 EXPECT_EQ(2, subspan[1]);
851 EXPECT_EQ(3, subspan[2]);
852 }
853}
854
855TEST(SpanTest, Subspan) {
856 int array[] = {1, 2, 3};
857 span<int> span(array);
858
859 {
860 auto subspan = span.subspan(0);
861 EXPECT_EQ(span.data(), subspan.data());
862 EXPECT_EQ(3u, subspan.size());
863 EXPECT_EQ(1, subspan[0]);
864 EXPECT_EQ(2, subspan[1]);
865 EXPECT_EQ(3, subspan[2]);
866 }
867
868 {
869 auto subspan = span.subspan(1);
870 EXPECT_EQ(span.data() + 1, subspan.data());
871 EXPECT_EQ(2u, subspan.size());
872 EXPECT_EQ(2, subspan[0]);
873 EXPECT_EQ(3, subspan[1]);
874 }
875
876 {
877 auto subspan = span.subspan(2);
878 EXPECT_EQ(span.data() + 2, subspan.data());
879 EXPECT_EQ(1u, subspan.size());
880 EXPECT_EQ(3, subspan[0]);
881 }
882
883 {
884 auto subspan = span.subspan(3);
885 EXPECT_EQ(span.data() + 3, subspan.data());
886 EXPECT_EQ(0u, subspan.size());
887 }
888
889 {
890 auto subspan = span.subspan(0, 0);
891 EXPECT_EQ(span.data(), subspan.data());
892 EXPECT_EQ(0u, subspan.size());
893 }
894
895 {
896 auto subspan = span.subspan(1, 0);
897 EXPECT_EQ(span.data() + 1, subspan.data());
898 EXPECT_EQ(0u, subspan.size());
899 }
900
901 {
902 auto subspan = span.subspan(2, 0);
903 EXPECT_EQ(span.data() + 2, subspan.data());
904 EXPECT_EQ(0u, subspan.size());
905 }
906
907 {
908 auto subspan = span.subspan(0, 1);
909 EXPECT_EQ(span.data(), subspan.data());
910 EXPECT_EQ(1u, subspan.size());
911 EXPECT_EQ(1, subspan[0]);
912 }
913
914 {
915 auto subspan = span.subspan(1, 1);
916 EXPECT_EQ(span.data() + 1, subspan.data());
917 EXPECT_EQ(1u, subspan.size());
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 EXPECT_EQ(3, subspan[0]);
926 }
927
928 {
929 auto subspan = span.subspan(0, 2);
930 EXPECT_EQ(span.data(), subspan.data());
931 EXPECT_EQ(2u, subspan.size());
932 EXPECT_EQ(1, subspan[0]);
933 EXPECT_EQ(2, subspan[1]);
934 }
935
936 {
937 auto subspan = span.subspan(1, 2);
938 EXPECT_EQ(span.data() + 1, subspan.data());
939 EXPECT_EQ(2u, subspan.size());
940 EXPECT_EQ(2, subspan[0]);
941 EXPECT_EQ(3, subspan[1]);
942 }
943
944 {
945 auto subspan = span.subspan(0, 3);
946 EXPECT_EQ(span.data(), subspan.data());
947 EXPECT_EQ(span.size(), subspan.size());
948 EXPECT_EQ(1, subspan[0]);
949 EXPECT_EQ(2, subspan[1]);
950 EXPECT_EQ(3, subspan[2]);
951 }
952}
953
954TEST(SpanTest, Size) {
955 {
956 span<int> span;
957 EXPECT_EQ(0u, span.size());
958 }
959
960 {
961 int array[] = {1, 2, 3};
962 span<int> span(array);
963 EXPECT_EQ(3u, span.size());
964 }
965}
966
967TEST(SpanTest, SizeBytes) {
968 {
969 span<int> span;
970 EXPECT_EQ(0u, span.size_bytes());
971 }
972
973 {
974 int array[] = {1, 2, 3};
975 span<int> span(array);
976 EXPECT_EQ(3u * sizeof(int), span.size_bytes());
977 }
978}
979
980TEST(SpanTest, Empty) {
981 {
982 span<int> span;
983 EXPECT_TRUE(span.empty());
984 }
985
986 {
987 int array[] = {1, 2, 3};
988 span<int> span(array);
989 EXPECT_FALSE(span.empty());
990 }
991}
992
993TEST(SpanTest, OperatorAt) {
994 static constexpr int kArray[] = {1, 6, 1, 8, 0};
995 constexpr span<const int> span(kArray);
996
997 static_assert(&kArray[0] == &span[0],
998 "span[0] does not refer to the same element as kArray[0]");
999 static_assert(&kArray[1] == &span[1],
1000 "span[1] does not refer to the same element as kArray[1]");
1001 static_assert(&kArray[2] == &span[2],
1002 "span[2] does not refer to the same element as kArray[2]");
1003 static_assert(&kArray[3] == &span[3],
1004 "span[3] does not refer to the same element as kArray[3]");
1005 static_assert(&kArray[4] == &span[4],
1006 "span[4] does not refer to the same element as kArray[4]");
1007}
1008
1009TEST(SpanTest, Front) {
1010 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1011 constexpr span<const int> span(kArray);
1012 static_assert(&kArray[0] == &span.front(),
1013 "span.front() does not refer to the same element as kArray[0]");
1014}
1015
1016TEST(SpanTest, Back) {
1017 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1018 constexpr span<const int> span(kArray);
1019 static_assert(&kArray[4] == &span.back(),
1020 "span.back() does not refer to the same element as kArray[4]");
1021}
1022
Wyatt Hepler77105652019-11-06 17:50:03 -08001023// Pigweed: This test uses gMock features not yet supported in Pigweed.
1024#if 0
1025TEST(SpanTest, Iterator) {
1026 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1027 constexpr span<const int> span(kArray);
1028
1029 std::vector<int> results;
1030 for (int i : span)
1031 results.emplace_back(i);
1032 EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
1033}
1034#endif // 0
1035
1036TEST(SpanTest, ConstexprIterator) {
1037 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1038 constexpr span<const int> span(kArray);
1039
Wyatt Hepler83d42482019-11-19 15:17:33 -08001040 static_assert(
1041 constexpr_equal(
1042 std::begin(kArray), std::end(kArray), span.begin(), span.end()),
1043 "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001044 static_assert(1 == span.begin()[0], "");
1045 // Pigweed: These tests assume an iterator object, but Pigweed's span uses a
1046 // simple pointer.
1047#if 0
1048 static_assert(1 == *(span.begin() += 0), "");
1049 static_assert(6 == *(span.begin() += 1), "");
1050
1051 static_assert(1 == *((span.begin() + 1) -= 1), "");
1052 static_assert(6 == *((span.begin() + 1) -= 0), "");
1053#endif // 0
1054}
1055
1056TEST(SpanTest, ReverseIterator) {
1057 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1058 constexpr span<const int> span(kArray);
1059
Wyatt Hepler83d42482019-11-19 15:17:33 -08001060 EXPECT_TRUE(std::equal(
1061 std::rbegin(kArray), std::rend(kArray), span.rbegin(), span.rend()));
1062 EXPECT_TRUE(std::equal(
1063 std::crbegin(kArray), std::crend(kArray), span.crbegin(), span.crend()));
Wyatt Hepler77105652019-11-06 17:50:03 -08001064}
1065
1066// Pigweed: These are tests for make_span, which is not included in Pigweed's
1067// implementation, since class template deduction is available.
1068#if 0
1069TEST(SpanTest, AsBytes) {
1070 {
1071 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1072 span<const uint8_t, sizeof(kArray)> bytes_span =
1073 as_bytes(make_span(kArray));
1074 EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
1075 EXPECT_EQ(sizeof(kArray), bytes_span.size());
1076 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1077 }
1078
1079 {
1080 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1081 span<int> mutable_span(vec);
1082 span<const uint8_t> bytes_span = as_bytes(mutable_span);
1083 EXPECT_EQ(reinterpret_cast<const uint8_t*>(vec.data()), bytes_span.data());
1084 EXPECT_EQ(sizeof(int) * vec.size(), bytes_span.size());
1085 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1086 }
1087}
1088
1089TEST(SpanTest, AsWritableBytes) {
1090 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1091 span<int> mutable_span(vec);
1092 span<uint8_t> writable_bytes_span = as_writable_bytes(mutable_span);
1093 EXPECT_EQ(reinterpret_cast<uint8_t*>(vec.data()), writable_bytes_span.data());
1094 EXPECT_EQ(sizeof(int) * vec.size(), writable_bytes_span.size());
1095 EXPECT_EQ(writable_bytes_span.size(), writable_bytes_span.size_bytes());
1096
1097 // Set the first entry of vec to zero while writing through the span.
1098 std::fill(writable_bytes_span.data(),
1099 writable_bytes_span.data() + sizeof(int), 0);
1100 EXPECT_EQ(0, vec[0]);
1101}
1102
1103TEST(SpanTest, MakeSpanFromDataAndSize) {
1104 int* nullint = nullptr;
1105 auto empty_span = make_span(nullint, 0);
1106 EXPECT_TRUE(empty_span.empty());
1107 EXPECT_EQ(nullptr, empty_span.data());
1108
1109 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1110 span<int> expected_span(vector.data(), vector.size());
1111 auto made_span = make_span(vector.data(), vector.size());
1112 EXPECT_EQ(expected_span.data(), made_span.data());
1113 EXPECT_EQ(expected_span.size(), made_span.size());
1114 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1115 static_assert(
1116 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1117 "the type of made_span differs from expected_span!");
1118}
1119
1120TEST(SpanTest, MakeSpanFromPointerPair) {
1121 int* nullint = nullptr;
1122 auto empty_span = make_span(nullint, nullint);
1123 EXPECT_TRUE(empty_span.empty());
1124 EXPECT_EQ(nullptr, empty_span.data());
1125
1126 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1127 span<int> expected_span(vector.data(), vector.size());
1128 auto made_span = make_span(vector.data(), vector.data() + vector.size());
1129 EXPECT_EQ(expected_span.data(), made_span.data());
1130 EXPECT_EQ(expected_span.size(), made_span.size());
1131 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1132 static_assert(
1133 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1134 "the type of made_span differs from expected_span!");
1135}
1136
1137TEST(SpanTest, MakeSpanFromConstexprArray) {
1138 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1139 constexpr span<const int, 5> expected_span(kArray);
1140 constexpr auto made_span = make_span(kArray);
1141 EXPECT_EQ(expected_span.data(), made_span.data());
1142 EXPECT_EQ(expected_span.size(), made_span.size());
1143 static_assert(decltype(made_span)::extent == 5, "");
1144 static_assert(
1145 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1146 "the type of made_span differs from expected_span!");
1147}
1148
1149TEST(SpanTest, MakeSpanFromStdArray) {
1150 const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
1151 span<const int, 5> expected_span(kArray);
1152 auto made_span = make_span(kArray);
1153 EXPECT_EQ(expected_span.data(), made_span.data());
1154 EXPECT_EQ(expected_span.size(), made_span.size());
1155 static_assert(decltype(made_span)::extent == 5, "");
1156 static_assert(
1157 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1158 "the type of made_span differs from expected_span!");
1159}
1160
1161TEST(SpanTest, MakeSpanFromConstContainer) {
1162 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1163 span<const int> expected_span(vector);
1164 auto made_span = make_span(vector);
1165 EXPECT_EQ(expected_span.data(), made_span.data());
1166 EXPECT_EQ(expected_span.size(), made_span.size());
1167 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1168 static_assert(
1169 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1170 "the type of made_span differs from expected_span!");
1171}
1172
1173TEST(SpanTest, MakeStaticSpanFromConstContainer) {
1174 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1175 span<const int, 5> expected_span(vector.data(), vector.size());
1176 auto made_span = make_span<5>(vector);
1177 EXPECT_EQ(expected_span.data(), made_span.data());
1178 EXPECT_EQ(expected_span.size(), made_span.size());
1179 static_assert(decltype(made_span)::extent == 5, "");
1180 static_assert(
1181 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1182 "the type of made_span differs from expected_span!");
1183}
1184
1185TEST(SpanTest, MakeSpanFromContainer) {
1186 std::vector<int> vector = {-1, -2, -3, -4, -5};
1187 span<int> expected_span(vector);
1188 auto made_span = make_span(vector);
1189 EXPECT_EQ(expected_span.data(), made_span.data());
1190 EXPECT_EQ(expected_span.size(), made_span.size());
1191 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1192 static_assert(
1193 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1194 "the type of made_span differs from expected_span!");
1195}
1196
1197TEST(SpanTest, MakeStaticSpanFromContainer) {
1198 std::vector<int> vector = {-1, -2, -3, -4, -5};
1199 span<int, 5> expected_span(vector.data(), vector.size());
1200 auto made_span = make_span<5>(vector);
1201 EXPECT_EQ(expected_span.data(), make_span<5>(vector).data());
1202 EXPECT_EQ(expected_span.size(), make_span<5>(vector).size());
1203 static_assert(decltype(make_span<5>(vector))::extent == 5, "");
1204 static_assert(
1205 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1206 "the type of made_span differs from expected_span!");
1207}
1208
1209TEST(SpanTest, MakeStaticSpanFromConstexprContainer) {
1210 constexpr StringPiece str = "Hello, World";
1211 constexpr auto made_span = make_span<12>(str);
1212 static_assert(str.data() == made_span.data(), "Error: data() does not match");
1213 static_assert(str.size() == made_span.size(), "Error: size() does not match");
1214 static_assert(std::is_same<decltype(str)::value_type,
1215 decltype(made_span)::value_type>::value,
1216 "Error: value_type does not match");
1217 static_assert(str.size() == decltype(made_span)::extent,
1218 "Error: extent does not match");
1219}
1220
1221TEST(SpanTest, MakeSpanFromRValueContainer) {
1222 std::vector<int> vector = {-1, -2, -3, -4, -5};
1223 span<const int> expected_span(vector);
1224 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1225 // std::move(foo), make_span does not actually take ownership of the passed in
1226 // container. Writing it this way makes it more obvious that we simply care
1227 // about the right behavour when passing rvalues.
1228 auto made_span = make_span(static_cast<std::vector<int>&&>(vector));
1229 EXPECT_EQ(expected_span.data(), made_span.data());
1230 EXPECT_EQ(expected_span.size(), made_span.size());
1231 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1232 static_assert(
1233 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1234 "the type of made_span differs from expected_span!");
1235}
1236
1237TEST(SpanTest, MakeStaticSpanFromRValueContainer) {
1238 std::vector<int> vector = {-1, -2, -3, -4, -5};
1239 span<const int, 5> expected_span(vector.data(), vector.size());
1240 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1241 // std::move(foo), make_span does not actually take ownership of the passed in
1242 // container. Writing it this way makes it more obvious that we simply care
1243 // about the right behavour when passing rvalues.
1244 auto made_span = make_span<5>(static_cast<std::vector<int>&&>(vector));
1245 EXPECT_EQ(expected_span.data(), made_span.data());
1246 EXPECT_EQ(expected_span.size(), made_span.size());
1247 static_assert(decltype(made_span)::extent == 5, "");
1248 static_assert(
1249 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1250 "the type of made_span differs from expected_span!");
1251}
1252
1253TEST(SpanTest, MakeSpanFromDynamicSpan) {
1254 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1255 constexpr span<const int> expected_span(kArray);
1256 constexpr auto made_span = make_span(expected_span);
1257 static_assert(std::is_same<decltype(expected_span)::element_type,
1258 decltype(made_span)::element_type>::value,
1259 "make_span(span) should have the same element_type as span");
1260
1261 static_assert(expected_span.data() == made_span.data(),
1262 "make_span(span) should have the same data() as span");
1263
1264 static_assert(expected_span.size() == made_span.size(),
1265 "make_span(span) should have the same size() as span");
1266
1267 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1268 "make_span(span) should have the same extent as span");
1269
1270 static_assert(
1271 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1272 "the type of made_span differs from expected_span!");
1273}
1274
1275TEST(SpanTest, MakeSpanFromStaticSpan) {
1276 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1277 constexpr span<const int, 5> expected_span(kArray);
1278 constexpr auto made_span = make_span(expected_span);
1279 static_assert(std::is_same<decltype(expected_span)::element_type,
1280 decltype(made_span)::element_type>::value,
1281 "make_span(span) should have the same element_type as span");
1282
1283 static_assert(expected_span.data() == made_span.data(),
1284 "make_span(span) should have the same data() as span");
1285
1286 static_assert(expected_span.size() == made_span.size(),
1287 "make_span(span) should have the same size() as span");
1288
1289 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1290 "make_span(span) should have the same extent as span");
1291
1292 static_assert(
1293 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1294 "the type of made_span differs from expected_span!");
1295}
1296#endif // 0
1297
1298TEST(SpanTest, StdTupleSize) {
1299 static_assert(std::tuple_size<span<int, 0>>::value == 0, "");
1300 static_assert(std::tuple_size<span<int, 1>>::value == 1, "");
1301 static_assert(std::tuple_size<span<int, 2>>::value == 2, "");
1302}
1303
1304TEST(SpanTest, StdTupleElement) {
1305 static_assert(std::is_same<int, std::tuple_element_t<0, span<int, 1>>>::value,
1306 "");
1307 static_assert(
1308 std::is_same<const int,
1309 std::tuple_element_t<0, span<const int, 2>>>::value,
1310 "");
1311 static_assert(
1312 std::is_same<const int*,
1313 std::tuple_element_t<1, span<const int*, 2>>>::value,
1314 "");
1315}
1316
1317TEST(SpanTest, StdGet) {
1318 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1319 constexpr span<const int, 5> span(kArray);
1320
1321 static_assert(
1322 &kArray[0] == &std::get<0>(span),
1323 "std::get<0>(span) does not refer to the same element as kArray[0]");
1324 static_assert(
1325 &kArray[1] == &std::get<1>(span),
1326 "std::get<1>(span) does not refer to the same element as kArray[1]");
1327 static_assert(
1328 &kArray[2] == &std::get<2>(span),
1329 "std::get<2>(span) does not refer to the same element as kArray[2]");
1330 static_assert(
1331 &kArray[3] == &std::get<3>(span),
1332 "std::get<3>(span) does not refer to the same element as kArray[3]");
1333 static_assert(
1334 &kArray[4] == &std::get<4>(span),
1335 "std::get<4>(span) does not refer to the same element as kArray[4]");
1336}
1337
1338TEST(SpanTest, EnsureConstexprGoodness) {
1339 static constexpr int kArray[] = {5, 4, 3, 2, 1};
1340 constexpr span<const int> constexpr_span(kArray);
1341 const size_t size = 2;
1342
1343 const size_t start = 1;
1344 constexpr span<const int> subspan =
1345 constexpr_span.subspan(start, start + size);
1346 for (size_t i = 0; i < subspan.size(); ++i)
1347 EXPECT_EQ(kArray[start + i], subspan[i]);
1348
1349 constexpr span<const int> firsts = constexpr_span.first(size);
1350 for (size_t i = 0; i < firsts.size(); ++i)
1351 EXPECT_EQ(kArray[i], firsts[i]);
1352
1353 constexpr span<const int> lasts = constexpr_span.last(size);
1354 for (size_t i = 0; i < lasts.size(); ++i) {
1355 const size_t j = (std::size(kArray) - size) + i;
1356 EXPECT_EQ(kArray[j], lasts[i]);
1357 }
1358
1359 constexpr int item = constexpr_span[size];
1360 EXPECT_EQ(kArray[size], item);
1361}
1362
1363#if 0
1364
1365// Pigweed: Death tests are not yet supported.
1366TEST(SpanTest, OutOfBoundsDeath) {
1367 constexpr span<int, 0> kEmptySpan;
1368 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan[0], "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001369 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.first(1), "");
1370 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.last(1), "");
1371 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1), "");
1372
1373 constexpr span<int> kEmptyDynamicSpan;
1374 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan[0], "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001375 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.front(), "");
1376 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.first(1), "");
1377 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.last(1), "");
1378 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.back(), "");
1379 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.subspan(1), "");
1380
1381 static constexpr int kArray[] = {0, 1, 2};
1382 constexpr span<const int> kNonEmptyDynamicSpan(kArray);
1383 EXPECT_EQ(3U, kNonEmptyDynamicSpan.size());
1384 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan[4], "");
Wyatt Hepler64c165e2020-01-13 10:21:08 -08001385 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(10), "");
1386 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(1, 7), "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001387}
1388
1389// Pigweed: These tests use CheckedContiguousConstIterator, which isn't used in
1390// Pigweed's version.
1391TEST(SpanTest, IteratorIsRangeMoveSafe) {
1392 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1393 const size_t kNumElements = 5;
1394 constexpr span<const int> span(kArray);
1395
1396 static constexpr int kOverlappingStartIndexes[] = {-4, 0, 3, 4};
1397 static constexpr int kNonOverlappingStartIndexes[] = {-7, -5, 5, 7};
1398
1399 // Overlapping ranges.
1400 for (const int dest_start_index : kOverlappingStartIndexes) {
1401 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1402 span.begin(), span.end(),
1403 CheckedContiguousIterator<const int>(
1404 span.data() + dest_start_index,
1405 span.data() + dest_start_index + kNumElements)));
1406 EXPECT_FALSE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1407 span.cbegin(), span.cend(),
1408 CheckedContiguousConstIterator<const int>(
1409 span.data() + dest_start_index,
1410 span.data() + dest_start_index + kNumElements)));
1411 }
1412
1413 // Non-overlapping ranges.
1414 for (const int dest_start_index : kNonOverlappingStartIndexes) {
1415 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1416 span.begin(), span.end(),
1417 CheckedContiguousIterator<const int>(
1418 span.data() + dest_start_index,
1419 span.data() + dest_start_index + kNumElements)));
1420 EXPECT_TRUE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1421 span.cbegin(), span.cend(),
1422 CheckedContiguousConstIterator<const int>(
1423 span.data() + dest_start_index,
1424 span.data() + dest_start_index + kNumElements)));
1425 }
1426
1427 // IsRangeMoveSafe is true if the length to be moved is 0.
1428 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1429 span.begin(), span.begin(),
1430 CheckedContiguousIterator<const int>(span.data(), span.data())));
1431 EXPECT_TRUE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1432 span.cbegin(), span.cbegin(),
1433 CheckedContiguousConstIterator<const int>(span.data(), span.data())));
1434
1435 // IsRangeMoveSafe is false if end < begin.
1436 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1437 span.end(), span.begin(),
1438 CheckedContiguousIterator<const int>(span.data(), span.data())));
1439 EXPECT_FALSE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1440 span.cend(), span.cbegin(),
1441 CheckedContiguousConstIterator<const int>(span.data(), span.data())));
1442}
1443
1444// Pigweed: gMock matchers are not yet supported.
1445TEST(SpanTest, Sort) {
1446 int array[] = {5, 4, 3, 2, 1};
1447
1448 span<int> dynamic_span = array;
1449 std::sort(dynamic_span.begin(), dynamic_span.end());
1450 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1451 std::sort(dynamic_span.rbegin(), dynamic_span.rend());
1452 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1453
1454 span<int, 5> static_span = array;
1455 std::sort(static_span.rbegin(), static_span.rend(), std::greater<>());
1456 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1457 std::sort(static_span.begin(), static_span.end(), std::greater<>());
1458 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1459}
1460#endif // 0
1461
1462TEST(SpanTest, SpanExtentConversions) {
1463 // Statically checks that various conversions between spans of dynamic and
1464 // static extent are possible or not.
1465 static_assert(
1466 !std::is_constructible<span<int, 0>, span<int>>::value,
1467 "Error: static span should not be constructible from dynamic span");
1468
1469 static_assert(!std::is_constructible<span<int, 2>, span<int, 1>>::value,
1470 "Error: static span should not be constructible from static "
1471 "span with different extent");
1472
1473 static_assert(std::is_convertible<span<int, 0>, span<int>>::value,
1474 "Error: static span should be convertible to dynamic span");
1475
1476 static_assert(std::is_convertible<span<int>, span<int>>::value,
1477 "Error: dynamic span should be convertible to dynamic span");
1478
1479 static_assert(std::is_convertible<span<int, 2>, span<int, 2>>::value,
1480 "Error: static span should be convertible to static span");
1481}
1482
1483TEST(SpanTest, IteratorConversions) {
1484 static_assert(std::is_convertible<span<int>::iterator,
1485 span<int>::const_iterator>::value,
1486 "Error: iterator should be convertible to const_iterator");
1487
1488 static_assert(!std::is_convertible<span<int>::const_iterator,
1489 span<int>::iterator>::value,
1490 "Error: const_iterator should not be convertible to iterator");
1491}
1492
1493} // namespace pw