Bug 1367674. P1 - add templates to deal with CV and argument number correctly. r=gerald
authorJW Wang <jwwang@mozilla.com>
Thu, 25 May 2017 15:41:01 +0800
changeset 409180 6dea98f4fbc27f19c3ab909bf9976b566236df1e
parent 409179 4541134e973a6bd5e667a603e844854c8e5361da
child 409181 02d43f8e8686d0b754f15e1b409366c0378ad591
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1367674
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1367674. P1 - add templates to deal with CV and argument number correctly. r=gerald 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