summaryrefslogtreecommitdiffstats
path: root/chromium/base/containers/span_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/containers/span_unittest.cc')
-rw-r--r--chromium/base/containers/span_unittest.cc109
1 files changed, 93 insertions, 16 deletions
diff --git a/chromium/base/containers/span_unittest.cc b/chromium/base/containers/span_unittest.cc
index 5ec3f3f4748..e8daf948420 100644
--- a/chromium/base/containers/span_unittest.cc
+++ b/chromium/base/containers/span_unittest.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include <memory>
#include <string>
+#include <type_traits>
#include <vector>
#include "base/containers/checked_iterators.h"
@@ -22,6 +23,24 @@ using ::testing::Pointwise;
namespace base {
+namespace {
+
+// constexpr implementation of std::equal's 4 argument overload.
+template <class InputIterator1, class InputIterator2>
+constexpr bool constexpr_equal(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2) {
+ for (; first1 != last1 && first2 != last2; ++first1, ++first2) {
+ if (*first1 != *first2)
+ return false;
+ }
+
+ return first1 == last1 && first2 == last2;
+}
+
+} // namespace
+
TEST(SpanTest, DefaultConstructor) {
span<int> dynamic_span;
EXPECT_EQ(nullptr, dynamic_span.data());
@@ -474,6 +493,17 @@ TEST(SpanTest, TemplatedSubspan) {
}
}
+TEST(SpanTest, SubscriptedBeginIterator) {
+ int array[] = {1, 2, 3};
+ span<const int> const_span(array);
+ for (size_t i = 0; i < const_span.size(); ++i)
+ EXPECT_EQ(array[i], const_span.begin()[i]);
+
+ span<int> mutable_span(array);
+ for (size_t i = 0; i < mutable_span.size(); ++i)
+ EXPECT_EQ(array[i], mutable_span.begin()[i]);
+}
+
TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
int array[] = {1, 2, 3};
span<const int> span(array);
@@ -950,6 +980,21 @@ TEST(SpanTest, Iterator) {
EXPECT_THAT(results, ElementsAre(1, 6, 1, 8, 0));
}
+TEST(SpanTest, ConstexprIterator) {
+ static constexpr int kArray[] = {1, 6, 1, 8, 0};
+ constexpr span<const int> span(kArray);
+
+ static_assert(constexpr_equal(std::begin(kArray), std::end(kArray),
+ span.begin(), span.end()),
+ "");
+ static_assert(1 == span.begin()[0], "");
+ static_assert(1 == *(span.begin() += 0), "");
+ static_assert(6 == *(span.begin() += 1), "");
+
+ static_assert(1 == *((span.begin() + 1) -= 1), "");
+ static_assert(6 == *((span.begin() + 1) -= 0), "");
+}
+
TEST(SpanTest, ReverseIterator) {
static constexpr int kArray[] = {1, 6, 1, 8, 0};
constexpr span<const int> span(kArray);
@@ -1212,12 +1257,16 @@ TEST(SpanTest, EnsureConstexprGoodness) {
TEST(SpanTest, OutOfBoundsDeath) {
constexpr span<int, 0> kEmptySpan;
ASSERT_DEATH_IF_SUPPORTED(kEmptySpan[0], "");
+ ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.begin()[0], "");
+ ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.end()[0], "");
ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.first(1), "");
ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.last(1), "");
ASSERT_DEATH_IF_SUPPORTED(kEmptySpan.subspan(1), "");
constexpr span<int> kEmptyDynamicSpan;
ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan[0], "");
+ ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.begin()[0], "");
+ ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.end()[0], "");
ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.front(), "");
ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.first(1), "");
ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.last(1), "");
@@ -1228,6 +1277,8 @@ TEST(SpanTest, OutOfBoundsDeath) {
constexpr span<const int> kNonEmptyDynamicSpan(kArray);
EXPECT_EQ(3U, kNonEmptyDynamicSpan.size());
ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan[4], "");
+ ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.begin()[-1], "");
+ ASSERT_DEATH_IF_SUPPORTED(kNonEmptyDynamicSpan.begin()[3], "");
ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.subspan(10), "");
ASSERT_DEATH_IF_SUPPORTED(kEmptyDynamicSpan.subspan(1, 7), "");
}
@@ -1242,47 +1293,73 @@ TEST(SpanTest, IteratorIsRangeMoveSafe) {
// Overlapping ranges.
for (const int dest_start_index : kOverlappingStartIndexes) {
- EXPECT_FALSE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
+ EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
span.begin(), span.end(),
- CheckedRandomAccessIterator<const int>(
+ CheckedContiguousIterator<const int>(
span.data() + dest_start_index,
span.data() + dest_start_index + kNumElements)));
- EXPECT_FALSE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
+ EXPECT_FALSE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
span.cbegin(), span.cend(),
- CheckedRandomAccessConstIterator<const int>(
+ CheckedContiguousConstIterator<const int>(
span.data() + dest_start_index,
span.data() + dest_start_index + kNumElements)));
}
// Non-overlapping ranges.
for (const int dest_start_index : kNonOverlappingStartIndexes) {
- EXPECT_TRUE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
+ EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
span.begin(), span.end(),
- CheckedRandomAccessIterator<const int>(
+ CheckedContiguousIterator<const int>(
span.data() + dest_start_index,
span.data() + dest_start_index + kNumElements)));
- EXPECT_TRUE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
+ EXPECT_TRUE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
span.cbegin(), span.cend(),
- CheckedRandomAccessConstIterator<const int>(
+ CheckedContiguousConstIterator<const int>(
span.data() + dest_start_index,
span.data() + dest_start_index + kNumElements)));
}
// IsRangeMoveSafe is true if the length to be moved is 0.
- EXPECT_TRUE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
+ EXPECT_TRUE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
span.begin(), span.begin(),
- CheckedRandomAccessIterator<const int>(span.data(), span.data())));
- EXPECT_TRUE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
+ CheckedContiguousIterator<const int>(span.data(), span.data())));
+ EXPECT_TRUE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
span.cbegin(), span.cbegin(),
- CheckedRandomAccessConstIterator<const int>(span.data(), span.data())));
+ CheckedContiguousConstIterator<const int>(span.data(), span.data())));
// IsRangeMoveSafe is false if end < begin.
- EXPECT_FALSE(CheckedRandomAccessIterator<const int>::IsRangeMoveSafe(
+ EXPECT_FALSE(CheckedContiguousIterator<const int>::IsRangeMoveSafe(
span.end(), span.begin(),
- CheckedRandomAccessIterator<const int>(span.data(), span.data())));
- EXPECT_FALSE(CheckedRandomAccessConstIterator<const int>::IsRangeMoveSafe(
+ CheckedContiguousIterator<const int>(span.data(), span.data())));
+ EXPECT_FALSE(CheckedContiguousConstIterator<const int>::IsRangeMoveSafe(
span.cend(), span.cbegin(),
- CheckedRandomAccessConstIterator<const int>(span.data(), span.data())));
+ CheckedContiguousConstIterator<const int>(span.data(), span.data())));
+}
+
+TEST(SpanTest, Sort) {
+ int array[] = {5, 4, 3, 2, 1};
+
+ span<int> dynamic_span = array;
+ std::sort(dynamic_span.begin(), dynamic_span.end());
+ EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
+ std::sort(dynamic_span.rbegin(), dynamic_span.rend());
+ EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
+
+ span<int, 5> static_span = array;
+ std::sort(static_span.rbegin(), static_span.rend(), std::greater<>());
+ EXPECT_THAT(array, ElementsAre(1, 2, 3, 4, 5));
+ std::sort(static_span.begin(), static_span.end(), std::greater<>());
+ EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1));
+}
+
+TEST(SpanTest, IteratorConversions) {
+ static_assert(std::is_convertible<span<int>::iterator,
+ span<int>::const_iterator>::value,
+ "Error: iterator should be convertible to const_iterator");
+
+ static_assert(!std::is_convertible<span<int>::const_iterator,
+ span<int>::iterator>::value,
+ "Error: const_iterator should not be convertible to iterator");
}
} // namespace base