Bug 1367674. P1 - add templates to deal with CV and argument number correctly. draft
authorJW Wang <jwwang@mozilla.com>
Thu, 25 May 2017 15:41:01 +0800
changeset 585785 926de4e9d15680ca7cfaae5f0551c60e4a6b9fc3
parent 585728 7bca522f66fd781e01315f3baf76c7ece02bc546
child 585786 8028ae6800e20a6bb5a28574840e7937340ad4cb
push id61191
push userjwwang@mozilla.com
push dateMon, 29 May 2017 00:38:30 +0000
bugs1367674
milestone55.0a1
Bug 1367674. P1 - add templates to deal with CV and argument number correctly. MozReview-Commit-ID: 5qeSBDny6uc
xpcom/threads/MozPromise.h
--- 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