Bug 1363676. P1 - use Variant as the internal storage of ResolveOrRejectValue.
MozReview-Commit-ID: 4B3M3hvfvyz
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -10,16 +10,17 @@
#include "mozilla/AbstractThread.h"
#include "mozilla/IndexSequence.h"
#include "mozilla/Logging.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
#include "mozilla/Monitor.h"
#include "mozilla/Tuple.h"
#include "mozilla/TypeTraits.h"
+#include "mozilla/Variant.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
#if defined(DEBUG) || !defined(RELEASE_OR_BETA)
#define PROMISE_DEBUG
#endif
@@ -132,29 +133,42 @@ class MozPromise : public MozPromiseRefc
{
static const uint32_t sMagic = 0xcecace11;
public:
typedef ResolveValueT ResolveValueType;
typedef RejectValueT RejectValueType;
class ResolveOrRejectValue
{
+ template <int, typename T>
+ struct Holder
+ {
+ template <typename... Args>
+ explicit Holder(Args&&... aArgs) : mData(Forward<Args>(aArgs)...) { }
+ T mData;
+ };
+
+ // Ensure Holder<0, T1> and Holder<1, T2> are different types
+ // which is required by Variant.
+ using ResolveValueHolder = Holder<0, ResolveValueType>;
+ using RejectValueHolder = Holder<1, RejectValueType>;
+
public:
template<typename ResolveValueType_>
void SetResolve(ResolveValueType_&& aResolveValue)
{
MOZ_ASSERT(IsNothing());
- mResolveValue.emplace(Forward<ResolveValueType_>(aResolveValue));
+ mValue = AsVariant(ResolveValueHolder(Forward<ResolveValueType_>(aResolveValue)));
}
template<typename RejectValueType_>
void SetReject(RejectValueType_&& aRejectValue)
{
MOZ_ASSERT(IsNothing());
- mRejectValue.emplace(Forward<RejectValueType_>(aRejectValue));
+ mValue = AsVariant(RejectValueHolder(Forward<RejectValueType_>(aRejectValue)));
}
template<typename ResolveValueType_>
static ResolveOrRejectValue MakeResolve(ResolveValueType_&& aResolveValue)
{
ResolveOrRejectValue val;
val.SetResolve(Forward<ResolveValueType_>(aResolveValue));
return val;
@@ -163,26 +177,39 @@ public:
template<typename RejectValueType_>
static ResolveOrRejectValue MakeReject(RejectValueType_&& aRejectValue)
{
ResolveOrRejectValue val;
val.SetReject(Forward<RejectValueType_>(aRejectValue));
return val;
}
- bool IsResolve() const { return mResolveValue.isSome(); }
- bool IsReject() const { return mRejectValue.isSome(); }
- bool IsNothing() const { return mResolveValue.isNothing() && mRejectValue.isNothing(); }
+ bool IsResolve() const { return mValue.template is<ResolveValueHolder>(); }
+ bool IsReject() const { return mValue.template is<RejectValueHolder>(); }
+ bool IsNothing() const { return mValue.template is<Nothing>(); }
- const ResolveValueType& ResolveValue() const { return mResolveValue.ref(); }
- const RejectValueType& RejectValue() const { return mRejectValue.ref(); }
+ const ResolveValueType& ResolveValue() const
+ {
+ return mValue.template as<ResolveValueHolder>().mData;
+ }
+ ResolveValueType& ResolveValue()
+ {
+ return mValue.template as<ResolveValueHolder>().mData;
+ }
+ const RejectValueType& RejectValue() const
+ {
+ return mValue.template as<RejectValueHolder>().mData;
+ }
+ RejectValueType& RejectValue()
+ {
+ return mValue.template as<RejectValueHolder>().mData;
+ }
private:
- Maybe<ResolveValueType> mResolveValue;
- Maybe<RejectValueType> mRejectValue;
+ Variant<Nothing, ResolveValueHolder, RejectValueHolder> mValue = AsVariant(Nothing{});
};
protected:
// MozPromise is the public type, and never constructed directly. Construct
// a MozPromise::Private, defined below.
MozPromise(const char* aCreationSite, bool aIsCompletionPromise)
: mCreationSite(aCreationSite)
, mMutex("MozPromise Mutex")