1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
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
12 // License for the specific language governing permissions and limitations under
15 // This is the base::span unit test from Chromium, with small modifications.
16 // Modifications are noted with "Pigweed:" comments.
19 // https://chromium.googlesource.com/chromium/src/+/ef71f9c29f0dc6eddae474879c4ca5232ca93a6c/base/containers/span_unittest.cc
21 // In order to minimize changes from the original, this file does NOT fully
22 // adhere to Pigweed's style guide.
29 #include <type_traits>
32 #include "gtest/gtest.h"
34 // Pigweed: gMock matchers are not yet supported.
36 using ::testing::ElementsAre;
38 using ::testing::Pointwise;
45 // constexpr implementation of std::equal's 4 argument overload.
46 template <class InputIterator1, class InputIterator2>
47 constexpr bool constexpr_equal(InputIterator1 first1,
49 InputIterator2 first2,
50 InputIterator2 last2) {
51 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
52 if (*first1 != *first2)
56 return first1 == last1 && first2 == last2;
61 TEST(SpanTest, DeductionGuides_MutableArray) {
62 char array[] = {'a', 'b', 'c', 'd', '\0'};
64 auto the_span = span(array);
65 static_assert(the_span.extent == 5u);
66 static_assert(the_span.size() == 5u);
69 EXPECT_STREQ(the_span.data(), "!bcd");
72 TEST(SpanTest, DeductionGuides_ConstArray) {
73 static constexpr char array[] = {'a', 'b', 'c', 'd', '\0'};
75 constexpr auto the_span = span(array);
76 static_assert(the_span.extent == 5u);
77 static_assert(the_span.size() == 5u);
79 EXPECT_STREQ(the_span.data(), "abcd");
82 TEST(SpanTest, DeductionGuides_MutableStdArray) {
83 std::array<char, 5> array{'a', 'b', 'c', 'd'};
85 auto the_span = span(array);
86 static_assert(the_span.extent == 5u);
87 static_assert(the_span.size() == 5u);
90 EXPECT_STREQ(the_span.data(), "?bcd");
93 TEST(SpanTest, DeductionGuides_ConstStdArray) {
94 static constexpr std::array<char, 5> array{'a', 'b', 'c', 'd'};
96 constexpr auto the_span = span(array);
97 static_assert(the_span.extent == 5u);
98 static_assert(the_span.size() == 5u);
100 EXPECT_STREQ(the_span.data(), "abcd");
103 TEST(SpanTest, DeductionGuides_MutableContainerWithConstElements) {
104 std::string_view string("Hello");
105 auto the_span = span(string);
106 static_assert(the_span.extent == dynamic_extent);
108 EXPECT_STREQ("Hello", the_span.data());
109 EXPECT_EQ(5u, the_span.size());
112 TEST(SpanTest, DeductionGuides_MutableContainerWithMutableElements) {
113 std::string string("Hello");
114 auto the_span = span(string);
115 static_assert(the_span.extent == dynamic_extent);
117 EXPECT_EQ(5u, the_span.size());
119 EXPECT_STREQ(the_span.data(), string.data());
120 EXPECT_STREQ("Hallo", the_span.data());
123 class MutableStringView {
125 using element_type = char;
126 using value_type = char;
127 using size_type = size_t;
128 using difference_type = ptrdiff_t;
129 using pointer = char*;
130 using reference = char&;
131 using iterator = char*;
132 using const_iterator = const char*;
133 using reverse_iterator = std::reverse_iterator<iterator>;
134 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
136 MutableStringView(char* str) : data_(str, std::strlen(str)) {}
138 char& operator[](size_type index) const { return data_[index]; }
139 pointer data() const { return data_.data(); }
140 size_type size() const { return data_.size(); }
141 iterator begin() const { return data_.begin(); }
142 iterator end() const { return data_.end(); }
148 TEST(SpanTest, DeductionGuides_ConstContainerWithMutableElements) {
149 char data[] = "54321";
150 MutableStringView view(data);
152 auto the_span = span(view);
153 static_assert(the_span.extent == dynamic_extent);
155 EXPECT_EQ(5u, the_span.size());
157 EXPECT_STREQ("54?21", the_span.data());
158 EXPECT_STREQ("54?21", data);
161 TEST(SpanTest, DeductionGuides_ConstContainerWithMutableValueType) {
162 const std::string string("Hello");
163 auto the_span = span(string);
164 static_assert(the_span.extent == dynamic_extent);
166 EXPECT_EQ(5u, the_span.size());
167 EXPECT_STREQ("Hello", the_span.data());
170 TEST(SpanTest, DeductionGuides_ConstContainerWithConstElements) {
171 const std::string_view string("Hello");
172 auto the_span = span(string);
173 static_assert(the_span.extent == dynamic_extent);
175 EXPECT_EQ(5u, the_span.size());
176 EXPECT_STREQ("Hello", the_span.data());
179 TEST(SpanTest, DeductionGuides_FromTemporary_ContainerWithConstElements) {
180 auto the_span = span(std::string_view("Hello"));
181 static_assert(the_span.extent == dynamic_extent);
183 EXPECT_EQ(5u, the_span.size());
184 EXPECT_STREQ("Hello", the_span.data());
187 TEST(SpanTest, DeductionGuides_FromReference) {
188 std::array<int, 5> array{1, 3, 5, 7, 9};
189 std::array<int, 5>& array_ref = array;
191 auto the_span = span(array_ref);
192 static_assert(the_span.extent == 5);
194 for (unsigned i = 0; i < array.size(); ++i) {
195 ASSERT_EQ(array[i], the_span[i]);
199 TEST(SpanTest, DeductionGuides_FromConstReference) {
200 std::string_view string = "yo!";
201 const std::string_view& string_ref = string;
203 auto the_span = span(string_ref);
204 static_assert(the_span.extent == dynamic_extent);
206 EXPECT_EQ(string, the_span.data());
209 TEST(SpanTest, DefaultConstructor) {
210 span<int> dynamic_span;
211 EXPECT_EQ(nullptr, dynamic_span.data());
212 EXPECT_EQ(0u, dynamic_span.size());
214 constexpr span<int, 0> static_span;
215 static_assert(nullptr == static_span.data(), "");
216 static_assert(static_span.empty(), "");
219 TEST(SpanTest, ConstructFromDataAndSize) {
220 constexpr span<int> empty_span(nullptr, 0);
221 EXPECT_TRUE(empty_span.empty());
222 EXPECT_EQ(nullptr, empty_span.data());
224 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
226 span<int> dynamic_span(vector.data(), vector.size());
227 EXPECT_EQ(vector.data(), dynamic_span.data());
228 EXPECT_EQ(vector.size(), dynamic_span.size());
230 for (size_t i = 0; i < dynamic_span.size(); ++i)
231 EXPECT_EQ(vector[i], dynamic_span[i]);
233 span<int, 6> static_span(vector.data(), vector.size());
234 EXPECT_EQ(vector.data(), static_span.data());
235 EXPECT_EQ(vector.size(), static_span.size());
237 for (size_t i = 0; i < static_span.size(); ++i)
238 EXPECT_EQ(vector[i], static_span[i]);
241 TEST(SpanTest, ConstructFromPointerPair) {
242 constexpr span<int> empty_span(nullptr, nullptr);
243 EXPECT_TRUE(empty_span.empty());
244 EXPECT_EQ(nullptr, empty_span.data());
246 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
248 span<int> dynamic_span(vector.data(), vector.data() + vector.size() / 2);
249 EXPECT_EQ(vector.data(), dynamic_span.data());
250 EXPECT_EQ(vector.size() / 2, dynamic_span.size());
252 for (size_t i = 0; i < dynamic_span.size(); ++i)
253 EXPECT_EQ(vector[i], dynamic_span[i]);
255 span<int, 3> static_span(vector.data(), vector.data() + vector.size() / 2);
256 EXPECT_EQ(vector.data(), static_span.data());
257 EXPECT_EQ(vector.size() / 2, static_span.size());
259 for (size_t i = 0; i < static_span.size(); ++i)
260 EXPECT_EQ(vector[i], static_span[i]);
263 TEST(SpanTest, AllowedConversionsFromStdArray) {
264 // In the following assertions we use std::is_convertible_v<From, To>, which
265 // for non-void types is equivalent to checking whether the following
266 // expression is well-formed:
268 // T obj = std::declval<From>();
270 // In particular we are checking whether From is implicitly convertible to To,
271 // which also implies that To is explicitly constructible from From.
273 std::is_convertible<std::array<int, 3>&, span<int>>::value,
274 "Error: l-value reference to std::array<int> should be convertible to "
275 "span<int> with dynamic extent.");
277 std::is_convertible<std::array<int, 3>&, span<int, 3>>::value,
278 "Error: l-value reference to std::array<int> should be convertible to "
279 "span<int> with the same static extent.");
281 std::is_convertible<std::array<int, 3>&, span<const int>>::value,
282 "Error: l-value reference to std::array<int> should be convertible to "
283 "span<const int> with dynamic extent.");
285 std::is_convertible<std::array<int, 3>&, span<const int, 3>>::value,
286 "Error: l-value reference to std::array<int> should be convertible to "
287 "span<const int> with the same static extent.");
289 std::is_convertible<const std::array<int, 3>&, span<const int>>::value,
290 "Error: const l-value reference to std::array<int> should be "
291 "convertible to span<const int> with dynamic extent.");
293 std::is_convertible<const std::array<int, 3>&, span<const int, 3>>::value,
294 "Error: const l-value reference to std::array<int> should be convertible "
295 "to span<const int> with the same static extent.");
297 std::is_convertible<std::array<const int, 3>&, span<const int>>::value,
298 "Error: l-value reference to std::array<const int> should be "
299 "convertible to span<const int> with dynamic extent.");
301 std::is_convertible<std::array<const int, 3>&, span<const int, 3>>::value,
302 "Error: l-value reference to std::array<const int> should be convertible "
303 "to span<const int> with the same static extent.");
305 std::is_convertible<const std::array<const int, 3>&,
306 span<const int>>::value,
307 "Error: const l-value reference to std::array<const int> should be "
308 "convertible to span<const int> with dynamic extent.");
310 std::is_convertible<const std::array<const int, 3>&,
311 span<const int, 3>>::value,
312 "Error: const l-value reference to std::array<const int> should be "
313 "convertible to span<const int> with the same static extent.");
316 TEST(SpanTest, DisallowedConstructionsFromStdArray) {
317 // In the following assertions we use !std::is_constructible_v<T, Args>, which
318 // is equivalent to checking whether the following expression is malformed:
320 // T obj(std::declval<Args>()...);
322 // In particular we are checking that T is not explicitly constructible from
323 // Args, which also implies that T is not implicitly constructible from Args
326 !std::is_constructible<span<int>, const std::array<int, 3>&>::value,
327 "Error: span<int> with dynamic extent should not be constructible "
328 "from const l-value reference to std::array<int>");
331 !std::is_constructible<span<int>, std::array<const int, 3>&>::value,
332 "Error: span<int> with dynamic extent should not be constructible "
333 "from l-value reference to std::array<const int>");
336 !std::is_constructible<span<int>, const std::array<const int, 3>&>::value,
337 "Error: span<int> with dynamic extent should not be constructible "
338 "const from l-value reference to std::array<const int>");
341 !std::is_constructible<span<int, 2>, std::array<int, 3>&>::value,
342 "Error: span<int> with static extent should not be constructible "
343 "from l-value reference to std::array<int> with different extent");
346 !std::is_constructible<span<int, 4>, std::array<int, 3>&>::value,
347 "Error: span<int> with dynamic extent should not be constructible "
348 "from l-value reference to std::array<int> with different extent");
351 !std::is_constructible<span<int>, std::array<bool, 3>&>::value,
352 "Error: span<int> with dynamic extent should not be constructible "
353 "from l-value reference to std::array<bool>");
356 TEST(SpanTest, ConstructFromConstexprArray) {
357 static constexpr int kArray[] = {5, 4, 3, 2, 1};
359 constexpr span<const int> dynamic_span(kArray);
360 static_assert(kArray == dynamic_span.data(), "");
361 static_assert(std::size(kArray) == dynamic_span.size(), "");
363 static_assert(kArray[0] == dynamic_span[0], "");
364 static_assert(kArray[1] == dynamic_span[1], "");
365 static_assert(kArray[2] == dynamic_span[2], "");
366 static_assert(kArray[3] == dynamic_span[3], "");
367 static_assert(kArray[4] == dynamic_span[4], "");
369 constexpr span<const int, std::size(kArray)> static_span(kArray);
370 static_assert(kArray == static_span.data(), "");
371 static_assert(std::size(kArray) == static_span.size(), "");
373 static_assert(kArray[0] == static_span[0], "");
374 static_assert(kArray[1] == static_span[1], "");
375 static_assert(kArray[2] == static_span[2], "");
376 static_assert(kArray[3] == static_span[3], "");
377 static_assert(kArray[4] == static_span[4], "");
380 TEST(SpanTest, ConstructFromArray) {
381 int array[] = {5, 4, 3, 2, 1};
383 span<const int> const_span(array);
384 EXPECT_EQ(array, const_span.data());
385 EXPECT_EQ(std::size(array), const_span.size());
386 for (size_t i = 0; i < const_span.size(); ++i)
387 EXPECT_EQ(array[i], const_span[i]);
389 span<int> dynamic_span(array);
390 EXPECT_EQ(array, dynamic_span.data());
391 EXPECT_EQ(std::size(array), dynamic_span.size());
392 for (size_t i = 0; i < dynamic_span.size(); ++i)
393 EXPECT_EQ(array[i], dynamic_span[i]);
395 span<int, std::size(array)> static_span(array);
396 EXPECT_EQ(array, static_span.data());
397 EXPECT_EQ(std::size(array), static_span.size());
398 for (size_t i = 0; i < static_span.size(); ++i)
399 EXPECT_EQ(array[i], static_span[i]);
402 TEST(SpanTest, ConstructFromStdArray) {
403 // Note: Constructing a constexpr span from a constexpr std::array does not
404 // work prior to C++17 due to non-constexpr std::array::data.
405 std::array<int, 5> array = {{5, 4, 3, 2, 1}};
407 span<const int> const_span(array);
408 EXPECT_EQ(array.data(), const_span.data());
409 EXPECT_EQ(array.size(), const_span.size());
410 for (size_t i = 0; i < const_span.size(); ++i)
411 EXPECT_EQ(array[i], const_span[i]);
413 span<int> dynamic_span(array);
414 EXPECT_EQ(array.data(), dynamic_span.data());
415 EXPECT_EQ(array.size(), dynamic_span.size());
416 for (size_t i = 0; i < dynamic_span.size(); ++i)
417 EXPECT_EQ(array[i], dynamic_span[i]);
419 span<int, std::size(array)> static_span(array);
420 EXPECT_EQ(array.data(), static_span.data());
421 EXPECT_EQ(array.size(), static_span.size());
422 for (size_t i = 0; i < static_span.size(); ++i)
423 EXPECT_EQ(array[i], static_span[i]);
426 TEST(SpanTest, ConstructFromInitializerList) {
427 std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
429 span<const int> const_span(il);
430 EXPECT_EQ(il.begin(), const_span.data());
431 EXPECT_EQ(il.size(), const_span.size());
433 for (size_t i = 0; i < const_span.size(); ++i)
434 EXPECT_EQ(il.begin()[i], const_span[i]);
436 span<const int, 6> static_span(il.begin(), il.end());
437 EXPECT_EQ(il.begin(), static_span.data());
438 EXPECT_EQ(il.size(), static_span.size());
440 for (size_t i = 0; i < static_span.size(); ++i)
441 EXPECT_EQ(il.begin()[i], static_span[i]);
444 TEST(SpanTest, ConstructFromStdString) {
445 std::string str = "foobar";
447 span<const char> const_span(str);
448 EXPECT_EQ(str.data(), const_span.data());
449 EXPECT_EQ(str.size(), const_span.size());
451 for (size_t i = 0; i < const_span.size(); ++i)
452 EXPECT_EQ(str[i], const_span[i]);
454 span<char> dynamic_span(str);
455 EXPECT_EQ(str.data(), dynamic_span.data());
456 EXPECT_EQ(str.size(), dynamic_span.size());
458 for (size_t i = 0; i < dynamic_span.size(); ++i)
459 EXPECT_EQ(str[i], dynamic_span[i]);
461 span<char, 6> static_span(data(str), str.size());
462 EXPECT_EQ(str.data(), static_span.data());
463 EXPECT_EQ(str.size(), static_span.size());
465 for (size_t i = 0; i < static_span.size(); ++i)
466 EXPECT_EQ(str[i], static_span[i]);
469 TEST(SpanTest, ConstructFromConstContainer) {
470 const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
472 span<const int> const_span(vector);
473 EXPECT_EQ(vector.data(), const_span.data());
474 EXPECT_EQ(vector.size(), const_span.size());
476 for (size_t i = 0; i < const_span.size(); ++i)
477 EXPECT_EQ(vector[i], const_span[i]);
479 span<const int, 6> static_span(vector.data(), vector.size());
480 EXPECT_EQ(vector.data(), static_span.data());
481 EXPECT_EQ(vector.size(), static_span.size());
483 for (size_t i = 0; i < static_span.size(); ++i)
484 EXPECT_EQ(vector[i], static_span[i]);
487 TEST(SpanTest, ConstructFromContainer) {
488 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
490 span<const int> const_span(vector);
491 EXPECT_EQ(vector.data(), const_span.data());
492 EXPECT_EQ(vector.size(), const_span.size());
494 for (size_t i = 0; i < const_span.size(); ++i)
495 EXPECT_EQ(vector[i], const_span[i]);
497 span<int> dynamic_span(vector);
498 EXPECT_EQ(vector.data(), dynamic_span.data());
499 EXPECT_EQ(vector.size(), dynamic_span.size());
501 for (size_t i = 0; i < dynamic_span.size(); ++i)
502 EXPECT_EQ(vector[i], dynamic_span[i]);
504 span<int, 6> static_span(vector.data(), vector.size());
505 EXPECT_EQ(vector.data(), static_span.data());
506 EXPECT_EQ(vector.size(), static_span.size());
508 for (size_t i = 0; i < static_span.size(); ++i)
509 EXPECT_EQ(vector[i], static_span[i]);
514 // Pigweed: gMock matchers are not yet supported.
515 TEST(SpanTest, ConvertNonConstIntegralToConst) {
516 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
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());
522 EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
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));
529 // Pigweed: gMock matchers are not yet supported.
530 TEST(SpanTest, ConvertNonConstPointerToConst) {
531 auto a = std::make_unique<int>(11);
532 auto b = std::make_unique<int>(22);
533 auto c = std::make_unique<int>(33);
534 std::vector<int*> vector = {a.get(), b.get(), c.get()};
536 span<int*> non_const_pointer_span(vector);
537 EXPECT_THAT(non_const_pointer_span, Pointwise(Eq(), vector));
538 span<int* const> const_pointer_span(non_const_pointer_span);
539 EXPECT_THAT(const_pointer_span, Pointwise(Eq(), non_const_pointer_span));
540 // Note: no test for conversion from span<int> to span<const int*>, since that
541 // would imply a conversion from int** to const int**, which is unsafe.
543 // Note: no test for conversion from span<int*> to span<const int* const>,
544 // due to CWG Defect 330:
545 // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
547 span<int*, 3> static_non_const_pointer_span(vector.data(), vector.size());
548 EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
549 span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
550 EXPECT_THAT(static_const_pointer_span,
551 Pointwise(Eq(), static_non_const_pointer_span));
554 // Pigweed: This test does not work on platforms where int32_t is long int.
555 TEST(SpanTest, ConvertBetweenEquivalentTypes) {
556 std::vector<int32_t> vector = {2, 4, 8, 16, 32};
558 span<int32_t> int32_t_span(vector);
559 span<int> converted_span(int32_t_span);
560 EXPECT_EQ(int32_t_span.data(), converted_span.data());
561 EXPECT_EQ(int32_t_span.size(), converted_span.size());
563 span<int32_t, 5> static_int32_t_span(vector.data(), vector.size());
564 span<int, 5> static_converted_span(static_int32_t_span);
565 EXPECT_EQ(static_int32_t_span.data(), static_converted_span.data());
566 EXPECT_EQ(static_int32_t_span.size(), static_converted_span.size());
571 TEST(SpanTest, TemplatedFirst) {
572 static constexpr int array[] = {1, 2, 3};
573 constexpr span<const int, 3> span(array);
576 constexpr auto subspan = span.first<0>();
577 static_assert(span.data() == subspan.data(), "");
578 static_assert(subspan.empty(), "");
579 static_assert(0u == decltype(subspan)::extent, "");
583 constexpr auto subspan = span.first<1>();
584 static_assert(span.data() == subspan.data(), "");
585 static_assert(1u == subspan.size(), "");
586 static_assert(1u == decltype(subspan)::extent, "");
587 static_assert(1 == subspan[0], "");
591 constexpr auto subspan = span.first<2>();
592 static_assert(span.data() == subspan.data(), "");
593 static_assert(2u == subspan.size(), "");
594 static_assert(2u == decltype(subspan)::extent, "");
595 static_assert(1 == subspan[0], "");
596 static_assert(2 == subspan[1], "");
600 constexpr auto subspan = span.first<3>();
601 static_assert(span.data() == subspan.data(), "");
602 static_assert(3u == subspan.size(), "");
603 static_assert(3u == decltype(subspan)::extent, "");
604 static_assert(1 == subspan[0], "");
605 static_assert(2 == subspan[1], "");
606 static_assert(3 == subspan[2], "");
610 TEST(SpanTest, TemplatedLast) {
611 static constexpr int array[] = {1, 2, 3};
612 constexpr span<const int, 3> span(array);
615 constexpr auto subspan = span.last<0>();
616 static_assert(span.data() + 3 == subspan.data(), "");
617 static_assert(subspan.empty(), "");
618 static_assert(0u == decltype(subspan)::extent, "");
622 constexpr auto subspan = span.last<1>();
623 static_assert(span.data() + 2 == subspan.data(), "");
624 static_assert(1u == subspan.size(), "");
625 static_assert(1u == decltype(subspan)::extent, "");
626 static_assert(3 == subspan[0], "");
630 constexpr auto subspan = span.last<2>();
631 static_assert(span.data() + 1 == subspan.data(), "");
632 static_assert(2u == subspan.size(), "");
633 static_assert(2u == decltype(subspan)::extent, "");
634 static_assert(2 == subspan[0], "");
635 static_assert(3 == subspan[1], "");
639 constexpr auto subspan = span.last<3>();
640 static_assert(span.data() == subspan.data(), "");
641 static_assert(3u == subspan.size(), "");
642 static_assert(3u == decltype(subspan)::extent, "");
643 static_assert(1 == subspan[0], "");
644 static_assert(2 == subspan[1], "");
645 static_assert(3 == subspan[2], "");
649 TEST(SpanTest, TemplatedSubspan) {
650 static constexpr int array[] = {1, 2, 3};
651 constexpr span<const int, 3> span(array);
654 constexpr auto subspan = span.subspan<0>();
655 static_assert(span.data() == subspan.data(), "");
656 static_assert(3u == subspan.size(), "");
657 static_assert(3u == decltype(subspan)::extent, "");
658 static_assert(1 == subspan[0], "");
659 static_assert(2 == subspan[1], "");
660 static_assert(3 == subspan[2], "");
664 constexpr auto subspan = span.subspan<1>();
665 static_assert(span.data() + 1 == subspan.data(), "");
666 static_assert(2u == subspan.size(), "");
667 static_assert(2u == decltype(subspan)::extent, "");
668 static_assert(2 == subspan[0], "");
669 static_assert(3 == subspan[1], "");
673 constexpr auto subspan = span.subspan<2>();
674 static_assert(span.data() + 2 == subspan.data(), "");
675 static_assert(1u == subspan.size(), "");
676 static_assert(1u == decltype(subspan)::extent, "");
677 static_assert(3 == subspan[0], "");
681 constexpr auto subspan = span.subspan<3>();
682 static_assert(span.data() + 3 == subspan.data(), "");
683 static_assert(subspan.empty(), "");
684 static_assert(0u == decltype(subspan)::extent, "");
688 constexpr auto subspan = span.subspan<0, 0>();
689 static_assert(span.data() == subspan.data(), "");
690 static_assert(subspan.empty(), "");
691 static_assert(0u == decltype(subspan)::extent, "");
695 constexpr auto subspan = span.subspan<1, 0>();
696 static_assert(span.data() + 1 == subspan.data(), "");
697 static_assert(subspan.empty(), "");
698 static_assert(0u == decltype(subspan)::extent, "");
702 constexpr auto subspan = span.subspan<2, 0>();
703 static_assert(span.data() + 2 == subspan.data(), "");
704 static_assert(subspan.empty(), "");
705 static_assert(0u == decltype(subspan)::extent, "");
709 constexpr auto subspan = span.subspan<0, 1>();
710 static_assert(span.data() == subspan.data(), "");
711 static_assert(1u == subspan.size(), "");
712 static_assert(1u == decltype(subspan)::extent, "");
713 static_assert(1 == subspan[0], "");
717 constexpr auto subspan = span.subspan<1, 1>();
718 static_assert(span.data() + 1 == subspan.data(), "");
719 static_assert(1u == subspan.size(), "");
720 static_assert(1u == decltype(subspan)::extent, "");
721 static_assert(2 == subspan[0], "");
725 constexpr auto subspan = span.subspan<2, 1>();
726 static_assert(span.data() + 2 == subspan.data(), "");
727 static_assert(1u == subspan.size(), "");
728 static_assert(1u == decltype(subspan)::extent, "");
729 static_assert(3 == subspan[0], "");
733 constexpr auto subspan = span.subspan<0, 2>();
734 static_assert(span.data() == subspan.data(), "");
735 static_assert(2u == subspan.size(), "");
736 static_assert(2u == decltype(subspan)::extent, "");
737 static_assert(1 == subspan[0], "");
738 static_assert(2 == subspan[1], "");
742 constexpr auto subspan = span.subspan<1, 2>();
743 static_assert(span.data() + 1 == subspan.data(), "");
744 static_assert(2u == subspan.size(), "");
745 static_assert(2u == decltype(subspan)::extent, "");
746 static_assert(2 == subspan[0], "");
747 static_assert(3 == subspan[1], "");
751 constexpr auto subspan = span.subspan<0, 3>();
752 static_assert(span.data() == subspan.data(), "");
753 static_assert(3u == subspan.size(), "");
754 static_assert(3u == decltype(subspan)::extent, "");
755 static_assert(1 == subspan[0], "");
756 static_assert(2 == subspan[1], "");
757 static_assert(3 == subspan[2], "");
761 TEST(SpanTest, SubscriptedBeginIterator) {
762 int array[] = {1, 2, 3};
763 span<const int> const_span(array);
764 for (size_t i = 0; i < const_span.size(); ++i)
765 EXPECT_EQ(array[i], const_span.begin()[i]);
767 span<int> mutable_span(array);
768 for (size_t i = 0; i < mutable_span.size(); ++i)
769 EXPECT_EQ(array[i], mutable_span.begin()[i]);
772 TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
773 int array[] = {1, 2, 3};
774 span<const int> span(array);
777 auto subspan = span.first<0>();
778 EXPECT_EQ(span.data(), subspan.data());
779 EXPECT_EQ(0u, subspan.size());
780 static_assert(0u == decltype(subspan)::extent, "");
784 auto subspan = span.first<1>();
785 EXPECT_EQ(span.data(), subspan.data());
786 EXPECT_EQ(1u, subspan.size());
787 static_assert(1u == decltype(subspan)::extent, "");
788 EXPECT_EQ(1, subspan[0]);
792 auto subspan = span.first<2>();
793 EXPECT_EQ(span.data(), subspan.data());
794 EXPECT_EQ(2u, subspan.size());
795 static_assert(2u == decltype(subspan)::extent, "");
796 EXPECT_EQ(1, subspan[0]);
797 EXPECT_EQ(2, subspan[1]);
801 auto subspan = span.first<3>();
802 EXPECT_EQ(span.data(), subspan.data());
803 EXPECT_EQ(3u, subspan.size());
804 static_assert(3u == decltype(subspan)::extent, "");
805 EXPECT_EQ(1, subspan[0]);
806 EXPECT_EQ(2, subspan[1]);
807 EXPECT_EQ(3, subspan[2]);
811 TEST(SpanTest, TemplatedLastOnDynamicSpan) {
812 int array[] = {1, 2, 3};
813 span<int> span(array);
816 auto subspan = span.last<0>();
817 EXPECT_EQ(span.data() + 3, subspan.data());
818 EXPECT_EQ(0u, subspan.size());
819 static_assert(0u == decltype(subspan)::extent, "");
823 auto subspan = span.last<1>();
824 EXPECT_EQ(span.data() + 2, subspan.data());
825 EXPECT_EQ(1u, subspan.size());
826 static_assert(1u == decltype(subspan)::extent, "");
827 EXPECT_EQ(3, subspan[0]);
831 auto subspan = span.last<2>();
832 EXPECT_EQ(span.data() + 1, subspan.data());
833 EXPECT_EQ(2u, subspan.size());
834 static_assert(2u == decltype(subspan)::extent, "");
835 EXPECT_EQ(2, subspan[0]);
836 EXPECT_EQ(3, subspan[1]);
840 auto subspan = span.last<3>();
841 EXPECT_EQ(span.data(), subspan.data());
842 EXPECT_EQ(3u, subspan.size());
843 static_assert(3u == decltype(subspan)::extent, "");
844 EXPECT_EQ(1, subspan[0]);
845 EXPECT_EQ(2, subspan[1]);
846 EXPECT_EQ(3, subspan[2]);
850 TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
851 int array[] = {1, 2, 3};
852 span<int, 3> span(array);
855 auto subspan = span.subspan<0>();
856 EXPECT_EQ(span.data(), subspan.data());
857 static_assert(3u == decltype(subspan)::extent, "");
858 EXPECT_EQ(3u, subspan.size());
859 EXPECT_EQ(1, subspan[0]);
860 EXPECT_EQ(2, subspan[1]);
861 EXPECT_EQ(3, subspan[2]);
865 auto subspan = span.subspan<1>();
866 EXPECT_EQ(span.data() + 1, subspan.data());
867 EXPECT_EQ(2u, subspan.size());
868 static_assert(2u == decltype(subspan)::extent, "");
869 EXPECT_EQ(2, subspan[0]);
870 EXPECT_EQ(3, subspan[1]);
874 auto subspan = span.subspan<2>();
875 EXPECT_EQ(span.data() + 2, subspan.data());
876 EXPECT_EQ(1u, subspan.size());
877 static_assert(1u == decltype(subspan)::extent, "");
878 EXPECT_EQ(3, subspan[0]);
882 auto subspan = span.subspan<3>();
883 EXPECT_EQ(span.data() + 3, subspan.data());
884 EXPECT_EQ(0u, subspan.size());
885 static_assert(0u == decltype(subspan)::extent, "");
889 auto subspan = span.subspan<0, 0>();
890 EXPECT_EQ(span.data(), subspan.data());
891 EXPECT_EQ(0u, subspan.size());
892 static_assert(0u == decltype(subspan)::extent, "");
896 auto subspan = span.subspan<1, 0>();
897 EXPECT_EQ(span.data() + 1, subspan.data());
898 EXPECT_EQ(0u, subspan.size());
899 static_assert(0u == decltype(subspan)::extent, "");
903 auto subspan = span.subspan<2, 0>();
904 EXPECT_EQ(span.data() + 2, subspan.data());
905 EXPECT_EQ(0u, subspan.size());
906 static_assert(0u == decltype(subspan)::extent, "");
910 auto subspan = span.subspan<0, 1>();
911 EXPECT_EQ(span.data(), subspan.data());
912 EXPECT_EQ(1u, subspan.size());
913 static_assert(1u == decltype(subspan)::extent, "");
914 EXPECT_EQ(1, subspan[0]);
918 auto subspan = span.subspan<1, 1>();
919 EXPECT_EQ(span.data() + 1, subspan.data());
920 EXPECT_EQ(1u, subspan.size());
921 static_assert(1u == decltype(subspan)::extent, "");
922 EXPECT_EQ(2, subspan[0]);
926 auto subspan = span.subspan<2, 1>();
927 EXPECT_EQ(span.data() + 2, subspan.data());
928 EXPECT_EQ(1u, subspan.size());
929 static_assert(1u == decltype(subspan)::extent, "");
930 EXPECT_EQ(3, subspan[0]);
934 auto subspan = span.subspan<0, 2>();
935 EXPECT_EQ(span.data(), subspan.data());
936 EXPECT_EQ(2u, subspan.size());
937 static_assert(2u == decltype(subspan)::extent, "");
938 EXPECT_EQ(1, subspan[0]);
939 EXPECT_EQ(2, subspan[1]);
943 auto subspan = span.subspan<1, 2>();
944 EXPECT_EQ(span.data() + 1, subspan.data());
945 EXPECT_EQ(2u, subspan.size());
946 static_assert(2u == decltype(subspan)::extent, "");
947 EXPECT_EQ(2, subspan[0]);
948 EXPECT_EQ(3, subspan[1]);
952 auto subspan = span.subspan<0, 3>();
953 EXPECT_EQ(span.data(), subspan.data());
954 EXPECT_EQ(3u, subspan.size());
955 static_assert(3u == decltype(subspan)::extent, "");
956 EXPECT_EQ(1, subspan[0]);
957 EXPECT_EQ(2, subspan[1]);
958 EXPECT_EQ(3, subspan[2]);
962 TEST(SpanTest, First) {
963 int array[] = {1, 2, 3};
964 span<int> span(array);
967 auto subspan = span.first(0);
968 EXPECT_EQ(span.data(), subspan.data());
969 EXPECT_EQ(0u, subspan.size());
973 auto subspan = span.first(1);
974 EXPECT_EQ(span.data(), subspan.data());
975 EXPECT_EQ(1u, subspan.size());
976 EXPECT_EQ(1, subspan[0]);
980 auto subspan = span.first(2);
981 EXPECT_EQ(span.data(), subspan.data());
982 EXPECT_EQ(2u, subspan.size());
983 EXPECT_EQ(1, subspan[0]);
984 EXPECT_EQ(2, subspan[1]);
988 auto subspan = span.first(3);
989 EXPECT_EQ(span.data(), subspan.data());
990 EXPECT_EQ(3u, subspan.size());
991 EXPECT_EQ(1, subspan[0]);
992 EXPECT_EQ(2, subspan[1]);
993 EXPECT_EQ(3, subspan[2]);
997 TEST(SpanTest, Last) {
998 int array[] = {1, 2, 3};
999 span<int> span(array);
1002 auto subspan = span.last(0);
1003 EXPECT_EQ(span.data() + 3, subspan.data());
1004 EXPECT_EQ(0u, subspan.size());
1008 auto subspan = span.last(1);
1009 EXPECT_EQ(span.data() + 2, subspan.data());
1010 EXPECT_EQ(1u, subspan.size());
1011 EXPECT_EQ(3, subspan[0]);
1015 auto subspan = span.last(2);
1016 EXPECT_EQ(span.data() + 1, subspan.data());
1017 EXPECT_EQ(2u, subspan.size());
1018 EXPECT_EQ(2, subspan[0]);
1019 EXPECT_EQ(3, subspan[1]);
1023 auto subspan = span.last(3);
1024 EXPECT_EQ(span.data(), subspan.data());
1025 EXPECT_EQ(3u, subspan.size());
1026 EXPECT_EQ(1, subspan[0]);
1027 EXPECT_EQ(2, subspan[1]);
1028 EXPECT_EQ(3, subspan[2]);
1032 TEST(SpanTest, Subspan) {
1033 int array[] = {1, 2, 3};
1034 span<int> span(array);
1037 auto subspan = span.subspan(0);
1038 EXPECT_EQ(span.data(), subspan.data());
1039 EXPECT_EQ(3u, subspan.size());
1040 EXPECT_EQ(1, subspan[0]);
1041 EXPECT_EQ(2, subspan[1]);
1042 EXPECT_EQ(3, subspan[2]);
1046 auto subspan = span.subspan(1);
1047 EXPECT_EQ(span.data() + 1, subspan.data());
1048 EXPECT_EQ(2u, subspan.size());
1049 EXPECT_EQ(2, subspan[0]);
1050 EXPECT_EQ(3, subspan[1]);
1054 auto subspan = span.subspan(2);
1055 EXPECT_EQ(span.data() + 2, subspan.data());
1056 EXPECT_EQ(1u, subspan.size());
1057 EXPECT_EQ(3, subspan[0]);
1061 auto subspan = span.subspan(3);
1062 EXPECT_EQ(span.data() + 3, subspan.data());
1063 EXPECT_EQ(0u, subspan.size());
1067 auto subspan = span.subspan(0, 0);
1068 EXPECT_EQ(span.data(), subspan.data());
1069 EXPECT_EQ(0u, subspan.size());
1073 auto subspan = span.subspan(1, 0);
1074 EXPECT_EQ(span.data() + 1, subspan.data());
1075 EXPECT_EQ(0u, subspan.size());
1079 auto subspan = span.subspan(2, 0);
1080 EXPECT_EQ(span.data() + 2, subspan.data());
1081 EXPECT_EQ(0u, subspan.size());
1085 auto subspan = span.subspan(0, 1);
1086 EXPECT_EQ(span.data(), subspan.data());
1087 EXPECT_EQ(1u, subspan.size());
1088 EXPECT_EQ(1, subspan[0]);
1092 auto subspan = span.subspan(1, 1);
1093 EXPECT_EQ(span.data() + 1, subspan.data());
1094 EXPECT_EQ(1u, subspan.size());
1095 EXPECT_EQ(2, subspan[0]);
1099 auto subspan = span.subspan(2, 1);
1100 EXPECT_EQ(span.data() + 2, subspan.data());
1101 EXPECT_EQ(1u, subspan.size());
1102 EXPECT_EQ(3, subspan[0]);
1106 auto subspan = span.subspan(0, 2);
1107 EXPECT_EQ(span.data(), subspan.data());
1108 EXPECT_EQ(2u, subspan.size());
1109 EXPECT_EQ(1, subspan[0]);
1110 EXPECT_EQ(2, subspan[1]);
1114 auto subspan = span.subspan(1, 2);
1115 EXPECT_EQ(span.data() + 1, subspan.data());
1116 EXPECT_EQ(2u, subspan.size());
1117 EXPECT_EQ(2, subspan[0]);
1118 EXPECT_EQ(3, subspan[1]);
1122 auto subspan = span.subspan(0, 3);
1123 EXPECT_EQ(span.data(), subspan.data());
1124 EXPECT_EQ(span.size(), subspan.size());
1125 EXPECT_EQ(1, subspan[0]);
1126 EXPECT_EQ(2, subspan[1]);
1127 EXPECT_EQ(3, subspan[2]);
1131 TEST(SpanTest, Size) {
1134 EXPECT_EQ(0u, span.size());
1138 int array[] = {1, 2, 3};
1139 span<int> span(array);
1140 EXPECT_EQ(3u, span.size());
1144 TEST(SpanTest, SizeBytes) {
1147 EXPECT_EQ(0u, span.size_bytes());
1151 int array[] = {1, 2, 3};
1152 span<int> span(array);
1153 EXPECT_EQ(3u * sizeof(int), span.size_bytes());
1157 TEST(SpanTest, Empty) {
1160 EXPECT_TRUE(span.empty());
1164 int array[] = {1, 2, 3};
1165 span<int> span(array);
1166 EXPECT_FALSE(span.empty());
1170 TEST(SpanTest, OperatorAt) {
1171 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1172 constexpr span<const int> span(kArray);
1174 static_assert(&kArray[0] == &span[0],
1175 "span[0] does not refer to the same element as kArray[0]");
1176 static_assert(&kArray[1] == &span[1],
1177 "span[1] does not refer to the same element as kArray[1]");
1178 static_assert(&kArray[2] == &span[2],
1179 "span[2] does not refer to the same element as kArray[2]");
1180 static_assert(&kArray[3] == &span[3],
1181 "span[3] does not refer to the same element as kArray[3]");
1182 static_assert(&kArray[4] == &span[4],
1183 "span[4] does not refer to the same element as kArray[4]");
1186 TEST(SpanTest, Front) {
1187 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1188 constexpr span<const int> span(kArray);
1189 static_assert(&kArray[0] == &span.front(),
1190 "span.front() does not refer to the same element as kArray[0]");
1193 TEST(SpanTest, Back) {
1194 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1195 constexpr span<const int> span(kArray);
1196 static_assert(&kArray[4] == &span.back(),
1197 "span.back() does not refer to the same element as kArray[4]");
1200 // Pigweed: This test uses gMock features not yet supported in Pigweed.
1202 TEST(SpanTest, Iterator) {
1203 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1204 constexpr span<const int> span(kArray);
1206 std::vector<int> results;
1208 results.emplace_back(i);
1209 EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
1213 TEST(SpanTest, ConstexprIterator) {
1214 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1215 constexpr span<const int> span(kArray);
1219 std::begin(kArray), std::end(kArray), span.begin(), span.end()),
1221 static_assert(1 == span.begin()[0], "");
1222 // Pigweed: These tests assume an iterator object, but Pigweed's span uses a
1225 static_assert(1 == *(span.begin() += 0), "");
1226 static_assert(6 == *(span.begin() += 1), "");
1228 static_assert(1 == *((span.begin() + 1) -= 1), "");
1229 static_assert(6 == *((span.begin() + 1) -= 0), "");
1233 TEST(SpanTest, ReverseIterator) {
1234 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1235 constexpr span<const int> span(kArray);
1237 EXPECT_TRUE(std::equal(
1238 std::rbegin(kArray), std::rend(kArray), span.rbegin(), span.rend()));
1239 EXPECT_TRUE(std::equal(std::crbegin(kArray),
1245 // Pigweed: These are tests for make_span, which is not included in Pigweed's
1246 // implementation, since class template deduction is available.
1248 TEST(SpanTest, AsBytes) {
1250 constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1251 span<const uint8_t, sizeof(kArray)> bytes_span =
1252 as_bytes(make_span(kArray));
1253 EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
1254 EXPECT_EQ(sizeof(kArray), bytes_span.size());
1255 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1259 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1260 span<int> mutable_span(vec);
1261 span<const uint8_t> bytes_span = as_bytes(mutable_span);
1262 EXPECT_EQ(reinterpret_cast<const uint8_t*>(vec.data()), bytes_span.data());
1263 EXPECT_EQ(sizeof(int) * vec.size(), bytes_span.size());
1264 EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1268 TEST(SpanTest, AsWritableBytes) {
1269 std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1270 span<int> mutable_span(vec);
1271 span<uint8_t> writable_bytes_span = as_writable_bytes(mutable_span);
1272 EXPECT_EQ(reinterpret_cast<uint8_t*>(vec.data()), writable_bytes_span.data());
1273 EXPECT_EQ(sizeof(int) * vec.size(), writable_bytes_span.size());
1274 EXPECT_EQ(writable_bytes_span.size(), writable_bytes_span.size_bytes());
1276 // Set the first entry of vec to zero while writing through the span.
1277 std::fill(writable_bytes_span.data(),
1278 writable_bytes_span.data() + sizeof(int), 0);
1279 EXPECT_EQ(0, vec[0]);
1282 TEST(SpanTest, MakeSpanFromDataAndSize) {
1283 int* nullint = nullptr;
1284 auto empty_span = make_span(nullint, 0);
1285 EXPECT_TRUE(empty_span.empty());
1286 EXPECT_EQ(nullptr, empty_span.data());
1288 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1289 span<int> expected_span(vector.data(), vector.size());
1290 auto made_span = make_span(vector.data(), vector.size());
1291 EXPECT_EQ(expected_span.data(), made_span.data());
1292 EXPECT_EQ(expected_span.size(), made_span.size());
1293 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1295 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1296 "the type of made_span differs from expected_span!");
1299 TEST(SpanTest, MakeSpanFromPointerPair) {
1300 int* nullint = nullptr;
1301 auto empty_span = make_span(nullint, nullint);
1302 EXPECT_TRUE(empty_span.empty());
1303 EXPECT_EQ(nullptr, empty_span.data());
1305 std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1306 span<int> expected_span(vector.data(), vector.size());
1307 auto made_span = make_span(vector.data(), vector.data() + vector.size());
1308 EXPECT_EQ(expected_span.data(), made_span.data());
1309 EXPECT_EQ(expected_span.size(), made_span.size());
1310 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1312 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1313 "the type of made_span differs from expected_span!");
1316 TEST(SpanTest, MakeSpanFromConstexprArray) {
1317 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1318 constexpr span<const int, 5> expected_span(kArray);
1319 constexpr auto made_span = make_span(kArray);
1320 EXPECT_EQ(expected_span.data(), made_span.data());
1321 EXPECT_EQ(expected_span.size(), made_span.size());
1322 static_assert(decltype(made_span)::extent == 5, "");
1324 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1325 "the type of made_span differs from expected_span!");
1328 TEST(SpanTest, MakeSpanFromStdArray) {
1329 const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
1330 span<const int, 5> expected_span(kArray);
1331 auto made_span = make_span(kArray);
1332 EXPECT_EQ(expected_span.data(), made_span.data());
1333 EXPECT_EQ(expected_span.size(), made_span.size());
1334 static_assert(decltype(made_span)::extent == 5, "");
1336 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1337 "the type of made_span differs from expected_span!");
1340 TEST(SpanTest, MakeSpanFromConstContainer) {
1341 const std::vector<int> vector = {-1, -2, -3, -4, -5};
1342 span<const int> expected_span(vector);
1343 auto made_span = make_span(vector);
1344 EXPECT_EQ(expected_span.data(), made_span.data());
1345 EXPECT_EQ(expected_span.size(), made_span.size());
1346 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1348 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1349 "the type of made_span differs from expected_span!");
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, "");
1360 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1361 "the type of made_span differs from expected_span!");
1364 TEST(SpanTest, MakeSpanFromContainer) {
1365 std::vector<int> vector = {-1, -2, -3, -4, -5};
1366 span<int> expected_span(vector);
1367 auto made_span = make_span(vector);
1368 EXPECT_EQ(expected_span.data(), made_span.data());
1369 EXPECT_EQ(expected_span.size(), made_span.size());
1370 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1372 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1373 "the type of made_span differs from expected_span!");
1376 TEST(SpanTest, MakeStaticSpanFromContainer) {
1377 std::vector<int> vector = {-1, -2, -3, -4, -5};
1378 span<int, 5> expected_span(vector.data(), vector.size());
1379 auto made_span = make_span<5>(vector);
1380 EXPECT_EQ(expected_span.data(), make_span<5>(vector).data());
1381 EXPECT_EQ(expected_span.size(), make_span<5>(vector).size());
1382 static_assert(decltype(make_span<5>(vector))::extent == 5, "");
1384 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1385 "the type of made_span differs from expected_span!");
1388 TEST(SpanTest, MakeStaticSpanFromConstexprContainer) {
1389 constexpr StringPiece str = "Hello, World";
1390 constexpr auto made_span = make_span<12>(str);
1391 static_assert(str.data() == made_span.data(), "Error: data() does not match");
1392 static_assert(str.size() == made_span.size(), "Error: size() does not match");
1393 static_assert(std::is_same<decltype(str)::value_type,
1394 decltype(made_span)::value_type>::value,
1395 "Error: value_type does not match");
1396 static_assert(str.size() == decltype(made_span)::extent,
1397 "Error: extent does not match");
1400 TEST(SpanTest, MakeSpanFromRValueContainer) {
1401 std::vector<int> vector = {-1, -2, -3, -4, -5};
1402 span<const int> expected_span(vector);
1403 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1404 // std::move(foo), make_span does not actually take ownership of the passed in
1405 // container. Writing it this way makes it more obvious that we simply care
1406 // about the right behavour when passing rvalues.
1407 auto made_span = make_span(static_cast<std::vector<int>&&>(vector));
1408 EXPECT_EQ(expected_span.data(), made_span.data());
1409 EXPECT_EQ(expected_span.size(), made_span.size());
1410 static_assert(decltype(made_span)::extent == dynamic_extent, "");
1412 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1413 "the type of made_span differs from expected_span!");
1416 TEST(SpanTest, MakeStaticSpanFromRValueContainer) {
1417 std::vector<int> vector = {-1, -2, -3, -4, -5};
1418 span<const int, 5> expected_span(vector.data(), vector.size());
1419 // Note: While static_cast<T&&>(foo) is effectively just a fancy spelling of
1420 // std::move(foo), make_span does not actually take ownership of the passed in
1421 // container. Writing it this way makes it more obvious that we simply care
1422 // about the right behavour when passing rvalues.
1423 auto made_span = make_span<5>(static_cast<std::vector<int>&&>(vector));
1424 EXPECT_EQ(expected_span.data(), made_span.data());
1425 EXPECT_EQ(expected_span.size(), made_span.size());
1426 static_assert(decltype(made_span)::extent == 5, "");
1428 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1429 "the type of made_span differs from expected_span!");
1432 TEST(SpanTest, MakeSpanFromDynamicSpan) {
1433 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1434 constexpr span<const int> expected_span(kArray);
1435 constexpr auto made_span = make_span(expected_span);
1436 static_assert(std::is_same<decltype(expected_span)::element_type,
1437 decltype(made_span)::element_type>::value,
1438 "make_span(span) should have the same element_type as span");
1440 static_assert(expected_span.data() == made_span.data(),
1441 "make_span(span) should have the same data() as span");
1443 static_assert(expected_span.size() == made_span.size(),
1444 "make_span(span) should have the same size() as span");
1446 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1447 "make_span(span) should have the same extent as span");
1450 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1451 "the type of made_span differs from expected_span!");
1454 TEST(SpanTest, MakeSpanFromStaticSpan) {
1455 static constexpr int kArray[] = {1, 2, 3, 4, 5};
1456 constexpr span<const int, 5> expected_span(kArray);
1457 constexpr auto made_span = make_span(expected_span);
1458 static_assert(std::is_same<decltype(expected_span)::element_type,
1459 decltype(made_span)::element_type>::value,
1460 "make_span(span) should have the same element_type as span");
1462 static_assert(expected_span.data() == made_span.data(),
1463 "make_span(span) should have the same data() as span");
1465 static_assert(expected_span.size() == made_span.size(),
1466 "make_span(span) should have the same size() as span");
1468 static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1469 "make_span(span) should have the same extent as span");
1472 std::is_same<decltype(expected_span), decltype(made_span)>::value,
1473 "the type of made_span differs from expected_span!");
1477 TEST(SpanTest, EnsureConstexprGoodness) {
1478 static constexpr int kArray[] = {5, 4, 3, 2, 1};
1479 constexpr span<const int> constexpr_span(kArray);
1480 const size_t size = 2;
1482 const size_t start = 1;
1483 constexpr span<const int> subspan =
1484 constexpr_span.subspan(start, start + size);
1485 for (size_t i = 0; i < subspan.size(); ++i)
1486 EXPECT_EQ(kArray[start + i], subspan[i]);
1488 constexpr span<const int> firsts = constexpr_span.first(size);
1489 for (size_t i = 0; i < firsts.size(); ++i)
1490 EXPECT_EQ(kArray[i], firsts[i]);
1492 constexpr span<const int> lasts = constexpr_span.last(size);
1493 for (size_t i = 0; i < lasts.size(); ++i) {
1494 const size_t j = (std::size(kArray) - size) + i;
1495 EXPECT_EQ(kArray[j], lasts[i]);
1498 constexpr int item = constexpr_span[size];
1499 EXPECT_EQ(kArray[size], item);
1504 // Pigweed: Death tests are not yet supported.
1505 TEST(SpanTest, OutOfBoundsDeath) {
1506 constexpr span<int, 0> kEmptySpan;
1507 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan[0], "");
1508 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.first(1), "");
1509 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.last(1), "");
1510 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1), "");
1512 constexpr span<int> kEmptyDynamicSpan;
1513 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan[0], "");
1514 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.front(), "");
1515 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.first(1), "");
1516 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.last(1), "");
1517 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.back(), "");
1518 ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.subspan(1), "");
1520 static constexpr int kArray[] = {0, 1, 2};
1521 constexpr span<const int> kNonEmptyDynamicSpan(kArray);
1522 EXPECT_EQ(3U, kNonEmptyDynamicSpan.size());
1523 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan[4], "");
1524 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(10), "");
1525 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(1, 7), "");
1528 // Pigweed: These tests use CheckedContiguousConstIterator, which isn't used in
1529 // Pigweed's version.
1530 TEST(SpanTest, IteratorIsRangeMoveSafe) {
1531 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1532 const size_t kNumElements = 5;
1533 constexpr span<const int> span(kArray);
1535 static constexpr int kOverlappingStartIndexes[] = {-4, 0, 3, 4};
1536 static constexpr int kNonOverlappingStartIndexes[] = {-7, -5, 5, 7};
1538 // Overlapping ranges.
1539 for (const int dest_start_index : kOverlappingStartIndexes) {
1540 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1541 span.begin(), span.end(),
1542 CheckedContiguousIterator<const int>(
1543 span.data() + dest_start_index,
1544 span.data() + dest_start_index + kNumElements)));
1545 EXPECT_FALSE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1546 std::cbegin(span), std::cend(span),
1547 CheckedContiguousConstIterator<const int>(
1548 span.data() + dest_start_index,
1549 span.data() + dest_start_index + kNumElements)));
1552 // Non-overlapping ranges.
1553 for (const int dest_start_index : kNonOverlappingStartIndexes) {
1554 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1555 span.begin(), span.end(),
1556 CheckedContiguousIterator<const int>(
1557 span.data() + dest_start_index,
1558 span.data() + dest_start_index + kNumElements)));
1559 EXPECT_TRUE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1560 std::cbegin(span), std::cend(span),
1561 CheckedContiguousConstIterator<const int>(
1562 span.data() + dest_start_index,
1563 span.data() + dest_start_index + kNumElements)));
1566 // IsRangeMoveSafe is true if the length to be moved is 0.
1567 EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1568 span.begin(), span.begin(),
1569 CheckedContiguousIterator<const int>(span.data(), span.data())));
1570 EXPECT_TRUE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1571 std::cbegin(span), std::cbegin(span),
1572 CheckedContiguousConstIterator<const int>(span.data(), span.data())));
1574 // IsRangeMoveSafe is false if end < begin.
1575 EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
1576 span.end(), span.begin(),
1577 CheckedContiguousIterator<const int>(span.data(), span.data())));
1578 EXPECT_FALSE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
1579 std::cend(span), std::cbegin(span),
1580 CheckedContiguousConstIterator<const int>(span.data(), span.data())));
1583 // Pigweed: gMock matchers are not yet supported.
1584 TEST(SpanTest, Sort) {
1585 int array[] = {5, 4, 3, 2, 1};
1587 span<int> dynamic_span = array;
1588 std::sort(dynamic_span.begin(), dynamic_span.end());
1589 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1590 std::sort(dynamic_span.rbegin(), dynamic_span.rend());
1591 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1593 span<int, 5> static_span = array;
1594 std::sort(static_span.rbegin(), static_span.rend(), std::greater<>());
1595 EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
1596 std::sort(static_span.begin(), static_span.end(), std::greater<>());
1597 EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
1601 TEST(SpanTest, SpanExtentConversions) {
1602 // Statically checks that various conversions between spans of dynamic and
1603 // static extent are possible or not.
1605 !std::is_constructible<span<int, 0>, span<int>>::value,
1606 "Error: static span should not be constructible from dynamic span");
1608 static_assert(!std::is_constructible<span<int, 2>, span<int, 1>>::value,
1609 "Error: static span should not be constructible from static "
1610 "span with different extent");
1612 static_assert(std::is_convertible<span<int, 0>, span<int>>::value,
1613 "Error: static span should be convertible to dynamic span");
1615 static_assert(std::is_convertible<span<int>, span<int>>::value,
1616 "Error: dynamic span should be convertible to dynamic span");
1618 static_assert(std::is_convertible<span<int, 2>, span<int, 2>>::value,
1619 "Error: static span should be convertible to static span");
1622 TEST(SpanTest, IteratorConversions) {
1623 static_assert(std::is_convertible<span<int>::iterator,
1624 span<const int>::iterator>::value,
1625 "Error: iterator should be convertible to const iterator");
1627 static_assert(!std::is_convertible<span<const int>::iterator,
1628 span<int>::iterator>::value,
1629 "Error: const iterator should not be convertible to iterator");