Bug 1367674. P1 - add templates to deal with CV and argument number correctly.
MozReview-Commit-ID: 5qeSBDny6uc
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -33,16 +33,49 @@
namespace mozilla {
extern LazyLogModule gMozPromiseLog;
#define PROMISE_LOG(x, ...) \
MOZ_LOG(gMozPromiseLog, mozilla::LogLevel::Debug, (x, ##__VA_ARGS__))
namespace detail {
+template <typename F>
+struct MethodTraitsHelper : MethodTraitsHelper<decltype(&F::operator())>
+{
+};
+template <typename ThisType, typename Ret, typename... ArgTypes>
+struct MethodTraitsHelper<Ret(ThisType::*)(ArgTypes...)>
+{
+ using ReturnType = Ret;
+ static const size_t ArgSize = sizeof...(ArgTypes);
+};
+template <typename ThisType, typename Ret, typename... ArgTypes>
+struct MethodTraitsHelper<Ret(ThisType::*)(ArgTypes...) const>
+{
+ using ReturnType = Ret;
+ static const size_t ArgSize = sizeof...(ArgTypes);
+};
+template <typename ThisType, typename Ret, typename... ArgTypes>
+struct MethodTraitsHelper<Ret(ThisType::*)(ArgTypes...) volatile>
+{
+ using ReturnType = Ret;
+ static const size_t ArgSize = sizeof...(ArgTypes);
+};
+template <typename ThisType, typename Ret, typename... ArgTypes>
+struct MethodTraitsHelper<Ret(ThisType::*)(ArgTypes...) const volatile>
+{
+ using ReturnType = Ret;
+ static const size_t ArgSize = sizeof...(ArgTypes);
+};
+template <typename T>
+struct MethodTrait : MethodTraitsHelper<typename RemoveReference<T>::Type>
+{
+};
+
template<typename ThisType, typename Ret, typename ArgType>
static TrueType TakesArgumentHelper(Ret (ThisType::*)(ArgType));
template<typename ThisType, typename Ret, typename ArgType>
static TrueType TakesArgumentHelper(Ret (ThisType::*)(ArgType) const);
template<typename ThisType, typename Ret>
static FalseType TakesArgumentHelper(Ret (ThisType::*)());
template<typename ThisType, typename Ret>
static FalseType TakesArgumentHelper(Ret (ThisType::*)() const);
@@ -52,31 +85,30 @@ static Ret ReturnTypeHelper(Ret (ThisTyp
template<typename ThisType, typename Ret, typename ArgType>
static Ret ReturnTypeHelper(Ret (ThisType::*)(ArgType) const);
template<typename ThisType, typename Ret>
static Ret ReturnTypeHelper(Ret (ThisType::*)());
template<typename ThisType, typename Ret>
static Ret ReturnTypeHelper(Ret (ThisType::*)() const);
template<typename MethodType>
-struct ReturnType {
- typedef decltype(detail::ReturnTypeHelper(DeclVal<MethodType>())) Type;
+struct ReturnType
+{
+ using Type = typename MethodTrait<MethodType>::ReturnType;
};
} // namespace detail
template<typename MethodType>
-struct TakesArgument {
- static const bool value = decltype(detail::TakesArgumentHelper(DeclVal<MethodType>()))::value;
-};
+using TakesArgument =
+ IntegralConstant<bool, detail::MethodTrait<MethodType>::ArgSize != 0>;
template<typename MethodType, typename TargetType>
-struct ReturnTypeIs {
- static const bool value = IsConvertible<typename detail::ReturnType<MethodType>::Type, TargetType>::value;
-};
+using ReturnTypeIs =
+ IsConvertible<typename detail::MethodTrait<MethodType>::ReturnType, TargetType>;
/*
* A promise manages an asynchronous request that may or may not be able to be
* fulfilled immediately. When an API returns a promise, the consumer may attach
* callbacks to be invoked (asynchronously, on a specified thread) when the
* request is either completed (resolved) or cannot be completed (rejected).
* Whereas JS promise callbacks are dispatched from Microtask checkpoints,
* MozPromises resolution/rejection make a normal round-trip through the event