Commit 405745c9 authored by jdoerrie's avatar jdoerrie Committed by Commit Bot

[base] Allow Comparisons of Spans Across Types

This change implements comparisons of base::spans with different types.
This is useful to compare spans that only differ in their cv qualifiers,
or whose different types allow comparison (e.g. int and double or
std::string and base::StringPiece).

Comparisons across types is a recent addition to the std::span proposal
and was not part of P0122R6.

Bug: 828324
Change-Id: Ia65a027c6b4a141f1a6dad11ba1d7699c7ed6f8c
Reviewed-on: https://chromium-review.googlesource.com/1006580Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550172}
parent 79605d54
...@@ -272,34 +272,34 @@ class span { ...@@ -272,34 +272,34 @@ class span {
// [span.comparison], span comparison operators // [span.comparison], span comparison operators
// Relational operators. Equality is a element-wise comparison. // Relational operators. Equality is a element-wise comparison.
template <typename T> template <typename T, typename U>
constexpr bool operator==(span<T> lhs, span<T> rhs) noexcept { constexpr bool operator==(span<T> lhs, span<U> rhs) noexcept {
return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend()); return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
} }
template <typename T> template <typename T, typename U>
constexpr bool operator!=(span<T> lhs, span<T> rhs) noexcept { constexpr bool operator!=(span<T> lhs, span<U> rhs) noexcept {
return !(lhs == rhs); return !(lhs == rhs);
} }
template <typename T> template <typename T, typename U>
constexpr bool operator<(span<T> lhs, span<T> rhs) noexcept { constexpr bool operator<(span<T> lhs, span<U> rhs) noexcept {
return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(),
rhs.cend()); rhs.cend());
} }
template <typename T> template <typename T, typename U>
constexpr bool operator<=(span<T> lhs, span<T> rhs) noexcept { constexpr bool operator<=(span<T> lhs, span<U> rhs) noexcept {
return !(rhs < lhs); return !(rhs < lhs);
} }
template <typename T> template <typename T, typename U>
constexpr bool operator>(span<T> lhs, span<T> rhs) noexcept { constexpr bool operator>(span<T> lhs, span<U> rhs) noexcept {
return rhs < lhs; return rhs < lhs;
} }
template <typename T> template <typename T, typename U>
constexpr bool operator>=(span<T> lhs, span<T> rhs) noexcept { constexpr bool operator>=(span<T> lhs, span<U> rhs) noexcept {
return !(lhs < rhs); return !(lhs < rhs);
} }
......
...@@ -367,6 +367,11 @@ TEST(SpanTest, Equality) { ...@@ -367,6 +367,11 @@ TEST(SpanTest, Equality) {
constexpr span<const int> span3(kArray3); constexpr span<const int> span3(kArray3);
EXPECT_FALSE(span1 == span3); EXPECT_FALSE(span1 == span3);
static double kArray4[] = {2.0, 7.0, 1.0, 8.0, 3.0};
span<double> span4(kArray4);
EXPECT_EQ(span3, span4);
} }
TEST(SpanTest, Inequality) { TEST(SpanTest, Inequality) {
...@@ -381,6 +386,11 @@ TEST(SpanTest, Inequality) { ...@@ -381,6 +386,11 @@ TEST(SpanTest, Inequality) {
constexpr span<const int> span3(kArray3); constexpr span<const int> span3(kArray3);
EXPECT_FALSE(span1 != span3); EXPECT_FALSE(span1 != span3);
static double kArray4[] = {1.0, 4.0, 6.0, 8.0, 9.0};
span<double> span4(kArray4);
EXPECT_NE(span3, span4);
} }
TEST(SpanTest, LessThan) { TEST(SpanTest, LessThan) {
...@@ -395,6 +405,11 @@ TEST(SpanTest, LessThan) { ...@@ -395,6 +405,11 @@ TEST(SpanTest, LessThan) {
constexpr span<const int> span3(kArray3); constexpr span<const int> span3(kArray3);
EXPECT_FALSE(span1 < span3); EXPECT_FALSE(span1 < span3);
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
span<double> span4(kArray4);
EXPECT_LT(span3, span4);
} }
TEST(SpanTest, LessEqual) { TEST(SpanTest, LessEqual) {
...@@ -410,6 +425,11 @@ TEST(SpanTest, LessEqual) { ...@@ -410,6 +425,11 @@ TEST(SpanTest, LessEqual) {
constexpr span<const int> span3(kArray3); constexpr span<const int> span3(kArray3);
EXPECT_FALSE(span1 <= span3); EXPECT_FALSE(span1 <= span3);
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
span<double> span4(kArray4);
EXPECT_LE(span3, span4);
} }
TEST(SpanTest, GreaterThan) { TEST(SpanTest, GreaterThan) {
...@@ -424,6 +444,11 @@ TEST(SpanTest, GreaterThan) { ...@@ -424,6 +444,11 @@ TEST(SpanTest, GreaterThan) {
constexpr span<const int> span3(kArray3); constexpr span<const int> span3(kArray3);
EXPECT_FALSE(span1 > span3); EXPECT_FALSE(span1 > span3);
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
span<double> span4(kArray4);
EXPECT_GT(span3, span4);
} }
TEST(SpanTest, GreaterEqual) { TEST(SpanTest, GreaterEqual) {
...@@ -439,6 +464,11 @@ TEST(SpanTest, GreaterEqual) { ...@@ -439,6 +464,11 @@ TEST(SpanTest, GreaterEqual) {
constexpr span<const int> span3(kArray3); constexpr span<const int> span3(kArray3);
EXPECT_FALSE(span1 >= span3); EXPECT_FALSE(span1 >= span3);
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
span<double> span4(kArray4);
EXPECT_GE(span3, span4);
} }
TEST(SpanTest, AsBytes) { TEST(SpanTest, AsBytes) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment