Commit 23de25b8 authored by Nick Wolchko's avatar Nick Wolchko Committed by Facebook Github Bot

allow comparing Optional<T> with none

Summary:
`std::optional` supports comparing with `std::nullopt`, so
`folly::Optional` should do the same with `folly::none`.
This also involves marking hasValue() noexcept to be the same as `std::optional`.

Reviewed By: yfeldblum, WillerZ

Differential Revision: D5617825

fbshipit-source-id: a4b863dd61c3a86223fb21a5b7759e7c295fd272
parent 7289b921
...@@ -228,11 +228,11 @@ class Optional { ...@@ -228,11 +228,11 @@ class Optional {
} }
Value* get_pointer() && = delete; Value* get_pointer() && = delete;
bool hasValue() const { bool hasValue() const noexcept {
return storage_.hasValue(); return storage_.hasValue();
} }
explicit operator bool() const { explicit operator bool() const noexcept {
return hasValue(); return hasValue();
} }
...@@ -319,7 +319,7 @@ class Optional { ...@@ -319,7 +319,7 @@ class Optional {
std::is_trivially_destructible<Value>::value, std::is_trivially_destructible<Value>::value,
StorageTriviallyDestructible, StorageTriviallyDestructible,
StorageNonTriviallyDestructible>::type { StorageNonTriviallyDestructible>::type {
bool hasValue() const { bool hasValue() const noexcept {
return this->hasValue_; return this->hasValue_;
} }
...@@ -461,6 +461,48 @@ bool operator>=(const V& other, const Optional<V>&) = delete; ...@@ -461,6 +461,48 @@ bool operator>=(const V& other, const Optional<V>&) = delete;
template <class V> template <class V>
bool operator>(const V& other, const Optional<V>&) = delete; bool operator>(const V& other, const Optional<V>&) = delete;
// Comparisons with none
template <class V>
bool operator==(const Optional<V>& a, None) noexcept {
return !a.hasValue();
}
template <class V>
bool operator==(None, const Optional<V>& a) noexcept {
return !a.hasValue();
}
template <class V>
bool operator<(const Optional<V>&, None) noexcept {
return false;
}
template <class V>
bool operator<(None, const Optional<V>& a) noexcept {
return a.hasValue();
}
template <class V>
bool operator>(const Optional<V>& a, None) noexcept {
return a.hasValue();
}
template <class V>
bool operator>(None, const Optional<V>&) noexcept {
return false;
}
template <class V>
bool operator<=(None, const Optional<V>&) noexcept {
return true;
}
template <class V>
bool operator<=(const Optional<V>& a, None) noexcept {
return !a.hasValue();
}
template <class V>
bool operator>=(const Optional<V>&, None) noexcept {
return true;
}
template <class V>
bool operator>=(None, const Optional<V>& a) noexcept {
return !a.hasValue();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
} // namespace folly } // namespace folly
......
...@@ -450,6 +450,39 @@ TEST(Optional, HeterogeneousComparisons) { ...@@ -450,6 +450,39 @@ TEST(Optional, HeterogeneousComparisons) {
EXPECT_TRUE(opt8(4) >= opt64()); EXPECT_TRUE(opt8(4) >= opt64());
} }
TEST(Optional, NoneComparisons) {
using opt = Optional<int>;
EXPECT_TRUE(opt() == none);
EXPECT_TRUE(none == opt());
EXPECT_FALSE(opt(1) == none);
EXPECT_FALSE(none == opt(1));
EXPECT_FALSE(opt() != none);
EXPECT_FALSE(none != opt());
EXPECT_TRUE(opt(1) != none);
EXPECT_TRUE(none != opt(1));
EXPECT_FALSE(opt() < none);
EXPECT_FALSE(none < opt());
EXPECT_FALSE(opt(1) < none);
EXPECT_TRUE(none < opt(1));
EXPECT_FALSE(opt() > none);
EXPECT_FALSE(none > opt());
EXPECT_FALSE(none > opt(1));
EXPECT_TRUE(opt(1) > none);
EXPECT_TRUE(opt() <= none);
EXPECT_TRUE(none <= opt());
EXPECT_FALSE(opt(1) <= none);
EXPECT_TRUE(none <= opt(1));
EXPECT_TRUE(opt() >= none);
EXPECT_TRUE(none >= opt());
EXPECT_TRUE(opt(1) >= none);
EXPECT_FALSE(none >= opt(1));
}
TEST(Optional, Conversions) { TEST(Optional, Conversions) {
Optional<bool> mbool; Optional<bool> mbool;
Optional<short> mshort; Optional<short> mshort;
......
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