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