summaryrefslogtreecommitdiff
path: root/mfbt
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-07-04 13:58:36 -0500
committerBrian Smith <brian@dbsoft.org>2023-07-04 13:58:36 -0500
commitd9c5b3bde58bf8d71a71473ded232c892b20a1c2 (patch)
treebcaec5b16e0f8e2885c70ddfe46a09918cd70fc4 /mfbt
parentb3f6b7a224449f0babe1c4753b25daa2665c0331 (diff)
downloaduxp-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.h67
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;