1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/containers/span.h"
6 
7 #include <stdint.h>
8 
9 #include <algorithm>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/macros.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 using ::testing::ElementsAre;
19 using ::testing::Eq;
20 using ::testing::Pointwise;
21 
22 namespace base {
23 
TEST(SpanTest,DefaultConstructor)24 TEST(SpanTest, DefaultConstructor) {
25   span<int> dynamic_span;
26   EXPECT_EQ(nullptr, dynamic_span.data());
27   EXPECT_EQ(0u, dynamic_span.size());
28 
29   constexpr span<int, 0> static_span;
30   static_assert(nullptr == static_span.data(), "");
31   static_assert(0u == static_span.size(), "");
32 }
33 
TEST(SpanTest,ConstructFromDataAndSize)34 TEST(SpanTest, ConstructFromDataAndSize) {
35   constexpr span<int> empty_span(nullptr, 0);
36   EXPECT_TRUE(empty_span.empty());
37   EXPECT_EQ(nullptr, empty_span.data());
38 
39   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
40 
41   span<int> dynamic_span(vector.data(), vector.size());
42   EXPECT_EQ(vector.data(), dynamic_span.data());
43   EXPECT_EQ(vector.size(), dynamic_span.size());
44 
45   for (size_t i = 0; i < dynamic_span.size(); ++i)
46     EXPECT_EQ(vector[i], dynamic_span[i]);
47 
48   span<int, 6> static_span(vector.data(), vector.size());
49   EXPECT_EQ(vector.data(), static_span.data());
50   EXPECT_EQ(vector.size(), static_span.size());
51 
52   for (size_t i = 0; i < static_span.size(); ++i)
53     EXPECT_EQ(vector[i], static_span[i]);
54 }
55 
TEST(SpanTest,ConstructFromPointerPair)56 TEST(SpanTest, ConstructFromPointerPair) {
57   constexpr span<int> empty_span(nullptr, nullptr);
58   EXPECT_TRUE(empty_span.empty());
59   EXPECT_EQ(nullptr, empty_span.data());
60 
61   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
62 
63   span<int> dynamic_span(vector.data(), vector.data() + vector.size() / 2);
64   EXPECT_EQ(vector.data(), dynamic_span.data());
65   EXPECT_EQ(vector.size() / 2, dynamic_span.size());
66 
67   for (size_t i = 0; i < dynamic_span.size(); ++i)
68     EXPECT_EQ(vector[i], dynamic_span[i]);
69 
70   span<int, 3> static_span(vector.data(), vector.data() + vector.size() / 2);
71   EXPECT_EQ(vector.data(), static_span.data());
72   EXPECT_EQ(vector.size() / 2, static_span.size());
73 
74   for (size_t i = 0; i < static_span.size(); ++i)
75     EXPECT_EQ(vector[i], static_span[i]);
76 }
77 
TEST(SpanTest,ConstructFromConstexprArray)78 TEST(SpanTest, ConstructFromConstexprArray) {
79   static constexpr int kArray[] = {5, 4, 3, 2, 1};
80 
81   constexpr span<const int> dynamic_span(kArray);
82   static_assert(kArray == dynamic_span.data(), "");
83   static_assert(base::size(kArray) == dynamic_span.size(), "");
84 
85   static_assert(kArray[0] == dynamic_span[0], "");
86   static_assert(kArray[1] == dynamic_span[1], "");
87   static_assert(kArray[2] == dynamic_span[2], "");
88   static_assert(kArray[3] == dynamic_span[3], "");
89   static_assert(kArray[4] == dynamic_span[4], "");
90 
91   constexpr span<const int, base::size(kArray)> static_span(kArray);
92   static_assert(kArray == static_span.data(), "");
93   static_assert(base::size(kArray) == static_span.size(), "");
94 
95   static_assert(kArray[0] == static_span[0], "");
96   static_assert(kArray[1] == static_span[1], "");
97   static_assert(kArray[2] == static_span[2], "");
98   static_assert(kArray[3] == static_span[3], "");
99   static_assert(kArray[4] == static_span[4], "");
100 }
101 
TEST(SpanTest,ConstructFromArray)102 TEST(SpanTest, ConstructFromArray) {
103   int array[] = {5, 4, 3, 2, 1};
104 
105   span<const int> const_span(array);
106   EXPECT_EQ(array, const_span.data());
107   EXPECT_EQ(arraysize(array), const_span.size());
108   for (size_t i = 0; i < const_span.size(); ++i)
109     EXPECT_EQ(array[i], const_span[i]);
110 
111   span<int> dynamic_span(array);
112   EXPECT_EQ(array, dynamic_span.data());
113   EXPECT_EQ(base::size(array), dynamic_span.size());
114   for (size_t i = 0; i < dynamic_span.size(); ++i)
115     EXPECT_EQ(array[i], dynamic_span[i]);
116 
117   span<int, base::size(array)> static_span(array);
118   EXPECT_EQ(array, static_span.data());
119   EXPECT_EQ(base::size(array), static_span.size());
120   for (size_t i = 0; i < static_span.size(); ++i)
121     EXPECT_EQ(array[i], static_span[i]);
122 }
123 
TEST(SpanTest,ConstructFromStdArray)124 TEST(SpanTest, ConstructFromStdArray) {
125   // Note: Constructing a constexpr span from a constexpr std::array does not
126   // work prior to C++17 due to non-constexpr std::array::data.
127   std::array<int, 5> array = {{5, 4, 3, 2, 1}};
128 
129   span<const int> const_span(array);
130   EXPECT_EQ(array.data(), const_span.data());
131   EXPECT_EQ(array.size(), const_span.size());
132   for (size_t i = 0; i < const_span.size(); ++i)
133     EXPECT_EQ(array[i], const_span[i]);
134 
135   span<int> dynamic_span(array);
136   EXPECT_EQ(array.data(), dynamic_span.data());
137   EXPECT_EQ(array.size(), dynamic_span.size());
138   for (size_t i = 0; i < dynamic_span.size(); ++i)
139     EXPECT_EQ(array[i], dynamic_span[i]);
140 
141   span<int, base::size(array)> static_span(array);
142   EXPECT_EQ(array.data(), static_span.data());
143   EXPECT_EQ(array.size(), static_span.size());
144   for (size_t i = 0; i < static_span.size(); ++i)
145     EXPECT_EQ(array[i], static_span[i]);
146 }
147 
TEST(SpanTest,ConstructFromInitializerList)148 TEST(SpanTest, ConstructFromInitializerList) {
149   std::initializer_list<int> il = {1, 1, 2, 3, 5, 8};
150 
151   span<const int> const_span(il);
152   EXPECT_EQ(il.begin(), const_span.data());
153   EXPECT_EQ(il.size(), const_span.size());
154 
155   for (size_t i = 0; i < const_span.size(); ++i)
156     EXPECT_EQ(il.begin()[i], const_span[i]);
157 
158   span<const int, 6> static_span(il);
159   EXPECT_EQ(il.begin(), static_span.data());
160   EXPECT_EQ(il.size(), static_span.size());
161 
162   for (size_t i = 0; i < static_span.size(); ++i)
163     EXPECT_EQ(il.begin()[i], static_span[i]);
164 }
165 
TEST(SpanTest,ConstructFromStdString)166 TEST(SpanTest, ConstructFromStdString) {
167   std::string str = "foobar";
168 
169   span<const char> const_span(str);
170   EXPECT_EQ(str.data(), const_span.data());
171   EXPECT_EQ(str.size(), const_span.size());
172 
173   for (size_t i = 0; i < const_span.size(); ++i)
174     EXPECT_EQ(str[i], const_span[i]);
175 
176   span<char> dynamic_span(str);
177   EXPECT_EQ(str.data(), dynamic_span.data());
178   EXPECT_EQ(str.size(), dynamic_span.size());
179 
180   for (size_t i = 0; i < dynamic_span.size(); ++i)
181     EXPECT_EQ(str[i], dynamic_span[i]);
182 
183   span<char, 6> static_span(str);
184   EXPECT_EQ(str.data(), static_span.data());
185   EXPECT_EQ(str.size(), static_span.size());
186 
187   for (size_t i = 0; i < static_span.size(); ++i)
188     EXPECT_EQ(str[i], static_span[i]);
189 }
190 
TEST(SpanTest,ConstructFromConstContainer)191 TEST(SpanTest, ConstructFromConstContainer) {
192   const std::vector<int> vector = {1, 1, 2, 3, 5, 8};
193 
194   span<const int> const_span(vector);
195   EXPECT_EQ(vector.data(), const_span.data());
196   EXPECT_EQ(vector.size(), const_span.size());
197 
198   for (size_t i = 0; i < const_span.size(); ++i)
199     EXPECT_EQ(vector[i], const_span[i]);
200 
201   span<const int, 6> static_span(vector);
202   EXPECT_EQ(vector.data(), static_span.data());
203   EXPECT_EQ(vector.size(), static_span.size());
204 
205   for (size_t i = 0; i < static_span.size(); ++i)
206     EXPECT_EQ(vector[i], static_span[i]);
207 }
208 
TEST(SpanTest,ConstructFromContainer)209 TEST(SpanTest, ConstructFromContainer) {
210   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
211 
212   span<const int> const_span(vector);
213   EXPECT_EQ(vector.data(), const_span.data());
214   EXPECT_EQ(vector.size(), const_span.size());
215 
216   for (size_t i = 0; i < const_span.size(); ++i)
217     EXPECT_EQ(vector[i], const_span[i]);
218 
219   span<int> dynamic_span(vector);
220   EXPECT_EQ(vector.data(), dynamic_span.data());
221   EXPECT_EQ(vector.size(), dynamic_span.size());
222 
223   for (size_t i = 0; i < dynamic_span.size(); ++i)
224     EXPECT_EQ(vector[i], dynamic_span[i]);
225 
226   span<int, 6> static_span(vector);
227   EXPECT_EQ(vector.data(), static_span.data());
228   EXPECT_EQ(vector.size(), static_span.size());
229 
230   for (size_t i = 0; i < static_span.size(); ++i)
231     EXPECT_EQ(vector[i], static_span[i]);
232 }
233 
TEST(SpanTest,ConvertNonConstIntegralToConst)234 TEST(SpanTest, ConvertNonConstIntegralToConst) {
235   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
236 
237   span<int> int_span(vector.data(), vector.size());
238   span<const int> const_span(int_span);
239   EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
240 
241   span<int, 6> static_int_span(vector.data(), vector.size());
242   span<const int, 6> static_const_span(static_int_span);
243   EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
244 }
245 
TEST(SpanTest,ConvertNonConstPointerToConst)246 TEST(SpanTest, ConvertNonConstPointerToConst) {
247   auto a = std::make_unique<int>(11);
248   auto b = std::make_unique<int>(22);
249   auto c = std::make_unique<int>(33);
250   std::vector<int*> vector = {a.get(), b.get(), c.get()};
251 
252   span<int*> non_const_pointer_span(vector);
253   EXPECT_THAT(non_const_pointer_span, Pointwise(Eq(), vector));
254   span<int* const> const_pointer_span(non_const_pointer_span);
255   EXPECT_THAT(const_pointer_span, Pointwise(Eq(), non_const_pointer_span));
256   // Note: no test for conversion from span<int> to span<const int*>, since that
257   // would imply a conversion from int** to const int**, which is unsafe.
258   //
259   // Note: no test for conversion from span<int*> to span<const int* const>,
260   // due to CWG Defect 330:
261   // http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
262 
263   span<int*, 3> static_non_const_pointer_span(vector);
264   EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
265   span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
266   EXPECT_THAT(static_const_pointer_span,
267               Pointwise(Eq(), static_non_const_pointer_span));
268 }
269 
TEST(SpanTest,ConvertBetweenEquivalentTypes)270 TEST(SpanTest, ConvertBetweenEquivalentTypes) {
271   std::vector<int32_t> vector = {2, 4, 8, 16, 32};
272 
273   span<int32_t> int32_t_span(vector);
274   span<int> converted_span(int32_t_span);
275   EXPECT_EQ(int32_t_span, converted_span);
276 
277   span<int32_t, 5> static_int32_t_span(vector);
278   span<int, 5> static_converted_span(static_int32_t_span);
279   EXPECT_EQ(static_int32_t_span, static_converted_span);
280 }
281 
TEST(SpanTest,TemplatedFirst)282 TEST(SpanTest, TemplatedFirst) {
283   static constexpr int array[] = {1, 2, 3};
284   constexpr span<const int, 3> span(array);
285 
286   {
287     constexpr auto subspan = span.first<0>();
288     static_assert(span.data() == subspan.data(), "");
289     static_assert(0u == subspan.size(), "");
290     static_assert(0u == decltype(subspan)::extent, "");
291   }
292 
293   {
294     constexpr auto subspan = span.first<1>();
295     static_assert(span.data() == subspan.data(), "");
296     static_assert(1u == subspan.size(), "");
297     static_assert(1u == decltype(subspan)::extent, "");
298     static_assert(1 == subspan[0], "");
299   }
300 
301   {
302     constexpr auto subspan = span.first<2>();
303     static_assert(span.data() == subspan.data(), "");
304     static_assert(2u == subspan.size(), "");
305     static_assert(2u == decltype(subspan)::extent, "");
306     static_assert(1 == subspan[0], "");
307     static_assert(2 == subspan[1], "");
308   }
309 
310   {
311     constexpr auto subspan = span.first<3>();
312     static_assert(span.data() == subspan.data(), "");
313     static_assert(3u == subspan.size(), "");
314     static_assert(3u == decltype(subspan)::extent, "");
315     static_assert(1 == subspan[0], "");
316     static_assert(2 == subspan[1], "");
317     static_assert(3 == subspan[2], "");
318   }
319 }
320 
TEST(SpanTest,TemplatedLast)321 TEST(SpanTest, TemplatedLast) {
322   static constexpr int array[] = {1, 2, 3};
323   constexpr span<const int, 3> span(array);
324 
325   {
326     constexpr auto subspan = span.last<0>();
327     static_assert(span.data() + 3 == subspan.data(), "");
328     static_assert(0u == subspan.size(), "");
329     static_assert(0u == decltype(subspan)::extent, "");
330   }
331 
332   {
333     constexpr auto subspan = span.last<1>();
334     static_assert(span.data() + 2 == subspan.data(), "");
335     static_assert(1u == subspan.size(), "");
336     static_assert(1u == decltype(subspan)::extent, "");
337     static_assert(3 == subspan[0], "");
338   }
339 
340   {
341     constexpr auto subspan = span.last<2>();
342     static_assert(span.data() + 1 == subspan.data(), "");
343     static_assert(2u == subspan.size(), "");
344     static_assert(2u == decltype(subspan)::extent, "");
345     static_assert(2 == subspan[0], "");
346     static_assert(3 == subspan[1], "");
347   }
348 
349   {
350     constexpr auto subspan = span.last<3>();
351     static_assert(span.data() == subspan.data(), "");
352     static_assert(3u == subspan.size(), "");
353     static_assert(3u == decltype(subspan)::extent, "");
354     static_assert(1 == subspan[0], "");
355     static_assert(2 == subspan[1], "");
356     static_assert(3 == subspan[2], "");
357   }
358 }
359 
TEST(SpanTest,TemplatedSubspan)360 TEST(SpanTest, TemplatedSubspan) {
361   static constexpr int array[] = {1, 2, 3};
362   constexpr span<const int, 3> span(array);
363 
364   {
365     constexpr auto subspan = span.subspan<0>();
366     static_assert(span.data() == subspan.data(), "");
367     static_assert(3u == subspan.size(), "");
368     static_assert(3u == decltype(subspan)::extent, "");
369     static_assert(1 == subspan[0], "");
370     static_assert(2 == subspan[1], "");
371     static_assert(3 == subspan[2], "");
372   }
373 
374   {
375     constexpr auto subspan = span.subspan<1>();
376     static_assert(span.data() + 1 == subspan.data(), "");
377     static_assert(2u == subspan.size(), "");
378     static_assert(2u == decltype(subspan)::extent, "");
379     static_assert(2 == subspan[0], "");
380     static_assert(3 == subspan[1], "");
381   }
382 
383   {
384     constexpr auto subspan = span.subspan<2>();
385     static_assert(span.data() + 2 == subspan.data(), "");
386     static_assert(1u == subspan.size(), "");
387     static_assert(1u == decltype(subspan)::extent, "");
388     static_assert(3 == subspan[0], "");
389   }
390 
391   {
392     constexpr auto subspan = span.subspan<3>();
393     static_assert(span.data() + 3 == subspan.data(), "");
394     static_assert(0u == subspan.size(), "");
395     static_assert(0u == decltype(subspan)::extent, "");
396   }
397 
398   {
399     constexpr auto subspan = span.subspan<0, 0>();
400     static_assert(span.data() == subspan.data(), "");
401     static_assert(0u == subspan.size(), "");
402     static_assert(0u == decltype(subspan)::extent, "");
403   }
404 
405   {
406     constexpr auto subspan = span.subspan<1, 0>();
407     static_assert(span.data() + 1 == subspan.data(), "");
408     static_assert(0u == subspan.size(), "");
409     static_assert(0u == decltype(subspan)::extent, "");
410   }
411 
412   {
413     constexpr auto subspan = span.subspan<2, 0>();
414     static_assert(span.data() + 2 == subspan.data(), "");
415     static_assert(0u == subspan.size(), "");
416     static_assert(0u == decltype(subspan)::extent, "");
417   }
418 
419   {
420     constexpr auto subspan = span.subspan<0, 1>();
421     static_assert(span.data() == subspan.data(), "");
422     static_assert(1u == subspan.size(), "");
423     static_assert(1u == decltype(subspan)::extent, "");
424     static_assert(1 == subspan[0], "");
425   }
426 
427   {
428     constexpr auto subspan = span.subspan<1, 1>();
429     static_assert(span.data() + 1 == subspan.data(), "");
430     static_assert(1u == subspan.size(), "");
431     static_assert(1u == decltype(subspan)::extent, "");
432     static_assert(2 == subspan[0], "");
433   }
434 
435   {
436     constexpr auto subspan = span.subspan<2, 1>();
437     static_assert(span.data() + 2 == subspan.data(), "");
438     static_assert(1u == subspan.size(), "");
439     static_assert(1u == decltype(subspan)::extent, "");
440     static_assert(3 == subspan[0], "");
441   }
442 
443   {
444     constexpr auto subspan = span.subspan<0, 2>();
445     static_assert(span.data() == subspan.data(), "");
446     static_assert(2u == subspan.size(), "");
447     static_assert(2u == decltype(subspan)::extent, "");
448     static_assert(1 == subspan[0], "");
449     static_assert(2 == subspan[1], "");
450   }
451 
452   {
453     constexpr auto subspan = span.subspan<1, 2>();
454     static_assert(span.data() + 1 == subspan.data(), "");
455     static_assert(2u == subspan.size(), "");
456     static_assert(2u == decltype(subspan)::extent, "");
457     static_assert(2 == subspan[0], "");
458     static_assert(3 == subspan[1], "");
459   }
460 
461   {
462     constexpr auto subspan = span.subspan<0, 3>();
463     static_assert(span.data() == subspan.data(), "");
464     static_assert(3u == subspan.size(), "");
465     static_assert(3u == decltype(subspan)::extent, "");
466     static_assert(1 == subspan[0], "");
467     static_assert(2 == subspan[1], "");
468     static_assert(3 == subspan[2], "");
469   }
470 }
471 
TEST(SpanTest,TemplatedFirstOnDynamicSpan)472 TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
473   int array[] = {1, 2, 3};
474   span<const int> span(array);
475 
476   {
477     auto subspan = span.first<0>();
478     EXPECT_EQ(span.data(), subspan.data());
479     EXPECT_EQ(0u, subspan.size());
480     static_assert(0u == decltype(subspan)::extent, "");
481   }
482 
483   {
484     auto subspan = span.first<1>();
485     EXPECT_EQ(span.data(), subspan.data());
486     EXPECT_EQ(1u, subspan.size());
487     static_assert(1u == decltype(subspan)::extent, "");
488     EXPECT_EQ(1, subspan[0]);
489   }
490 
491   {
492     auto subspan = span.first<2>();
493     EXPECT_EQ(span.data(), subspan.data());
494     EXPECT_EQ(2u, subspan.size());
495     static_assert(2u == decltype(subspan)::extent, "");
496     EXPECT_EQ(1, subspan[0]);
497     EXPECT_EQ(2, subspan[1]);
498   }
499 
500   {
501     auto subspan = span.first<3>();
502     EXPECT_EQ(span.data(), subspan.data());
503     EXPECT_EQ(3u, subspan.size());
504     static_assert(3u == decltype(subspan)::extent, "");
505     EXPECT_EQ(1, subspan[0]);
506     EXPECT_EQ(2, subspan[1]);
507     EXPECT_EQ(3, subspan[2]);
508   }
509 }
510 
TEST(SpanTest,TemplatedLastOnDynamicSpan)511 TEST(SpanTest, TemplatedLastOnDynamicSpan) {
512   int array[] = {1, 2, 3};
513   span<int> span(array);
514 
515   {
516     auto subspan = span.last<0>();
517     EXPECT_EQ(span.data() + 3, subspan.data());
518     EXPECT_EQ(0u, subspan.size());
519     static_assert(0u == decltype(subspan)::extent, "");
520   }
521 
522   {
523     auto subspan = span.last<1>();
524     EXPECT_EQ(span.data() + 2, subspan.data());
525     EXPECT_EQ(1u, subspan.size());
526     static_assert(1u == decltype(subspan)::extent, "");
527     EXPECT_EQ(3, subspan[0]);
528   }
529 
530   {
531     auto subspan = span.last<2>();
532     EXPECT_EQ(span.data() + 1, subspan.data());
533     EXPECT_EQ(2u, subspan.size());
534     static_assert(2u == decltype(subspan)::extent, "");
535     EXPECT_EQ(2, subspan[0]);
536     EXPECT_EQ(3, subspan[1]);
537   }
538 
539   {
540     auto subspan = span.last<3>();
541     EXPECT_EQ(span.data(), subspan.data());
542     EXPECT_EQ(3u, subspan.size());
543     static_assert(3u == decltype(subspan)::extent, "");
544     EXPECT_EQ(1, subspan[0]);
545     EXPECT_EQ(2, subspan[1]);
546     EXPECT_EQ(3, subspan[2]);
547   }
548 }
549 
TEST(SpanTest,TemplatedSubspanFromDynamicSpan)550 TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
551   int array[] = {1, 2, 3};
552   span<int, 3> span(array);
553 
554   {
555     auto subspan = span.subspan<0>();
556     EXPECT_EQ(span.data(), subspan.data());
557     static_assert(3u == decltype(subspan)::extent, "");
558     EXPECT_EQ(3u, subspan.size());
559     EXPECT_EQ(1, subspan[0]);
560     EXPECT_EQ(2, subspan[1]);
561     EXPECT_EQ(3, subspan[2]);
562   }
563 
564   {
565     auto subspan = span.subspan<1>();
566     EXPECT_EQ(span.data() + 1, subspan.data());
567     EXPECT_EQ(2u, subspan.size());
568     static_assert(2u == decltype(subspan)::extent, "");
569     EXPECT_EQ(2, subspan[0]);
570     EXPECT_EQ(3, subspan[1]);
571   }
572 
573   {
574     auto subspan = span.subspan<2>();
575     EXPECT_EQ(span.data() + 2, subspan.data());
576     EXPECT_EQ(1u, subspan.size());
577     static_assert(1u == decltype(subspan)::extent, "");
578     EXPECT_EQ(3, subspan[0]);
579   }
580 
581   {
582     auto subspan = span.subspan<3>();
583     EXPECT_EQ(span.data() + 3, subspan.data());
584     EXPECT_EQ(0u, subspan.size());
585     static_assert(0u == decltype(subspan)::extent, "");
586   }
587 
588   {
589     auto subspan = span.subspan<0, 0>();
590     EXPECT_EQ(span.data(), subspan.data());
591     EXPECT_EQ(0u, subspan.size());
592     static_assert(0u == decltype(subspan)::extent, "");
593   }
594 
595   {
596     auto subspan = span.subspan<1, 0>();
597     EXPECT_EQ(span.data() + 1, subspan.data());
598     EXPECT_EQ(0u, subspan.size());
599     static_assert(0u == decltype(subspan)::extent, "");
600   }
601 
602   {
603     auto subspan = span.subspan<2, 0>();
604     EXPECT_EQ(span.data() + 2, subspan.data());
605     EXPECT_EQ(0u, subspan.size());
606     static_assert(0u == decltype(subspan)::extent, "");
607   }
608 
609   {
610     auto subspan = span.subspan<0, 1>();
611     EXPECT_EQ(span.data(), subspan.data());
612     EXPECT_EQ(1u, subspan.size());
613     static_assert(1u == decltype(subspan)::extent, "");
614     EXPECT_EQ(1, subspan[0]);
615   }
616 
617   {
618     auto subspan = span.subspan<1, 1>();
619     EXPECT_EQ(span.data() + 1, subspan.data());
620     EXPECT_EQ(1u, subspan.size());
621     static_assert(1u == decltype(subspan)::extent, "");
622     EXPECT_EQ(2, subspan[0]);
623   }
624 
625   {
626     auto subspan = span.subspan<2, 1>();
627     EXPECT_EQ(span.data() + 2, subspan.data());
628     EXPECT_EQ(1u, subspan.size());
629     static_assert(1u == decltype(subspan)::extent, "");
630     EXPECT_EQ(3, subspan[0]);
631   }
632 
633   {
634     auto subspan = span.subspan<0, 2>();
635     EXPECT_EQ(span.data(), subspan.data());
636     EXPECT_EQ(2u, subspan.size());
637     static_assert(2u == decltype(subspan)::extent, "");
638     EXPECT_EQ(1, subspan[0]);
639     EXPECT_EQ(2, subspan[1]);
640   }
641 
642   {
643     auto subspan = span.subspan<1, 2>();
644     EXPECT_EQ(span.data() + 1, subspan.data());
645     EXPECT_EQ(2u, subspan.size());
646     static_assert(2u == decltype(subspan)::extent, "");
647     EXPECT_EQ(2, subspan[0]);
648     EXPECT_EQ(3, subspan[1]);
649   }
650 
651   {
652     auto subspan = span.subspan<0, 3>();
653     EXPECT_EQ(span.data(), subspan.data());
654     EXPECT_EQ(3u, subspan.size());
655     static_assert(3u == decltype(subspan)::extent, "");
656     EXPECT_EQ(1, subspan[0]);
657     EXPECT_EQ(2, subspan[1]);
658     EXPECT_EQ(3, subspan[2]);
659   }
660 }
661 
TEST(SpanTest,First)662 TEST(SpanTest, First) {
663   int array[] = {1, 2, 3};
664   span<int> span(array);
665 
666   {
667     auto subspan = span.first(0);
668     EXPECT_EQ(span.data(), subspan.data());
669     EXPECT_EQ(0u, subspan.size());
670   }
671 
672   {
673     auto subspan = span.first(1);
674     EXPECT_EQ(span.data(), subspan.data());
675     EXPECT_EQ(1u, subspan.size());
676     EXPECT_EQ(1, subspan[0]);
677   }
678 
679   {
680     auto subspan = span.first(2);
681     EXPECT_EQ(span.data(), subspan.data());
682     EXPECT_EQ(2u, subspan.size());
683     EXPECT_EQ(1, subspan[0]);
684     EXPECT_EQ(2, subspan[1]);
685   }
686 
687   {
688     auto subspan = span.first(3);
689     EXPECT_EQ(span.data(), subspan.data());
690     EXPECT_EQ(3u, subspan.size());
691     EXPECT_EQ(1, subspan[0]);
692     EXPECT_EQ(2, subspan[1]);
693     EXPECT_EQ(3, subspan[2]);
694   }
695 }
696 
TEST(SpanTest,Last)697 TEST(SpanTest, Last) {
698   int array[] = {1, 2, 3};
699   span<int> span(array);
700 
701   {
702     auto subspan = span.last(0);
703     EXPECT_EQ(span.data() + 3, subspan.data());
704     EXPECT_EQ(0u, subspan.size());
705   }
706 
707   {
708     auto subspan = span.last(1);
709     EXPECT_EQ(span.data() + 2, subspan.data());
710     EXPECT_EQ(1u, subspan.size());
711     EXPECT_EQ(3, subspan[0]);
712   }
713 
714   {
715     auto subspan = span.last(2);
716     EXPECT_EQ(span.data() + 1, subspan.data());
717     EXPECT_EQ(2u, subspan.size());
718     EXPECT_EQ(2, subspan[0]);
719     EXPECT_EQ(3, subspan[1]);
720   }
721 
722   {
723     auto subspan = span.last(3);
724     EXPECT_EQ(span.data(), subspan.data());
725     EXPECT_EQ(3u, subspan.size());
726     EXPECT_EQ(1, subspan[0]);
727     EXPECT_EQ(2, subspan[1]);
728     EXPECT_EQ(3, subspan[2]);
729   }
730 }
731 
TEST(SpanTest,Subspan)732 TEST(SpanTest, Subspan) {
733   int array[] = {1, 2, 3};
734   span<int> span(array);
735 
736   {
737     auto subspan = span.subspan(0);
738     EXPECT_EQ(span.data(), subspan.data());
739     EXPECT_EQ(3u, subspan.size());
740     EXPECT_EQ(1, subspan[0]);
741     EXPECT_EQ(2, subspan[1]);
742     EXPECT_EQ(3, subspan[2]);
743   }
744 
745   {
746     auto subspan = span.subspan(1);
747     EXPECT_EQ(span.data() + 1, subspan.data());
748     EXPECT_EQ(2u, subspan.size());
749     EXPECT_EQ(2, subspan[0]);
750     EXPECT_EQ(3, subspan[1]);
751   }
752 
753   {
754     auto subspan = span.subspan(2);
755     EXPECT_EQ(span.data() + 2, subspan.data());
756     EXPECT_EQ(1u, subspan.size());
757     EXPECT_EQ(3, subspan[0]);
758   }
759 
760   {
761     auto subspan = span.subspan(3);
762     EXPECT_EQ(span.data() + 3, subspan.data());
763     EXPECT_EQ(0u, subspan.size());
764   }
765 
766   {
767     auto subspan = span.subspan(0, 0);
768     EXPECT_EQ(span.data(), subspan.data());
769     EXPECT_EQ(0u, subspan.size());
770   }
771 
772   {
773     auto subspan = span.subspan(1, 0);
774     EXPECT_EQ(span.data() + 1, subspan.data());
775     EXPECT_EQ(0u, subspan.size());
776   }
777 
778   {
779     auto subspan = span.subspan(2, 0);
780     EXPECT_EQ(span.data() + 2, subspan.data());
781     EXPECT_EQ(0u, subspan.size());
782   }
783 
784   {
785     auto subspan = span.subspan(0, 1);
786     EXPECT_EQ(span.data(), subspan.data());
787     EXPECT_EQ(1u, subspan.size());
788     EXPECT_EQ(1, subspan[0]);
789   }
790 
791   {
792     auto subspan = span.subspan(1, 1);
793     EXPECT_EQ(span.data() + 1, subspan.data());
794     EXPECT_EQ(1u, subspan.size());
795     EXPECT_EQ(2, subspan[0]);
796   }
797 
798   {
799     auto subspan = span.subspan(2, 1);
800     EXPECT_EQ(span.data() + 2, subspan.data());
801     EXPECT_EQ(1u, subspan.size());
802     EXPECT_EQ(3, subspan[0]);
803   }
804 
805   {
806     auto subspan = span.subspan(0, 2);
807     EXPECT_EQ(span.data(), subspan.data());
808     EXPECT_EQ(2u, subspan.size());
809     EXPECT_EQ(1, subspan[0]);
810     EXPECT_EQ(2, subspan[1]);
811   }
812 
813   {
814     auto subspan = span.subspan(1, 2);
815     EXPECT_EQ(span.data() + 1, subspan.data());
816     EXPECT_EQ(2u, subspan.size());
817     EXPECT_EQ(2, subspan[0]);
818     EXPECT_EQ(3, subspan[1]);
819   }
820 
821   {
822     auto subspan = span.subspan(0, 3);
823     EXPECT_EQ(span.data(), subspan.data());
824     EXPECT_EQ(span.size(), subspan.size());
825     EXPECT_EQ(1, subspan[0]);
826     EXPECT_EQ(2, subspan[1]);
827     EXPECT_EQ(3, subspan[2]);
828   }
829 }
830 
TEST(SpanTest,Size)831 TEST(SpanTest, Size) {
832   {
833     span<int> span;
834     EXPECT_EQ(0u, span.size());
835   }
836 
837   {
838     int array[] = {1, 2, 3};
839     span<int> span(array);
840     EXPECT_EQ(3u, span.size());
841   }
842 }
843 
TEST(SpanTest,SizeBytes)844 TEST(SpanTest, SizeBytes) {
845   {
846     span<int> span;
847     EXPECT_EQ(0u, span.size_bytes());
848   }
849 
850   {
851     int array[] = {1, 2, 3};
852     span<int> span(array);
853     EXPECT_EQ(3u * sizeof(int), span.size_bytes());
854   }
855 }
856 
TEST(SpanTest,Empty)857 TEST(SpanTest, Empty) {
858   {
859     span<int> span;
860     EXPECT_TRUE(span.empty());
861   }
862 
863   {
864     int array[] = {1, 2, 3};
865     span<int> span(array);
866     EXPECT_FALSE(span.empty());
867   }
868 }
869 
TEST(SpanTest,OperatorAt)870 TEST(SpanTest, OperatorAt) {
871   static constexpr int kArray[] = {1, 6, 1, 8, 0};
872   constexpr span<const int> span(kArray);
873 
874   static_assert(kArray[0] == span[0], "span[0] does not equal kArray[0]");
875   static_assert(kArray[1] == span[1], "span[1] does not equal kArray[1]");
876   static_assert(kArray[2] == span[2], "span[2] does not equal kArray[2]");
877   static_assert(kArray[3] == span[3], "span[3] does not equal kArray[3]");
878   static_assert(kArray[4] == span[4], "span[4] does not equal kArray[4]");
879 
880   static_assert(kArray[0] == span(0), "span(0) does not equal kArray[0]");
881   static_assert(kArray[1] == span(1), "span(1) does not equal kArray[1]");
882   static_assert(kArray[2] == span(2), "span(2) does not equal kArray[2]");
883   static_assert(kArray[3] == span(3), "span(3) does not equal kArray[3]");
884   static_assert(kArray[4] == span(4), "span(4) does not equal kArray[4]");
885 }
886 
TEST(SpanTest,Iterator)887 TEST(SpanTest, Iterator) {
888   static constexpr int kArray[] = {1, 6, 1, 8, 0};
889   constexpr span<const int> span(kArray);
890 
891   std::vector<int> results;
892   for (int i : span)
893     results.emplace_back(i);
894   EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
895 }
896 
TEST(SpanTest,ReverseIterator)897 TEST(SpanTest, ReverseIterator) {
898   static constexpr int kArray[] = {1, 6, 1, 8, 0};
899   constexpr span<const int> span(kArray);
900 
901   EXPECT_TRUE(std::equal(std::rbegin(kArray), std::rend(kArray), span.rbegin(),
902                          span.rend()));
903   EXPECT_TRUE(std::equal(std::crbegin(kArray), std::crend(kArray),
904                          span.crbegin(), span.crend()));
905 }
906 
TEST(SpanTest,Equality)907 TEST(SpanTest, Equality) {
908   static constexpr int kArray1[] = {3, 1, 4, 1, 5};
909   static constexpr int kArray2[] = {3, 1, 4, 1, 5};
910   constexpr span<const int> span1(kArray1);
911   constexpr span<const int, 5> span2(kArray2);
912 
913   EXPECT_EQ(span1, span2);
914 
915   static constexpr int kArray3[] = {2, 7, 1, 8, 3};
916   constexpr span<const int> span3(kArray3);
917 
918   EXPECT_FALSE(span1 == span3);
919 
920   static double kArray4[] = {2.0, 7.0, 1.0, 8.0, 3.0};
921   span<double, 5> span4(kArray4);
922 
923   EXPECT_EQ(span3, span4);
924 }
925 
TEST(SpanTest,Inequality)926 TEST(SpanTest, Inequality) {
927   static constexpr int kArray1[] = {2, 3, 5, 7, 11};
928   static constexpr int kArray2[] = {1, 4, 6, 8, 9};
929   constexpr span<const int> span1(kArray1);
930   constexpr span<const int, 5> span2(kArray2);
931 
932   EXPECT_NE(span1, span2);
933 
934   static constexpr int kArray3[] = {2, 3, 5, 7, 11};
935   constexpr span<const int> span3(kArray3);
936 
937   EXPECT_FALSE(span1 != span3);
938 
939   static double kArray4[] = {1.0, 4.0, 6.0, 8.0, 9.0};
940   span<double, 5> span4(kArray4);
941 
942   EXPECT_NE(span3, span4);
943 }
944 
TEST(SpanTest,LessThan)945 TEST(SpanTest, LessThan) {
946   static constexpr int kArray1[] = {2, 3, 5, 7, 11};
947   static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
948   constexpr span<const int> span1(kArray1);
949   constexpr span<const int, 6> span2(kArray2);
950 
951   EXPECT_LT(span1, span2);
952 
953   static constexpr int kArray3[] = {2, 3, 5, 7, 11};
954   constexpr span<const int> span3(kArray3);
955 
956   EXPECT_FALSE(span1 < span3);
957 
958   static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
959   span<double, 6> span4(kArray4);
960 
961   EXPECT_LT(span3, span4);
962 }
963 
TEST(SpanTest,LessEqual)964 TEST(SpanTest, LessEqual) {
965   static constexpr int kArray1[] = {2, 3, 5, 7, 11};
966   static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
967   constexpr span<const int> span1(kArray1);
968   constexpr span<const int, 6> span2(kArray2);
969 
970   EXPECT_LE(span1, span1);
971   EXPECT_LE(span1, span2);
972 
973   static constexpr int kArray3[] = {2, 3, 5, 7, 10};
974   constexpr span<const int> span3(kArray3);
975 
976   EXPECT_FALSE(span1 <= span3);
977 
978   static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
979   span<double, 6> span4(kArray4);
980 
981   EXPECT_LE(span3, span4);
982 }
983 
TEST(SpanTest,GreaterThan)984 TEST(SpanTest, GreaterThan) {
985   static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
986   static constexpr int kArray2[] = {2, 3, 5, 7, 11};
987   constexpr span<const int> span1(kArray1);
988   constexpr span<const int, 5> span2(kArray2);
989 
990   EXPECT_GT(span1, span2);
991 
992   static constexpr int kArray3[] = {2, 3, 5, 7, 11, 13};
993   constexpr span<const int> span3(kArray3);
994 
995   EXPECT_FALSE(span1 > span3);
996 
997   static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
998   span<double, 5> span4(kArray4);
999 
1000   EXPECT_GT(span3, span4);
1001 }
1002 
TEST(SpanTest,GreaterEqual)1003 TEST(SpanTest, GreaterEqual) {
1004   static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
1005   static constexpr int kArray2[] = {2, 3, 5, 7, 11};
1006   constexpr span<const int> span1(kArray1);
1007   constexpr span<const int, 5> span2(kArray2);
1008 
1009   EXPECT_GE(span1, span1);
1010   EXPECT_GE(span1, span2);
1011 
1012   static constexpr int kArray3[] = {2, 3, 5, 7, 12};
1013   constexpr span<const int> span3(kArray3);
1014 
1015   EXPECT_FALSE(span1 >= span3);
1016 
1017   static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
1018   span<double, 5> span4(kArray4);
1019 
1020   EXPECT_GE(span3, span4);
1021 }
1022 
TEST(SpanTest,AsBytes)1023 TEST(SpanTest, AsBytes) {
1024   {
1025     constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
1026     span<const uint8_t, sizeof(kArray)> bytes_span =
1027         as_bytes(make_span(kArray));
1028     EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
1029     EXPECT_EQ(sizeof(kArray), bytes_span.size());
1030     EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1031   }
1032 
1033   {
1034     std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1035     span<int> mutable_span(vec);
1036     span<const uint8_t> bytes_span = as_bytes(mutable_span);
1037     EXPECT_EQ(reinterpret_cast<const uint8_t*>(vec.data()), bytes_span.data());
1038     EXPECT_EQ(sizeof(int) * vec.size(), bytes_span.size());
1039     EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
1040   }
1041 }
1042 
TEST(SpanTest,AsWritableBytes)1043 TEST(SpanTest, AsWritableBytes) {
1044   std::vector<int> vec = {1, 1, 2, 3, 5, 8};
1045   span<int> mutable_span(vec);
1046   span<uint8_t> writable_bytes_span = as_writable_bytes(mutable_span);
1047   EXPECT_EQ(reinterpret_cast<uint8_t*>(vec.data()), writable_bytes_span.data());
1048   EXPECT_EQ(sizeof(int) * vec.size(), writable_bytes_span.size());
1049   EXPECT_EQ(writable_bytes_span.size(), writable_bytes_span.size_bytes());
1050 
1051   // Set the first entry of vec to zero while writing through the span.
1052   std::fill(writable_bytes_span.data(),
1053             writable_bytes_span.data() + sizeof(int), 0);
1054   EXPECT_EQ(0, vec[0]);
1055 }
1056 
TEST(SpanTest,MakeSpanFromDataAndSize)1057 TEST(SpanTest, MakeSpanFromDataAndSize) {
1058   int* nullint = nullptr;
1059   auto empty_span = make_span(nullint, 0);
1060   EXPECT_TRUE(empty_span.empty());
1061   EXPECT_EQ(nullptr, empty_span.data());
1062 
1063   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1064   span<int> span(vector.data(), vector.size());
1065   auto made_span = make_span(vector.data(), vector.size());
1066   EXPECT_EQ(span, made_span);
1067   static_assert(decltype(made_span)::extent == dynamic_extent, "");
1068 }
1069 
TEST(SpanTest,MakeSpanFromPointerPair)1070 TEST(SpanTest, MakeSpanFromPointerPair) {
1071   int* nullint = nullptr;
1072   auto empty_span = make_span(nullint, nullint);
1073   EXPECT_TRUE(empty_span.empty());
1074   EXPECT_EQ(nullptr, empty_span.data());
1075 
1076   std::vector<int> vector = {1, 1, 2, 3, 5, 8};
1077   span<int> span(vector.data(), vector.size());
1078   auto made_span = make_span(vector.data(), vector.data() + vector.size());
1079   EXPECT_EQ(span, made_span);
1080   static_assert(decltype(made_span)::extent == dynamic_extent, "");
1081 }
1082 
TEST(SpanTest,MakeSpanFromConstexprArray)1083 TEST(SpanTest, MakeSpanFromConstexprArray) {
1084   static constexpr int kArray[] = {1, 2, 3, 4, 5};
1085   constexpr span<const int> span(kArray);
1086   EXPECT_EQ(span, make_span(kArray));
1087   static_assert(decltype(make_span(kArray))::extent == 5, "");
1088 }
1089 
TEST(SpanTest,MakeSpanFromStdArray)1090 TEST(SpanTest, MakeSpanFromStdArray) {
1091   const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
1092   span<const int> span(kArray);
1093   EXPECT_EQ(span, make_span(kArray));
1094   static_assert(decltype(make_span(kArray))::extent == 5, "");
1095 }
1096 
TEST(SpanTest,MakeSpanFromConstContainer)1097 TEST(SpanTest, MakeSpanFromConstContainer) {
1098   const std::vector<int> vector = {-1, -2, -3, -4, -5};
1099   span<const int> span(vector);
1100   EXPECT_EQ(span, make_span(vector));
1101   static_assert(decltype(make_span(vector))::extent == dynamic_extent, "");
1102 }
1103 
TEST(SpanTest,MakeSpanFromContainer)1104 TEST(SpanTest, MakeSpanFromContainer) {
1105   std::vector<int> vector = {-1, -2, -3, -4, -5};
1106   span<int> span(vector);
1107   EXPECT_EQ(span, make_span(vector));
1108   static_assert(decltype(make_span(vector))::extent == dynamic_extent, "");
1109 }
1110 
TEST(SpanTest,MakeSpanFromDynamicSpan)1111 TEST(SpanTest, MakeSpanFromDynamicSpan) {
1112   static constexpr int kArray[] = {1, 2, 3, 4, 5};
1113   constexpr span<const int> span(kArray);
1114   static_assert(std::is_same<decltype(span)::element_type,
1115                              decltype(make_span(span))::element_type>::value,
1116                 "make_span(span) should have the same element_type as span");
1117 
1118   static_assert(span.data() == make_span(span).data(),
1119                 "make_span(span) should have the same data() as span");
1120 
1121   static_assert(span.size() == make_span(span).size(),
1122                 "make_span(span) should have the same size() as span");
1123 
1124   static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
1125                 "make_span(span) should have the same extent as span");
1126 }
1127 
TEST(SpanTest,MakeSpanFromStaticSpan)1128 TEST(SpanTest, MakeSpanFromStaticSpan) {
1129   static constexpr int kArray[] = {1, 2, 3, 4, 5};
1130   constexpr span<const int, 5> span(kArray);
1131   static_assert(std::is_same<decltype(span)::element_type,
1132                              decltype(make_span(span))::element_type>::value,
1133                 "make_span(span) should have the same element_type as span");
1134 
1135   static_assert(span.data() == make_span(span).data(),
1136                 "make_span(span) should have the same data() as span");
1137 
1138   static_assert(span.size() == make_span(span).size(),
1139                 "make_span(span) should have the same size() as span");
1140 
1141   static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
1142                 "make_span(span) should have the same extent as span");
1143 }
1144 
TEST(SpanTest,EnsureConstexprGoodness)1145 TEST(SpanTest, EnsureConstexprGoodness) {
1146   static constexpr int kArray[] = {5, 4, 3, 2, 1};
1147   constexpr span<const int> constexpr_span(kArray);
1148   const size_t size = 2;
1149 
1150   const size_t start = 1;
1151   constexpr span<const int> subspan =
1152       constexpr_span.subspan(start, start + size);
1153   for (size_t i = 0; i < subspan.size(); ++i)
1154     EXPECT_EQ(kArray[start + i], subspan[i]);
1155 
1156   constexpr span<const int> firsts = constexpr_span.first(size);
1157   for (size_t i = 0; i < firsts.size(); ++i)
1158     EXPECT_EQ(kArray[i], firsts[i]);
1159 
1160   constexpr span<const int> lasts = constexpr_span.last(size);
1161   for (size_t i = 0; i < lasts.size(); ++i) {
1162     const size_t j = (arraysize(kArray) - size) + i;
1163     EXPECT_EQ(kArray[j], lasts[i]);
1164   }
1165 
1166   constexpr int item = constexpr_span[size];
1167   EXPECT_EQ(kArray[size], item);
1168 }
1169 
1170 }  // namespace base
1171