diff options
author | Brian Smith <brian@dbsoft.org> | 2023-07-04 13:58:36 -0500 |
---|---|---|
committer | Brian Smith <brian@dbsoft.org> | 2023-07-04 13:58:36 -0500 |
commit | d9c5b3bde58bf8d71a71473ded232c892b20a1c2 (patch) | |
tree | bcaec5b16e0f8e2885c70ddfe46a09918cd70fc4 /mfbt | |
parent | b3f6b7a224449f0babe1c4753b25daa2665c0331 (diff) | |
download | uxp-d9c5b3bde58bf8d71a71473ded232c892b20a1c2.tar.gz |
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.
Diffstat (limited to 'mfbt')
-rw-r--r-- | mfbt/Maybe.h | 67 |
1 files changed, 44 insertions, 23 deletions
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<T*> can be copy-constructed from a Maybe<U*> if U* and T* are - * compatible, or from Maybe<decltype(nullptr)>. + * Maybe<T> can be copy-constructed from a Maybe<U> if U is convertible to T. */ template<typename U, typename = - typename std::enable_if<std::is_pointer<T>::value && - (std::is_same<U, decltype(nullptr)>::value || - (std::is_pointer<U>::value && - std::is_base_of<typename std::remove_pointer<T>::type, - typename std::remove_pointer<U>::type>::value))>::type> + typename std::enable_if<std::is_convertible<U, T>::value>::type> MOZ_IMPLICIT Maybe(const Maybe<U>& aOther) : mIsSome(false) @@ -131,16 +126,11 @@ public: } /** - * Maybe<T*> can be move-constructed from a Maybe<U*> if U* and T* are - * compatible, or from Maybe<decltype(nullptr)>. + * Maybe<T> can be move-constructed from a Maybe<U> if U is convertible to T. */ template<typename U, typename = - typename std::enable_if<std::is_pointer<T>::value && - (std::is_same<U, decltype(nullptr)>::value || - (std::is_pointer<U>::value && - std::is_base_of<typename std::remove_pointer<T>::type, - typename std::remove_pointer<U>::type>::value))>::type> + typename std::enable_if<std::is_convertible<U, T>::value>::type> MOZ_IMPLICIT Maybe(Maybe<U>&& 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<typename U, + typename = + typename std::enable_if<std::is_convertible<U, T>::value>::type> + Maybe& operator=(const Maybe<U>& 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<typename U, + typename = + typename std::enable_if<std::is_convertible<U, T>::value>::type> + Maybe& operator=(Maybe<U>&& 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<typename T> -Maybe<typename RemoveCV<typename RemoveReference<T>::Type>::Type> +template<typename T, + typename U = typename std::remove_cv< + typename std::remove_reference<T>::type>::type> +Maybe<U> Some(T&& aValue) { - typedef typename RemoveCV<typename RemoveReference<T>::Type>::Type U; Maybe<U> value; value.emplace(Forward<T>(aValue)); return value; |