From 4b351b61294aee1643f4793598dd31381faa8801 Mon Sep 17 00:00:00 2001 From: Benjamin Jaeger Date: Fri, 8 Sep 2017 13:59:20 -0700 Subject: [PATCH] Optional.h - make == operators constexprs Summary: This more closely matches std optional and allows folly Optional to be a drop in replacement. Reviewed By: aary, yfeldblum Differential Revision: D5775541 fbshipit-source-id: f754c006429fa3c5a866b6b5ffdfd8883ec2dd4f --- folly/Optional.h | 84 +++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/folly/Optional.h b/folly/Optional.h index a57f065a..2693423d 100644 --- a/folly/Optional.h +++ b/folly/Optional.h @@ -104,7 +104,7 @@ class Optional { !std::is_abstract::value, "Optional may not be used with abstract types"); - Optional() noexcept {} + FOLLY_CPP14_CONSTEXPR Optional() noexcept {} Optional(const Optional& src) noexcept( std::is_nothrow_copy_constructible::value) { @@ -121,20 +121,20 @@ class Optional { } } - /* implicit */ Optional(const None&) noexcept {} + FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(const None&) noexcept {} - /* implicit */ Optional(Value&& newValue) noexcept( + FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(Value&& newValue) noexcept( std::is_nothrow_move_constructible::value) { storage_.construct(std::move(newValue)); } - /* implicit */ Optional(const Value& newValue) noexcept( + FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(const Value& newValue) noexcept( std::is_nothrow_copy_constructible::value) { storage_.construct(newValue); } template - explicit Optional(in_place_t, Args&&... args) noexcept( + FOLLY_CPP14_CONSTEXPR explicit Optional(in_place_t, Args&&... args) noexcept( std::is_nothrow_constructible::value) { storage_.construct(std::forward(args)...); } @@ -212,22 +212,22 @@ class Optional { storage_.clear(); } - const Value& value() const & { + FOLLY_CPP14_CONSTEXPR const Value& value() const & { require_value(); return *storage_.value_pointer(); } - Value& value() & { + FOLLY_CPP14_CONSTEXPR Value& value() & { require_value(); return *storage_.value_pointer(); } - Value&& value() && { + FOLLY_CPP14_CONSTEXPR Value&& value() && { require_value(); return std::move(*storage_.value_pointer()); } - const Value&& value() const && { + FOLLY_CPP14_CONSTEXPR const Value&& value() const && { require_value(); return std::move(*storage_.value_pointer()); } @@ -240,37 +240,37 @@ class Optional { } Value* get_pointer() && = delete; - bool hasValue() const noexcept { + FOLLY_CPP14_CONSTEXPR bool hasValue() const noexcept { return storage_.hasValue(); } - explicit operator bool() const noexcept { + FOLLY_CPP14_CONSTEXPR explicit operator bool() const noexcept { return hasValue(); } - const Value& operator*() const & { + FOLLY_CPP14_CONSTEXPR const Value& operator*() const & { return value(); } - Value& operator*() & { + FOLLY_CPP14_CONSTEXPR Value& operator*() & { return value(); } - const Value&& operator*() const && { + FOLLY_CPP14_CONSTEXPR const Value&& operator*() const && { return std::move(value()); } - Value&& operator*() && { + FOLLY_CPP14_CONSTEXPR Value&& operator*() && { return std::move(value()); } - const Value* operator->() const { + FOLLY_CPP14_CONSTEXPR const Value* operator->() const { return &value(); } - Value* operator->() { + FOLLY_CPP14_CONSTEXPR Value* operator->() { return &value(); } // Return a copy of the value if set, or a given default if not. template - Value value_or(U&& dflt) const & { + FOLLY_CPP14_CONSTEXPR Value value_or(U&& dflt) const & { if (storage_.hasValue()) { return *storage_.value_pointer(); } @@ -279,7 +279,7 @@ class Optional { } template - Value value_or(U&& dflt) && { + FOLLY_CPP14_CONSTEXPR Value value_or(U&& dflt) && { if (storage_.hasValue()) { return std::move(*storage_.value_pointer()); } @@ -386,7 +386,7 @@ void swap(Optional& a, Optional& b) { } template ::type>> -Opt make_optional(T&& v) { +constexpr Opt make_optional(T&& v) { return Opt(std::forward(v)); } @@ -394,27 +394,29 @@ Opt make_optional(T&& v) { // Comparisons. template -bool operator==(const Optional& a, const V& b) { +constexpr bool operator==(const Optional& a, const V& b) { return a.hasValue() && a.value() == b; } template -bool operator!=(const Optional& a, const V& b) { +constexpr bool operator!=(const Optional& a, const V& b) { return !(a == b); } template -bool operator==(const U& a, const Optional& b) { +constexpr bool operator==(const U& a, const Optional& b) { return b.hasValue() && b.value() == a; } template -bool operator!=(const U& a, const Optional& b) { +constexpr bool operator!=(const U& a, const Optional& b) { return !(a == b); } template -bool operator==(const Optional& a, const Optional& b) { +FOLLY_CPP14_CONSTEXPR bool operator==( + const Optional& a, + const Optional& b) { if (a.hasValue() != b.hasValue()) { return false; } @@ -425,12 +427,14 @@ bool operator==(const Optional& a, const Optional& b) { } template -bool operator!=(const Optional& a, const Optional& b) { +constexpr bool operator!=(const Optional& a, const Optional& b) { return !(a == b); } template -bool operator<(const Optional& a, const Optional& b) { +FOLLY_CPP14_CONSTEXPR bool operator<( + const Optional& a, + const Optional& b) { if (a.hasValue() != b.hasValue()) { return a.hasValue() < b.hasValue(); } @@ -441,17 +445,17 @@ bool operator<(const Optional& a, const Optional& b) { } template -bool operator>(const Optional& a, const Optional& b) { +constexpr bool operator>(const Optional& a, const Optional& b) { return b < a; } template -bool operator<=(const Optional& a, const Optional& b) { +constexpr bool operator<=(const Optional& a, const Optional& b) { return !(b < a); } template -bool operator>=(const Optional& a, const Optional& b) { +constexpr bool operator>=(const Optional& a, const Optional& b) { return !(a < b); } @@ -475,43 +479,43 @@ bool operator>(const V& other, const Optional&) = delete; // Comparisons with none template -bool operator==(const Optional& a, None) noexcept { +constexpr bool operator==(const Optional& a, None) noexcept { return !a.hasValue(); } template -bool operator==(None, const Optional& a) noexcept { +constexpr bool operator==(None, const Optional& a) noexcept { return !a.hasValue(); } template -bool operator<(const Optional&, None) noexcept { +constexpr bool operator<(const Optional&, None) noexcept { return false; } template -bool operator<(None, const Optional& a) noexcept { +constexpr bool operator<(None, const Optional& a) noexcept { return a.hasValue(); } template -bool operator>(const Optional& a, None) noexcept { +constexpr bool operator>(const Optional& a, None) noexcept { return a.hasValue(); } template -bool operator>(None, const Optional&) noexcept { +constexpr bool operator>(None, const Optional&) noexcept { return false; } template -bool operator<=(None, const Optional&) noexcept { +constexpr bool operator<=(None, const Optional&) noexcept { return true; } template -bool operator<=(const Optional& a, None) noexcept { +constexpr bool operator<=(const Optional& a, None) noexcept { return !a.hasValue(); } template -bool operator>=(const Optional&, None) noexcept { +constexpr bool operator>=(const Optional&, None) noexcept { return true; } template -bool operator>=(None, const Optional& a) noexcept { +constexpr bool operator>=(None, const Optional& a) noexcept { return !a.hasValue(); } -- 2.34.1