From: Nick Wolchko Date: Mon, 14 Aug 2017 19:49:06 +0000 (-0700) Subject: allow comparing Optional with none X-Git-Tag: v2017.08.21.00~16 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=23de25b883ac689625ace272d9d3136a2fc4a375;p=folly.git allow comparing Optional 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 --- diff --git a/folly/Optional.h b/folly/Optional.h index f8d39cb8..049251ba 100644 --- a/folly/Optional.h +++ b/folly/Optional.h @@ -228,11 +228,11 @@ class Optional { } Value* get_pointer() && = delete; - bool hasValue() const { + bool hasValue() const noexcept { return storage_.hasValue(); } - explicit operator bool() const { + explicit operator bool() const noexcept { return hasValue(); } @@ -319,7 +319,7 @@ class Optional { std::is_trivially_destructible::value, StorageTriviallyDestructible, StorageNonTriviallyDestructible>::type { - bool hasValue() const { + bool hasValue() const noexcept { return this->hasValue_; } @@ -461,6 +461,48 @@ bool operator>=(const V& other, const Optional&) = delete; template bool operator>(const V& other, const Optional&) = delete; +// Comparisons with none +template +bool operator==(const Optional& a, None) noexcept { + return !a.hasValue(); +} +template +bool operator==(None, const Optional& a) noexcept { + return !a.hasValue(); +} +template +bool operator<(const Optional&, None) noexcept { + return false; +} +template +bool operator<(None, const Optional& a) noexcept { + return a.hasValue(); +} +template +bool operator>(const Optional& a, None) noexcept { + return a.hasValue(); +} +template +bool operator>(None, const Optional&) noexcept { + return false; +} +template +bool operator<=(None, const Optional&) noexcept { + return true; +} +template +bool operator<=(const Optional& a, None) noexcept { + return !a.hasValue(); +} +template +bool operator>=(const Optional&, None) noexcept { + return true; +} +template +bool operator>=(None, const Optional& a) noexcept { + return !a.hasValue(); +} + /////////////////////////////////////////////////////////////////////////////// } // namespace folly diff --git a/folly/test/OptionalTest.cpp b/folly/test/OptionalTest.cpp index 365d8e41..990f1e17 100644 --- a/folly/test/OptionalTest.cpp +++ b/folly/test/OptionalTest.cpp @@ -450,6 +450,39 @@ TEST(Optional, HeterogeneousComparisons) { EXPECT_TRUE(opt8(4) >= opt64()); } +TEST(Optional, NoneComparisons) { + using opt = Optional; + 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) { Optional mbool; Optional mshort;