Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_span / span_test.cc
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 #include <algorithm>
25 #include <cstdint>
26 #include <memory>
27 #include <span>
28 #include <string>
29 #include <type_traits>
30 #include <vector>
31
32 #include "gtest/gtest.h"
33
34 // Pigweed: gMock matchers are not yet supported.
35 #if 0
36 using ::testing::ElementsAre;
37 using ::testing::Eq;
38 using ::testing::Pointwise;
39 #endif  // 0
40
41 namespace std {
42
43 namespace {
44
45 // constexpr implementation of std::equal's 4 argument overload.
46 template <class InputIterator1, class InputIterator2>
47 constexpr bool constexpr_equal(InputIterator1 first1,
48                                InputIterator1 last1,
49                                InputIterator2 first2,
50                                InputIterator2 last2) {
51   for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
52     if (*first1 != *first2)
53       return false;
54   }
55
56   return first1 == last1 && first2 == last2;
57 }
58
59 }  // namespace
60
61 TEST(SpanTest, DeductionGuides_MutableArray) {
62   char array[] = {'a', 'b', 'c', 'd', '\0'};
63
64   auto the_span = span(array);
65   static_assert(the_span.extent == 5u);
66   static_assert(the_span.size() == 5u);
67
68   the_span[0] = '!';
69   EXPECT_STREQ(the_span.data(), "!bcd");
70 }
71
72 TEST(SpanTest, DeductionGuides_ConstArray) {
73   static constexpr char array[] = {'a', 'b', 'c', 'd', '\0'};
74
75   constexpr auto the_span = span(array);
76   static_assert(the_span.extent == 5u);
77   static_assert(the_span.size() == 5u);
78
79   EXPECT_STREQ(the_span.data(), "abcd");
80 }
81
82 TEST(SpanTest, DeductionGuides_MutableStdArray) {
83   std::array<char, 5> array{'a', 'b', 'c', 'd'};
84
85   auto the_span = span(array);
86   static_assert(the_span.extent == 5u);
87   static_assert(the_span.size() == 5u);
88
89   the_span[0] = '?';
90   EXPECT_STREQ(the_span.data(), "?bcd");
91 }
92
93 TEST(SpanTest, DeductionGuides_ConstStdArray) {
94   static constexpr std::array<char, 5> array{'a', 'b', 'c', 'd'};
95
96   constexpr auto the_span = span(array);
97   static_assert(the_span.extent == 5u);
98   static_assert(the_span.size() == 5u);
99
100   EXPECT_STREQ(the_span.data(), "abcd");
101 }
102
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);
107
108   EXPECT_STREQ("Hello", the_span.data());
109   EXPECT_EQ(5u, the_span.size());
110 }
111
112 TEST(SpanTest, DeductionGuides_MutableContainerWithMutableElements) {
113   std::string string("Hello");
114   auto the_span = span(string);
115   static_assert(the_span.extent == dynamic_extent);
116
117   EXPECT_EQ(5u, the_span.size());
118   the_span[1] = 'a';
119   EXPECT_STREQ(the_span.data(), string.data());
120   EXPECT_STREQ("Hallo", the_span.data());
121 }
122
123 class MutableStringView {
124  public:
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>;
135
136   MutableStringView(char* str) : data_(str, std::strlen(str)) {}
137
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(); }
143
144  private:
145   span<char> data_;
146 };
147
148 TEST(SpanTest, DeductionGuides_ConstContainerWithMutableElements) {
149   char data[] = "54321";
150   MutableStringView view(data);
151
152   auto the_span = span(view);
153   static_assert(the_span.extent == dynamic_extent);
154
155   EXPECT_EQ(5u, the_span.size());
156   view[2] = '?';
157   EXPECT_STREQ("54?21", the_span.data());
158   EXPECT_STREQ("54?21", data);
159 }
160
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);
165
166   EXPECT_EQ(5u, the_span.size());
167   EXPECT_STREQ("Hello", the_span.data());
168 }
169
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);
174
175   EXPECT_EQ(5u, the_span.size());
176   EXPECT_STREQ("Hello", the_span.data());
177 }
178
179 TEST(SpanTest, DeductionGuides_FromTemporary_ContainerWithConstElements) {
180   auto the_span = span(std::string_view("Hello"));
181   static_assert(the_span.extent == dynamic_extent);
182
183   EXPECT_EQ(5u, the_span.size());
184   EXPECT_STREQ("Hello", the_span.data());
185 }
186
187 TEST(SpanTest, DeductionGuides_FromReference) {
188   std::array<int, 5> array{1, 3, 5, 7, 9};
189   std::array<int, 5>& array_ref = array;
190
191   auto the_span = span(array_ref);
192   static_assert(the_span.extent == 5);
193
194   for (unsigned i = 0; i < array.size(); ++i) {
195     ASSERT_EQ(array[i], the_span[i]);
196   }
197 }
198
199 TEST(SpanTest, DeductionGuides_FromConstReference) {
200   std::string_view string = "yo!";
201   const std::string_view& string_ref = string;
202
203   auto the_span = span(string_ref);
204   static_assert(the_span.extent == dynamic_extent);
205
206   EXPECT_EQ(string, the_span.data());
207 }
208
209 TEST(SpanTest, DefaultConstructor) {
210   span<int> dynamic_span;
211   EXPECT_EQ(nullptr, dynamic_span.data());
212   EXPECT_EQ(0u, dynamic_span.size());
213
214   constexpr span<int, 0> static_span;
215   static_assert(nullptr == static_span.data(), "");
216   static_assert(static_span.empty(), "");
217 }
218
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());
223
224   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
225
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());
229
230   for (size_t i = 0; i < dynamic_span.size(); ++i)
231     EXPECT_EQ(vector[i], dynamic_span[i]);
232
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());
236
237   for (size_t i = 0; i < static_span.size(); ++i)
238     EXPECT_EQ(vector[i], static_span[i]);
239 }
240
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());
245
246   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
247
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());
251
252   for (size_t i = 0; i < dynamic_span.size(); ++i)
253     EXPECT_EQ(vector[i], dynamic_span[i]);
254
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());
258
259   for (size_t i = 0; i < static_span.size(); ++i)
260     EXPECT_EQ(vector[i], static_span[i]);
261 }
262
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:
267   //
268   // T obj = std::declval<From>();
269   //
270   // In particular we are checking whether From is implicitly convertible to To,
271   // which also implies that To is explicitly constructible from From.
272   static_assert(
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.");
276   static_assert(
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.");
280   static_assert(
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.");
284   static_assert(
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.");
288   static_assert(
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.");
292   static_assert(
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.");
296   static_assert(
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.");
300   static_assert(
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.");
304   static_assert(
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.");
309   static_assert(
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.");
314 }
315
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:
319   //
320   // T obj(std::declval<Args>()...);
321   //
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
324   // as well.
325   static_assert(
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>");
329
330   static_assert(
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>");
334
335   static_assert(
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>");
339
340   static_assert(
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");
344
345   static_assert(
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");
349
350   static_assert(
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>");
354 }
355
356 TEST(SpanTest, ConstructFromConstexprArray) {
357   static constexpr int kArray[] = {5, 4, 3, 2, 1};
358
359   constexpr span<const int> dynamic_span(kArray);
360   static_assert(kArray == dynamic_span.data(), "");
361   static_assert(std::size(kArray) == dynamic_span.size(), "");
362
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], "");
368
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(), "");
372
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], "");
378 }
379
380 TEST(SpanTest, ConstructFromArray) {
381   int array[] = {5, 4, 3, 2, 1};
382
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]);
388
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]);
394
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]);
400 }
401
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}};
406
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]);
412
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]);
418
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]);
424 }
425
426 TEST(SpanTest, ConstructFromInitializerList) {
427   std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
428
429   span<const int> const_span(il);
430   EXPECT_EQ(il.begin(), const_span.data());
431   EXPECT_EQ(il.size(), const_span.size());
432
433   for (size_t i = 0; i < const_span.size(); ++i)
434     EXPECT_EQ(il.begin()[i], const_span[i]);
435
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());
439
440   for (size_t i = 0; i < static_span.size(); ++i)
441     EXPECT_EQ(il.begin()[i], static_span[i]);
442 }
443
444 TEST(SpanTest, ConstructFromStdString) {
445   std::string str = "foobar";
446
447   span<const char> const_span(str);
448   EXPECT_EQ(str.data(), const_span.data());
449   EXPECT_EQ(str.size(), const_span.size());
450
451   for (size_t i = 0; i < const_span.size(); ++i)
452     EXPECT_EQ(str[i], const_span[i]);
453
454   span<char> dynamic_span(str);
455   EXPECT_EQ(str.data(), dynamic_span.data());
456   EXPECT_EQ(str.size(), dynamic_span.size());
457
458   for (size_t i = 0; i < dynamic_span.size(); ++i)
459     EXPECT_EQ(str[i], dynamic_span[i]);
460
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());
464
465   for (size_t i = 0; i < static_span.size(); ++i)
466     EXPECT_EQ(str[i], static_span[i]);
467 }
468
469 TEST(SpanTest, ConstructFromConstContainer) {
470   const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
471
472   span<const int> const_span(vector);
473   EXPECT_EQ(vector.data(), const_span.data());
474   EXPECT_EQ(vector.size(), const_span.size());
475
476   for (size_t i = 0; i < const_span.size(); ++i)
477     EXPECT_EQ(vector[i], const_span[i]);
478
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());
482
483   for (size_t i = 0; i < static_span.size(); ++i)
484     EXPECT_EQ(vector[i], static_span[i]);
485 }
486
487 TEST(SpanTest, ConstructFromContainer) {
488   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
489
490   span<const int> const_span(vector);
491   EXPECT_EQ(vector.data(), const_span.data());
492   EXPECT_EQ(vector.size(), const_span.size());
493
494   for (size_t i = 0; i < const_span.size(); ++i)
495     EXPECT_EQ(vector[i], const_span[i]);
496
497   span<int> dynamic_span(vector);
498   EXPECT_EQ(vector.data(), dynamic_span.data());
499   EXPECT_EQ(vector.size(), dynamic_span.size());
500
501   for (size_t i = 0; i < dynamic_span.size(); ++i)
502     EXPECT_EQ(vector[i], dynamic_span[i]);
503
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());
507
508   for (size_t i = 0; i < static_span.size(); ++i)
509     EXPECT_EQ(vector[i], static_span[i]);
510 }
511
512 #if 0
513
514 // Pigweed: gMock matchers are not yet supported.
515 TEST(SpanTest, ConvertNonConstIntegralToConst) {
516   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
517
518   span<int> int_span(vector.data(), vector.size());
519   span<const int> const_span(int_span);
520   EXPECT_EQ(int_span.size(), const_span.size());
521
522   EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
523
524   span<int, 6> static_int_span(vector.data(), vector.size());
525   span<const int, 6> static_const_span(static_int_span);
526   EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
527 }
528
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()};
535
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.
542   //
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
546
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));
552 }
553
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};
557
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());
562
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());
567 }
568
569 #endif  // 0
570
571 TEST(SpanTest, TemplatedFirst) {
572   static constexpr int array[] = {1, 2, 3};
573   constexpr span<const int, 3> span(array);
574
575   {
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, "");
580   }
581
582   {
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], "");
588   }
589
590   {
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], "");
597   }
598
599   {
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], "");
607   }
608 }
609
610 TEST(SpanTest, TemplatedLast) {
611   static constexpr int array[] = {1, 2, 3};
612   constexpr span<const int, 3> span(array);
613
614   {
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, "");
619   }
620
621   {
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], "");
627   }
628
629   {
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], "");
636   }
637
638   {
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], "");
646   }
647 }
648
649 TEST(SpanTest, TemplatedSubspan) {
650   static constexpr int array[] = {1, 2, 3};
651   constexpr span<const int, 3> span(array);
652
653   {
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], "");
661   }
662
663   {
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], "");
670   }
671
672   {
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], "");
678   }
679
680   {
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, "");
685   }
686
687   {
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, "");
692   }
693
694   {
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, "");
699   }
700
701   {
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, "");
706   }
707
708   {
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], "");
714   }
715
716   {
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], "");
722   }
723
724   {
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], "");
730   }
731
732   {
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], "");
739   }
740
741   {
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], "");
748   }
749
750   {
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], "");
758   }
759 }
760
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]);
766
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]);
770 }
771
772 TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
773   int array[] = {1, 2, 3};
774   span<const int> span(array);
775
776   {
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, "");
781   }
782
783   {
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]);
789   }
790
791   {
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]);
798   }
799
800   {
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]);
808   }
809 }
810
811 TEST(SpanTest, TemplatedLastOnDynamicSpan) {
812   int array[] = {1, 2, 3};
813   span<int> span(array);
814
815   {
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, "");
820   }
821
822   {
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]);
828   }
829
830   {
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]);
837   }
838
839   {
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]);
847   }
848 }
849
850 TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
851   int array[] = {1, 2, 3};
852   span<int, 3> span(array);
853
854   {
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]);
862   }
863
864   {
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]);
871   }
872
873   {
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]);
879   }
880
881   {
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, "");
886   }
887
888   {
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, "");
893   }
894
895   {
896     auto subspan = span.subspan<1, 0>();
897     EXPECT_EQ(span.data() + 1, subspan.data());
898     EXPECT_EQ(0u, subspan.size());
899     static_assert(0u == decltype(subspan)::extent, "");
900   }
901
902   {
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, "");
907   }
908
909   {
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]);
915   }
916
917   {
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]);
923   }
924
925   {
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]);
931   }
932
933   {
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]);
940   }
941
942   {
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]);
949   }
950
951   {
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]);
959   }
960 }
961
962 TEST(SpanTest, First) {
963   int array[] = {1, 2, 3};
964   span<int> span(array);
965
966   {
967     auto subspan = span.first(0);
968     EXPECT_EQ(span.data(), subspan.data());
969     EXPECT_EQ(0u, subspan.size());
970   }
971
972   {
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]);
977   }
978
979   {
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]);
985   }
986
987   {
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]);
994   }
995 }
996
997 TEST(SpanTest, Last) {
998   int array[] = {1, 2, 3};
999   span<int> span(array);
1000
1001   {
1002     auto subspan = span.last(0);
1003     EXPECT_EQ(span.data() + 3, subspan.data());
1004     EXPECT_EQ(0u, subspan.size());
1005   }
1006
1007   {
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]);
1012   }
1013
1014   {
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]);
1020   }
1021
1022   {
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]);
1029   }
1030 }
1031
1032 TEST(SpanTest, Subspan) {
1033   int array[] = {1, 2, 3};
1034   span<int> span(array);
1035
1036   {
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]);
1043   }
1044
1045   {
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]);
1051   }
1052
1053   {
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]);
1058   }
1059
1060   {
1061     auto subspan = span.subspan(3);
1062     EXPECT_EQ(span.data() + 3, subspan.data());
1063     EXPECT_EQ(0u, subspan.size());
1064   }
1065
1066   {
1067     auto subspan = span.subspan(0, 0);
1068     EXPECT_EQ(span.data(), subspan.data());
1069     EXPECT_EQ(0u, subspan.size());
1070   }
1071
1072   {
1073     auto subspan = span.subspan(1, 0);
1074     EXPECT_EQ(span.data() + 1, subspan.data());
1075     EXPECT_EQ(0u, subspan.size());
1076   }
1077
1078   {
1079     auto subspan = span.subspan(2, 0);
1080     EXPECT_EQ(span.data() + 2, subspan.data());
1081     EXPECT_EQ(0u, subspan.size());
1082   }
1083
1084   {
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]);
1089   }
1090
1091   {
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]);
1096   }
1097
1098   {
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]);
1103   }
1104
1105   {
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]);
1111   }
1112
1113   {
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]);
1119   }
1120
1121   {
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]);
1128   }
1129 }
1130
1131 TEST(SpanTest, Size) {
1132   {
1133     span<int> span;
1134     EXPECT_EQ(0u, span.size());
1135   }
1136
1137   {
1138     int array[] = {1, 2, 3};
1139     span<int> span(array);
1140     EXPECT_EQ(3u, span.size());
1141   }
1142 }
1143
1144 TEST(SpanTest, SizeBytes) {
1145   {
1146     span<int> span;
1147     EXPECT_EQ(0u, span.size_bytes());
1148   }
1149
1150   {
1151     int array[] = {1, 2, 3};
1152     span<int> span(array);
1153     EXPECT_EQ(3u * sizeof(int), span.size_bytes());
1154   }
1155 }
1156
1157 TEST(SpanTest, Empty) {
1158   {
1159     span<int> span;
1160     EXPECT_TRUE(span.empty());
1161   }
1162
1163   {
1164     int array[] = {1, 2, 3};
1165     span<int> span(array);
1166     EXPECT_FALSE(span.empty());
1167   }
1168 }
1169
1170 TEST(SpanTest, OperatorAt) {
1171   static constexpr int kArray[] = {1, 6, 1, 8, 0};
1172   constexpr span<const int> span(kArray);
1173
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]");
1184 }
1185
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]");
1191 }
1192
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]");
1198 }
1199
1200 // Pigweed: This test uses gMock features not yet supported in Pigweed.
1201 #if 0
1202 TEST(SpanTest, Iterator) {
1203   static constexpr int kArray[] = {1, 6, 1, 8, 0};
1204   constexpr span<const int> span(kArray);
1205
1206   std::vector<int> results;
1207   for (int i : span)
1208     results.emplace_back(i);
1209   EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
1210 }
1211 #endif  // 0
1212
1213 TEST(SpanTest, ConstexprIterator) {
1214   static constexpr int kArray[] = {1, 6, 1, 8, 0};
1215   constexpr span<const int> span(kArray);
1216
1217   static_assert(
1218       constexpr_equal(
1219           std::begin(kArray), std::end(kArray), span.begin(), span.end()),
1220       "");
1221   static_assert(1 == span.begin()[0], "");
1222   // Pigweed: These tests assume an iterator object, but Pigweed's span uses a
1223   //          simple pointer.
1224 #if 0
1225   static_assert(1 == *(span.begin() += 0), "");
1226   static_assert(6 == *(span.begin() += 1), "");
1227
1228   static_assert(1 == *((span.begin() + 1) -= 1), "");
1229   static_assert(6 == *((span.begin() + 1) -= 0), "");
1230 #endif  // 0
1231 }
1232
1233 TEST(SpanTest, ReverseIterator) {
1234   static constexpr int kArray[] = {1, 6, 1, 8, 0};
1235   constexpr span<const int> span(kArray);
1236
1237   EXPECT_TRUE(std::equal(
1238       std::rbegin(kArray), std::rend(kArray), span.rbegin(), span.rend()));
1239   EXPECT_TRUE(std::equal(std::crbegin(kArray),
1240                          std::crend(kArray),
1241                          std::crbegin(span),
1242                          std::crend(span)));
1243 }
1244
1245 // Pigweed: These are tests for make_span, which is not included in Pigweed's
1246 //          implementation, since class template deduction is available.
1247 #if 0
1248 TEST(SpanTest, AsBytes) {
1249   {
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());
1256   }
1257
1258   {
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());
1265   }
1266 }
1267
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());
1275
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]);
1280 }
1281
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());
1287
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, "");
1294   static_assert(
1295       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1296       "the type of made_span differs from expected_span!");
1297 }
1298
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());
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.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, 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, "");
1323   static_assert(
1324       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1325       "the type of made_span differs from expected_span!");
1326 }
1327
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, "");
1335   static_assert(
1336       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1337       "the type of made_span differs from expected_span!");
1338 }
1339
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, "");
1347   static_assert(
1348       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1349       "the type of made_span differs from expected_span!");
1350 }
1351
1352 TEST(SpanTest, MakeStaticSpanFromConstContainer) {
1353   const std::vector<int> vector = {-1, -2, -3, -4, -5};
1354   span<const int, 5> expected_span(vector.data(), vector.size());
1355   auto made_span = make_span<5>(vector);
1356   EXPECT_EQ(expected_span.data(), made_span.data());
1357   EXPECT_EQ(expected_span.size(), made_span.size());
1358   static_assert(decltype(made_span)::extent == 5, "");
1359   static_assert(
1360       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1361       "the type of made_span differs from expected_span!");
1362 }
1363
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, "");
1371   static_assert(
1372       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1373       "the type of made_span differs from expected_span!");
1374 }
1375
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, "");
1383   static_assert(
1384       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1385       "the type of made_span differs from expected_span!");
1386 }
1387
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");
1398 }
1399
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, "");
1411   static_assert(
1412       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1413       "the type of made_span differs from expected_span!");
1414 }
1415
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, "");
1427   static_assert(
1428       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1429       "the type of made_span differs from expected_span!");
1430 }
1431
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");
1439
1440   static_assert(expected_span.data() == made_span.data(),
1441                 "make_span(span) should have the same data() as span");
1442
1443   static_assert(expected_span.size() == made_span.size(),
1444                 "make_span(span) should have the same size() as span");
1445
1446   static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1447                 "make_span(span) should have the same extent as span");
1448
1449   static_assert(
1450       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1451       "the type of made_span differs from expected_span!");
1452 }
1453
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");
1461
1462   static_assert(expected_span.data() == made_span.data(),
1463                 "make_span(span) should have the same data() as span");
1464
1465   static_assert(expected_span.size() == made_span.size(),
1466                 "make_span(span) should have the same size() as span");
1467
1468   static_assert(decltype(made_span)::extent == decltype(expected_span)::extent,
1469                 "make_span(span) should have the same extent as span");
1470
1471   static_assert(
1472       std::is_same<decltype(expected_span), decltype(made_span)>::value,
1473       "the type of made_span differs from expected_span!");
1474 }
1475 #endif  // 0
1476
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;
1481
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]);
1487
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]);
1491
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]);
1496   }
1497
1498   constexpr int item = constexpr_span[size];
1499   EXPECT_EQ(kArray[size], item);
1500 }
1501
1502 #if 0
1503
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), "");
1511
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), "");
1519
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), "");
1526 }
1527
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);
1534
1535   static constexpr int kOverlappingStartIndexes[] = {-4, 0, 3, 4};
1536   static constexpr int kNonOverlappingStartIndexes[] = {-7, -5, 5, 7};
1537
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)));
1550   }
1551
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)));
1564   }
1565
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())));
1573
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())));
1581 }
1582
1583 // Pigweed: gMock matchers are not yet supported.
1584 TEST(SpanTest, Sort) {
1585   int array[] = {5, 4, 3, 2, 1};
1586
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));
1592
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));
1598 }
1599 #endif  // 0
1600
1601 TEST(SpanTest, SpanExtentConversions) {
1602   // Statically checks that various conversions between spans of dynamic and
1603   // static extent are possible or not.
1604   static_assert(
1605       !std::is_constructible<span<int, 0>, span<int>>::value,
1606       "Error: static span should not be constructible from dynamic span");
1607
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");
1611
1612   static_assert(std::is_convertible<span<int, 0>, span<int>>::value,
1613                 "Error: static span should be convertible to dynamic span");
1614
1615   static_assert(std::is_convertible<span<int>, span<int>>::value,
1616                 "Error: dynamic span should be convertible to dynamic span");
1617
1618   static_assert(std::is_convertible<span<int, 2>, span<int, 2>>::value,
1619                 "Error: static span should be convertible to static span");
1620 }
1621
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");
1626
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");
1630 }
1631
1632 }  // namespace std