blob: 22e1044b730ec0ea0ddaa0447c26d7c3306ad1fd [file] [log] [blame]
Wyatt Hepler64c165e2020-01-13 10:21:08 -08001// Copyright 2020 The Pigweed Authors
Wyatt Hepler77105652019-11-06 17:50:03 -08002//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
Wyatt Hepler1a960942019-11-26 14:13:38 -08004// use this file except in compliance with the License. You may obtain a copy of
5// the License at
Wyatt Hepler77105652019-11-06 17:50:03 -08006//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
Wyatt Hepler1a960942019-11-26 14:13:38 -080012// License for the specific language governing permissions and limitations under
13// the License.
Wyatt Hepler77105652019-11-06 17:50:03 -080014
15// This is the base::span unit test from Chromium, with small modifications.
16// Modifications are noted with "Pigweed:" comments.
17//
18// Original file:
Wyatt Hepler64c165e2020-01-13 10:21:08 -080019// https://chromium.googlesource.com/chromium/src/+/ef71f9c29f0dc6eddae474879c4ca5232ca93a6c/base/containers/span_unittest.cc
Wyatt Hepler77105652019-11-06 17:50:03 -080020//
Wyatt Hepler64c165e2020-01-13 10:21:08 -080021// In order to minimize changes from the original, this file does NOT fully
22// adhere to Pigweed's style guide.
Wyatt Hepler77105652019-11-06 17:50:03 -080023
24#include <algorithm>
25#include <cstdint>
26#include <memory>
Wyatt Hepler69a51902020-06-22 10:42:53 -070027#include <span>
Wyatt Hepler77105652019-11-06 17:50:03 -080028#include <string>
29#include <type_traits>
30#include <vector>
31
32#include "gtest/gtest.h"
33
34// Pigweed: gMock matchers are not yet supported.
35#if 0
36using ::testing::ElementsAre;
37using ::testing::Eq;
38using ::testing::Pointwise;
39#endif // 0
40
Wyatt Hepler69a51902020-06-22 10:42:53 -070041namespace std {
Wyatt Hepler77105652019-11-06 17:50:03 -080042
43namespace {
44
45// constexpr implementation of std::equal's 4 argument overload.
46template <class InputIterator1, class InputIterator2>
47constexpr bool constexpr_equal(InputIterator1 first1,
48 InputIterator1 last1,
49 InputIterator2 first2,
50 InputIterator2 last2) {
51 for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
52 if (*first1 != *first2)
53 return false;
54 }
55
56 return first1 == last1 && first2 == last2;
57}
58
59} // namespace
60
Wyatt Hepler83d42482019-11-19 15:17:33 -080061TEST(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
72TEST(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
82TEST(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
93TEST(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
Wyatt Hepler1cb06df2020-01-31 10:01:12 -0800103TEST(SpanTest, DeductionGuides_MutableContainerWithConstElements) {
104 std::string_view string("Hello");
105 auto the_span = span(string);
Wyatt Hepler83d42482019-11-19 15:17:33 -0800106 static_assert(the_span.extent == dynamic_extent);
107
108 EXPECT_STREQ("Hello", the_span.data());
109 EXPECT_EQ(5u, the_span.size());
110}
111
Wyatt Hepler1cb06df2020-01-31 10:01:12 -0800112TEST(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
123class 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
148TEST(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
161TEST(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
170TEST(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
179TEST(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
187TEST(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
199TEST(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
Wyatt Hepler77105652019-11-06 17:50:03 -0800209TEST(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(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800216 static_assert(static_span.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800217}
218
219TEST(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
241TEST(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
Wyatt Hepler3a3ec582020-03-13 10:05:12 -0700263TEST(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
316TEST(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
Wyatt Hepler77105652019-11-06 17:50:03 -0800356TEST(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
380TEST(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
402TEST(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
426TEST(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
444TEST(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
469TEST(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
487TEST(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.
515TEST(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.
530TEST(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.
555TEST(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
571TEST(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(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800578 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800579 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
610TEST(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(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800617 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800618 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
649TEST(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(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800683 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800684 static_assert(0u == decltype(subspan)::extent, "");
685 }
686
687 {
688 constexpr auto subspan = span.subspan<0, 0>();
689 static_assert(span.data() == subspan.data(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800690 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800691 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(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800697 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800698 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(), "");
Rob Mohrcd59b7e2019-11-19 09:54:45 -0800704 static_assert(subspan.empty(), "");
Wyatt Hepler77105652019-11-06 17:50:03 -0800705 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
761TEST(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
772TEST(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
811TEST(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
850TEST(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
962TEST(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
997TEST(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
1032TEST(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
1131TEST(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
1144TEST(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
1157TEST(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
1170TEST(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
1186TEST(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
1193TEST(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
Wyatt Hepler77105652019-11-06 17:50:03 -08001200// Pigweed: This test uses gMock features not yet supported in Pigweed.
1201#if 0
1202TEST(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
1213TEST(SpanTest, ConstexprIterator) {
1214 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1215 constexpr span<const int> span(kArray);
1216
Wyatt Hepler83d42482019-11-19 15:17:33 -08001217 static_assert(
1218 constexpr_equal(
1219 std::begin(kArray), std::end(kArray), span.begin(), span.end()),
1220 "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001221 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
1233TEST(SpanTest, ReverseIterator) {
1234 static constexpr int kArray[] = {1, 6, 1, 8, 0};
1235 constexpr span<const int> span(kArray);
1236
Wyatt Hepler83d42482019-11-19 15:17:33 -08001237 EXPECT_TRUE(std::equal(
1238 std::rbegin(kArray), std::rend(kArray), span.rbegin(), span.rend()));
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001239 EXPECT_TRUE(std::equal(std::crbegin(kArray),
1240 std::crend(kArray),
1241 std::crbegin(span),
1242 std::crend(span)));
Wyatt Hepler77105652019-11-06 17:50:03 -08001243}
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
1248TEST(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
1268TEST(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
1282TEST(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
1299TEST(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
1316TEST(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
1328TEST(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
1340TEST(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
1352TEST(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
1364TEST(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
1376TEST(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
1388TEST(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
1400TEST(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
1416TEST(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
1432TEST(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
1454TEST(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
Wyatt Hepler77105652019-11-06 17:50:03 -08001477TEST(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.
1505TEST(SpanTest, OutOfBoundsDeath) {
1506 constexpr span<int, 0> kEmptySpan;
1507 ASSERT_DEATH_IF_SUPPORTED(kEmptySpan[0], "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001508 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], "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001514 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], "");
Wyatt Hepler64c165e2020-01-13 10:21:08 -08001524 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(10), "");
1525 ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.subspan(1, 7), "");
Wyatt Hepler77105652019-11-06 17:50:03 -08001526}
1527
1528// Pigweed: These tests use CheckedContiguousConstIterator, which isn't used in
1529// Pigweed's version.
1530TEST(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(
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001546 std::cbegin(span), std::cend(span),
Wyatt Hepler77105652019-11-06 17:50:03 -08001547 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(
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001560 std::cbegin(span), std::cend(span),
Wyatt Hepler77105652019-11-06 17:50:03 -08001561 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(
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001571 std::cbegin(span), std::cbegin(span),
Wyatt Hepler77105652019-11-06 17:50:03 -08001572 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(
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001579 std::cend(span), std::cbegin(span),
Wyatt Hepler77105652019-11-06 17:50:03 -08001580 CheckedContiguousConstIterator<const int>(span.data(), span.data())));
1581}
1582
1583// Pigweed: gMock matchers are not yet supported.
1584TEST(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
1601TEST(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
1622TEST(SpanTest, IteratorConversions) {
1623 static_assert(std::is_convertible<span<int>::iterator,
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001624 span<const int>::iterator>::value,
1625 "Error: iterator should be convertible to const iterator");
Wyatt Hepler77105652019-11-06 17:50:03 -08001626
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001627 static_assert(!std::is_convertible<span<const int>::iterator,
Wyatt Hepler77105652019-11-06 17:50:03 -08001628 span<int>::iterator>::value,
Wyatt Hepler3a3ec582020-03-13 10:05:12 -07001629 "Error: const iterator should not be convertible to iterator");
Wyatt Hepler77105652019-11-06 17:50:03 -08001630}
1631
Wyatt Hepler69a51902020-06-22 10:42:53 -07001632} // namespace std