Add comparison operators to skstd::optional.
This involves a significant number of overloads, as optionals can be compared against other optionals, or nullopt, or a value; either side can mix and match as desired. Change-Id: I26b8420e417300d32569fc76a55bcfd8e01eb322 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/420576 Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
343588ddf0
commit
e2c4e7e62d
@ -173,6 +173,144 @@ private:
|
||||
bool fHasValue = false;
|
||||
};
|
||||
|
||||
// Comparison operators for optional x optional
|
||||
template <typename T, typename U> bool operator==(const optional<T>& a, const optional<U>& b) {
|
||||
return (a.has_value() != b.has_value()) ? false :
|
||||
!a.has_value() ? true :
|
||||
(*a == *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator!=(const optional<T>& a, const optional<U>& b) {
|
||||
return (a.has_value() != b.has_value()) ? true :
|
||||
!a.has_value() ? false :
|
||||
(*a != *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator<(const optional<T>& a, const optional<U>& b) {
|
||||
return !b.has_value() ? false :
|
||||
!a.has_value() ? true :
|
||||
(*a < *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator<=(const optional<T>& a, const optional<U>& b) {
|
||||
return !a.has_value() ? true :
|
||||
!b.has_value() ? false :
|
||||
(*a <= *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator>(const optional<T>& a, const optional<U>& b) {
|
||||
return !a.has_value() ? false :
|
||||
!b.has_value() ? true :
|
||||
(*a > *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator>=(const optional<T>& a, const optional<U>& b) {
|
||||
return !b.has_value() ? true :
|
||||
!a.has_value() ? false :
|
||||
(*a >= *b);
|
||||
}
|
||||
|
||||
// Comparison operators for optional x nullopt
|
||||
template <typename T> bool operator==(const optional<T>& a, nullopt_t) {
|
||||
return !a.has_value();
|
||||
}
|
||||
|
||||
template <typename T> bool operator!=(const optional<T>& a, nullopt_t) {
|
||||
return a.has_value();
|
||||
}
|
||||
|
||||
template <typename T> bool operator<(const optional<T>& a, nullopt_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T> bool operator<=(const optional<T>& a, nullopt_t) {
|
||||
return !a.has_value();
|
||||
}
|
||||
|
||||
template <typename T> bool operator>(const optional<T>& a, nullopt_t) {
|
||||
return a.has_value();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator>=(const optional<T>& a, nullopt_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Comparison operators for nullopt x optional
|
||||
template <typename U> bool operator==(nullopt_t, const optional<U>& b) {
|
||||
return !b.has_value();
|
||||
}
|
||||
|
||||
template <typename U> bool operator!=(nullopt_t, const optional<U>& b) {
|
||||
return b.has_value();
|
||||
}
|
||||
|
||||
template <typename U> bool operator<(nullopt_t, const optional<U>& b) {
|
||||
return b.has_value();
|
||||
}
|
||||
|
||||
template <typename U> bool operator<=(nullopt_t, const optional<U>& b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename U> bool operator>(nullopt_t, const optional<U>& b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename U> bool operator>=(nullopt_t, const optional<U>& b) {
|
||||
return !b.has_value();
|
||||
}
|
||||
|
||||
// Comparison operators for optional x value
|
||||
template <typename T, typename U> bool operator==(const optional<T>& a, const U& b) {
|
||||
return a.has_value() && (*a == b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator!=(const optional<T>& a, const U& b) {
|
||||
return !a.has_value() || (*a != b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator<(const optional<T>& a, const U& b) {
|
||||
return !a.has_value() || (*a < b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator<=(const optional<T>& a, const U& b) {
|
||||
return !a.has_value() || (*a <= b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator>(const optional<T>& a, const U& b) {
|
||||
return a.has_value() && (*a > b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator>=(const optional<T>& a, const U& b) {
|
||||
return a.has_value() && (*a >= b);
|
||||
}
|
||||
|
||||
// Comparison operators for value x optional
|
||||
template <typename T, typename U> bool operator==(const T& a, const optional<U>& b) {
|
||||
return b.has_value() && (a == *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator!=(const T& a, const optional<U>& b) {
|
||||
return !b.has_value() || (a != *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator<(const T& a, const optional<U>& b) {
|
||||
return b.has_value() && (a < *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator<=(const T& a, const optional<U>& b) {
|
||||
return b.has_value() && (a <= *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator>(const T& a, const optional<U>& b) {
|
||||
return !b.has_value() || (a > *b);
|
||||
}
|
||||
|
||||
template <typename T, typename U> bool operator>=(const T& a, const optional<U>& b) {
|
||||
return !b.has_value() || (a >= *b);
|
||||
}
|
||||
|
||||
} // namespace skstd
|
||||
|
||||
#endif
|
||||
|
@ -50,6 +50,84 @@ DEF_TEST(SkTOptionalNulloptReturn, r) {
|
||||
REPORTER_ASSERT(r, !o.has_value());
|
||||
}
|
||||
|
||||
DEF_TEST(SkTOptionalComparisons, r) {
|
||||
int v[] = { 1, 2, 3, 4, 5 };
|
||||
skstd::optional<int> o[] = {1, 2, skstd::nullopt, 4, 5};
|
||||
skstd::optional<int> five = 5;
|
||||
skstd::optional<int> six = 6;
|
||||
|
||||
for (int index = 0; index < (int)SK_ARRAY_COUNT(v); ++index) {
|
||||
REPORTER_ASSERT(r, v[index] < six);
|
||||
REPORTER_ASSERT(r, o[index] < six);
|
||||
REPORTER_ASSERT(r, six > v[index]);
|
||||
REPORTER_ASSERT(r, six > o[index]);
|
||||
|
||||
REPORTER_ASSERT(r, v[index] < 6);
|
||||
REPORTER_ASSERT(r, o[index] < 6);
|
||||
REPORTER_ASSERT(r, 6 > v[index]);
|
||||
REPORTER_ASSERT(r, 6 > o[index]);
|
||||
|
||||
REPORTER_ASSERT(r, !(six < v[index]));
|
||||
REPORTER_ASSERT(r, !(six < o[index]));
|
||||
REPORTER_ASSERT(r, !(v[index] > six));
|
||||
REPORTER_ASSERT(r, !(o[index] > six));
|
||||
|
||||
REPORTER_ASSERT(r, !(6 < v[index]));
|
||||
REPORTER_ASSERT(r, !(6 < o[index]));
|
||||
REPORTER_ASSERT(r, !(v[index] > 6));
|
||||
REPORTER_ASSERT(r, !(o[index] > 6));
|
||||
|
||||
REPORTER_ASSERT(r, v[index] <= five);
|
||||
REPORTER_ASSERT(r, o[index] <= five);
|
||||
REPORTER_ASSERT(r, five >= v[index]);
|
||||
REPORTER_ASSERT(r, five >= o[index]);
|
||||
|
||||
REPORTER_ASSERT(r, v[index] <= 5);
|
||||
REPORTER_ASSERT(r, o[index] <= 5);
|
||||
REPORTER_ASSERT(r, 5 >= v[index]);
|
||||
REPORTER_ASSERT(r, 5 >= o[index]);
|
||||
|
||||
REPORTER_ASSERT(r, skstd::nullopt <= o[index]);
|
||||
REPORTER_ASSERT(r, !(skstd::nullopt > o[index]));
|
||||
REPORTER_ASSERT(r, o[index] >= skstd::nullopt);
|
||||
REPORTER_ASSERT(r, !(o[index] < skstd::nullopt));
|
||||
|
||||
if (o[index].has_value()) {
|
||||
REPORTER_ASSERT(r, o[index] != skstd::nullopt);
|
||||
REPORTER_ASSERT(r, skstd::nullopt != o[index]);
|
||||
|
||||
REPORTER_ASSERT(r, o[index] == o[index]);
|
||||
REPORTER_ASSERT(r, o[index] != six);
|
||||
REPORTER_ASSERT(r, o[index] == v[index]);
|
||||
REPORTER_ASSERT(r, v[index] == o[index]);
|
||||
REPORTER_ASSERT(r, o[index] > 0);
|
||||
REPORTER_ASSERT(r, o[index] >= 1);
|
||||
REPORTER_ASSERT(r, o[index] <= 5);
|
||||
REPORTER_ASSERT(r, o[index] < 6);
|
||||
REPORTER_ASSERT(r, 0 < o[index]);
|
||||
REPORTER_ASSERT(r, 1 <= o[index]);
|
||||
REPORTER_ASSERT(r, 5 >= o[index]);
|
||||
REPORTER_ASSERT(r, 6 > o[index]);
|
||||
} else {
|
||||
REPORTER_ASSERT(r, o[index] == skstd::nullopt);
|
||||
REPORTER_ASSERT(r, skstd::nullopt == o[index]);
|
||||
|
||||
REPORTER_ASSERT(r, o[index] == o[index]);
|
||||
REPORTER_ASSERT(r, o[index] != five);
|
||||
REPORTER_ASSERT(r, o[index] != v[index]);
|
||||
REPORTER_ASSERT(r, v[index] != o[index]);
|
||||
REPORTER_ASSERT(r, o[index] < 0);
|
||||
REPORTER_ASSERT(r, o[index] <= 0);
|
||||
REPORTER_ASSERT(r, 0 > o[index]);
|
||||
REPORTER_ASSERT(r, 0 >= o[index]);
|
||||
REPORTER_ASSERT(r, !(o[index] > 0));
|
||||
REPORTER_ASSERT(r, !(o[index] >= 0));
|
||||
REPORTER_ASSERT(r, !(0 < o[index]));
|
||||
REPORTER_ASSERT(r, !(0 <= o[index]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SkTOptionalTestPayload {
|
||||
public:
|
||||
enum State {
|
||||
|
Loading…
Reference in New Issue
Block a user