From 2c0384c4a2b033a644a6ddeb03b0e7666395abde Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 4 Jul 2023 13:58:36 -0500 Subject: [PATCH] Issue #2255 & #1240 - Simplify and enhance Maybe and Some(). https://bugzilla.mozilla.org/show_bug.cgi?id=1325351 This is a prerequisite for our BigInt V8 fast forward and potential #2255 fix. --- js/public/Proxy.h | 9 +++++++ mfbt/Maybe.h | 67 +++++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/js/public/Proxy.h b/js/public/Proxy.h index e493f522c6..981adc853c 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -588,6 +588,15 @@ class JS_FRIEND_API(AutoEnterPolicy) inline void recordLeave() {} #endif + private: + // This operator needs to be deleted explicitly, otherwise Visual C++ will + // create it automatically when it is part of the export JS API. In that + // case, compile would fail because HandleId is not allowed to be assigned + // and consequently instantiation of assign operator of mozilla::Maybe + // would fail. See bug 1325351 comment 16. Copy constructor is removed at + // the same time for consistency. + AutoEnterPolicy(const AutoEnterPolicy&) = delete; + AutoEnterPolicy& operator=(const AutoEnterPolicy&) = delete; }; #ifdef JS_DEBUG diff --git a/mfbt/Maybe.h b/mfbt/Maybe.h index 79df8d2518..bc123b047f 100644 --- a/mfbt/Maybe.h +++ b/mfbt/Maybe.h @@ -102,16 +102,11 @@ public: } /** - * Maybe can be copy-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. + * Maybe can be copy-constructed from a Maybe if U is convertible to T. */ template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> + typename std::enable_if::value>::type> MOZ_IMPLICIT Maybe(const Maybe& aOther) : mIsSome(false) @@ -131,16 +126,11 @@ public: } /** - * Maybe can be move-constructed from a Maybe if U* and T* are - * compatible, or from Maybe. + * Maybe can be move-constructed from a Maybe if U is convertible to T. */ template::value && - (std::is_same::value || - (std::is_pointer::value && - std::is_base_of::type, - typename std::remove_pointer::type>::value))>::type> + typename std::enable_if::value>::type> MOZ_IMPLICIT Maybe(Maybe&& aOther) : mIsSome(false) @@ -156,13 +146,7 @@ public: if (&aOther != this) { if (aOther.mIsSome) { if (mIsSome) { - // XXX(seth): The correct code for this branch, below, can't be used - // due to a bug in Visual Studio 2010. See bug 1052940. - /* ref() = aOther.ref(); - */ - reset(); - emplace(*aOther); } else { emplace(*aOther); } @@ -173,6 +157,23 @@ public: return *this; } + template::value>::type> + Maybe& operator=(const Maybe& aOther) + { + if (aOther.isSome()) { + if (mIsSome) { + ref() = aOther.ref(); + } else { + emplace(*aOther); + } + } else { + reset(); + } + return *this; + } + Maybe& operator=(Maybe&& aOther) { MOZ_ASSERT(this != &aOther, "Self-moves are prohibited"); @@ -191,6 +192,25 @@ public: return *this; } + template::value>::type> + Maybe& operator=(Maybe&& aOther) + { + if (aOther.isSome()) { + if (mIsSome) { + ref() = Move(aOther.ref()); + } else { + emplace(Move(*aOther)); + } + aOther.reset(); + } else { + reset(); + } + + return *this; + } + /* Methods that check whether this Maybe contains a value */ explicit operator bool() const { return isSome(); } bool isSome() const { return mIsSome; } @@ -443,11 +463,12 @@ public: * if you need to construct a Maybe value that holds a const, volatile, or * reference value, you need to use emplace() instead. */ -template -Maybe::Type>::Type> +template::type>::type> +Maybe Some(T&& aValue) { - typedef typename RemoveCV::Type>::Type U; Maybe value; value.emplace(Forward(aValue)); return value;