--- a/xpcom/glue/nsThreadUtils.h
+++ b/xpcom/glue/nsThreadUtils.h
@@ -13,17 +13,19 @@
#include "nsIThreadManager.h"
#include "nsIThread.h"
#include "nsIRunnable.h"
#include "nsICancelableRunnable.h"
#include "nsStringGlue.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "mozilla/Atomics.h"
+#include "mozilla/IndexSequence.h"
#include "mozilla/Likely.h"
+#include "mozilla/Tuple.h"
#include "mozilla/TypeTraits.h"
//-----------------------------------------------------------------------------
// These methods are alternatives to the methods on nsIThreadManager, provided
// for convenience.
/**
* Set name of the target thread. This operation is asynchronous.
@@ -364,157 +366,157 @@ struct IsParameterStorageClass : public
template<typename T>
struct StoreCopyPassByValue
{
typedef T stored_type;
typedef T passed_type;
stored_type m;
template <typename A>
- explicit StoreCopyPassByValue(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StoreCopyPassByValue(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StoreCopyPassByValue<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreCopyPassByConstLRef
{
typedef T stored_type;
typedef const T& passed_type;
stored_type m;
template <typename A>
- explicit StoreCopyPassByConstLRef(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StoreCopyPassByConstLRef(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StoreCopyPassByConstLRef<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreCopyPassByLRef
{
typedef T stored_type;
typedef T& passed_type;
stored_type m;
template <typename A>
- explicit StoreCopyPassByLRef(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StoreCopyPassByLRef(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StoreCopyPassByLRef<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreCopyPassByRRef
{
typedef T stored_type;
typedef T&& passed_type;
stored_type m;
template <typename A>
- explicit StoreCopyPassByRRef(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StoreCopyPassByRRef(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return mozilla::Move(m); }
};
template<typename S>
struct IsParameterStorageClass<StoreCopyPassByRRef<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreRefPassByLRef
{
typedef T& stored_type;
typedef T& passed_type;
stored_type m;
template <typename A>
- explicit StoreRefPassByLRef(A& a) : m(a) {}
+ MOZ_IMPLICIT StoreRefPassByLRef(A& a) : m(a) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StoreRefPassByLRef<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreConstRefPassByConstLRef
{
typedef const T& stored_type;
typedef const T& passed_type;
stored_type m;
template <typename A>
- explicit StoreConstRefPassByConstLRef(const A& a) : m(a) {}
+ MOZ_IMPLICIT StoreConstRefPassByConstLRef(const A& a) : m(a) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StoreConstRefPassByConstLRef<S>>
: public mozilla::TrueType {};
template<typename T>
struct StorensRefPtrPassByPtr
{
typedef RefPtr<T> stored_type;
typedef T* passed_type;
stored_type m;
template <typename A>
- explicit StorensRefPtrPassByPtr(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StorensRefPtrPassByPtr(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return m.get(); }
};
template<typename S>
struct IsParameterStorageClass<StorensRefPtrPassByPtr<S>>
: public mozilla::TrueType {};
template<typename T>
struct StorePtrPassByPtr
{
typedef T* stored_type;
typedef T* passed_type;
stored_type m;
template <typename A>
- explicit StorePtrPassByPtr(A a) : m(a) {}
+ MOZ_IMPLICIT StorePtrPassByPtr(A a) : m(a) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StorePtrPassByPtr<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreConstPtrPassByConstPtr
{
typedef const T* stored_type;
typedef const T* passed_type;
stored_type m;
template <typename A>
- explicit StoreConstPtrPassByConstPtr(A a) : m(a) {}
+ MOZ_IMPLICIT StoreConstPtrPassByConstPtr(A a) : m(a) {}
passed_type PassAsParameter() { return m; }
};
template<typename S>
struct IsParameterStorageClass<StoreConstPtrPassByConstPtr<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreCopyPassByConstPtr
{
typedef T stored_type;
typedef const T* passed_type;
stored_type m;
template <typename A>
- explicit StoreCopyPassByConstPtr(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StoreCopyPassByConstPtr(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return &m; }
};
template<typename S>
struct IsParameterStorageClass<StoreCopyPassByConstPtr<S>>
: public mozilla::TrueType {};
template<typename T>
struct StoreCopyPassByPtr
{
typedef T stored_type;
typedef T* passed_type;
stored_type m;
template <typename A>
- explicit StoreCopyPassByPtr(A&& a) : m(mozilla::Forward<A>(a)) {}
+ MOZ_IMPLICIT StoreCopyPassByPtr(A&& a) : m(mozilla::Forward<A>(a)) {}
passed_type PassAsParameter() { return &m; }
};
template<typename S>
struct IsParameterStorageClass<StoreCopyPassByPtr<S>>
: public mozilla::TrueType {};
namespace detail {
@@ -646,206 +648,38 @@ struct ParameterStorage
: mozilla::Conditional<IsParameterStorageClass<T>::value,
T,
typename NonParameterStorageClass<T>::Type>
{};
} /* namespace detail */
// struct used to store arguments and later apply them to a method.
-template <typename... Ts> struct nsRunnableMethodArguments;
-
-// Specializations for 0-8 arguments, add more as required.
-// TODO Use tuple instead; And/or use lambdas (see bug 1152753)
-template <>
-struct nsRunnableMethodArguments<>
-{
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)();
- }
-};
-template <typename T0>
-struct nsRunnableMethodArguments<T0>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- template<typename A0>
- explicit nsRunnableMethodArguments(A0&& a0)
- : m0(mozilla::Forward<A0>(a0))
- {}
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)(m0.PassAsParameter());
- }
-};
-template <typename T0, typename T1>
-struct nsRunnableMethodArguments<T0, T1>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- template<typename A0, typename A1>
- nsRunnableMethodArguments(A0&& a0, A1&& a1)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- {}
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter());
- }
-};
-template <typename T0, typename T1, typename T2>
-struct nsRunnableMethodArguments<T0, T1, T2>
+template <typename... Ts>
+struct nsRunnableMethodArguments
{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- typename ::detail::ParameterStorage<T2>::Type m2;
- template<typename A0, typename A1, typename A2>
- nsRunnableMethodArguments(A0&& a0, A1&& a1, A2&& a2)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- , m2(mozilla::Forward<A2>(a2))
+ mozilla::Tuple<typename ::detail::ParameterStorage<Ts>::Type...> mArguments;
+ template <typename... As>
+ explicit nsRunnableMethodArguments(As&&... aArguments)
+ : mArguments(mozilla::Forward<As>(aArguments)...)
{}
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter(), m2.PassAsParameter());
- }
-};
-template <typename T0, typename T1, typename T2, typename T3>
-struct nsRunnableMethodArguments<T0, T1, T2, T3>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- typename ::detail::ParameterStorage<T2>::Type m2;
- typename ::detail::ParameterStorage<T3>::Type m3;
- template<typename A0, typename A1, typename A2, typename A3>
- nsRunnableMethodArguments(A0&& a0, A1&& a1, A2&& a2, A3&& a3)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- , m2(mozilla::Forward<A2>(a2))
- , m3(mozilla::Forward<A3>(a3))
- {}
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter(),
- m2.PassAsParameter(), m3.PassAsParameter());
- }
-};
-template <typename T0, typename T1, typename T2, typename T3, typename T4>
-struct nsRunnableMethodArguments<T0, T1, T2, T3, T4>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- typename ::detail::ParameterStorage<T2>::Type m2;
- typename ::detail::ParameterStorage<T3>::Type m3;
- typename ::detail::ParameterStorage<T4>::Type m4;
- template<typename A0, typename A1, typename A2, typename A3, typename A4>
- nsRunnableMethodArguments(A0&& a0, A1&& a1, A2&& a2, A3&& a3, A4&& a4)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- , m2(mozilla::Forward<A2>(a2))
- , m3(mozilla::Forward<A3>(a3))
- , m4(mozilla::Forward<A4>(a4))
- {}
- template<class C, typename M> void apply(C* o, M m)
+ template<typename C, typename M, typename... Args, size_t... Indices>
+ static auto
+ applyImpl(C* o, M m, mozilla::Tuple<Args...>& args,
+ mozilla::IndexSequence<Indices...>)
+ -> decltype(((*o).*m)(mozilla::Get<Indices>(args).PassAsParameter()...))
{
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter(),
- m2.PassAsParameter(), m3.PassAsParameter(),
- m4.PassAsParameter());
- }
-};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5>
-struct nsRunnableMethodArguments<T0, T1, T2, T3, T4, T5>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- typename ::detail::ParameterStorage<T2>::Type m2;
- typename ::detail::ParameterStorage<T3>::Type m3;
- typename ::detail::ParameterStorage<T4>::Type m4;
- typename ::detail::ParameterStorage<T5>::Type m5;
- template<typename A0, typename A1, typename A2, typename A3, typename A4,
- typename A5>
- nsRunnableMethodArguments(A0&& a0, A1&& a1, A2&& a2, A3&& a3, A4&& a4,
- A5&& a5)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- , m2(mozilla::Forward<A2>(a2))
- , m3(mozilla::Forward<A3>(a3))
- , m4(mozilla::Forward<A4>(a4))
- , m5(mozilla::Forward<A5>(a5))
- {}
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter(),
- m2.PassAsParameter(), m3.PassAsParameter(),
- m4.PassAsParameter(), m5.PassAsParameter());
+ return ((*o).*m)(mozilla::Get<Indices>(args).PassAsParameter()...);
}
-};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6>
-struct nsRunnableMethodArguments<T0, T1, T2, T3, T4, T5, T6>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- typename ::detail::ParameterStorage<T2>::Type m2;
- typename ::detail::ParameterStorage<T3>::Type m3;
- typename ::detail::ParameterStorage<T4>::Type m4;
- typename ::detail::ParameterStorage<T5>::Type m5;
- typename ::detail::ParameterStorage<T6>::Type m6;
- template<typename A0, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
- nsRunnableMethodArguments(A0&& a0, A1&& a1, A2&& a2, A3&& a3, A4&& a4,
- A5&& a5, A6&& a6)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- , m2(mozilla::Forward<A2>(a2))
- , m3(mozilla::Forward<A3>(a3))
- , m4(mozilla::Forward<A4>(a4))
- , m5(mozilla::Forward<A5>(a5))
- , m6(mozilla::Forward<A6>(a6))
- {}
- template<class C, typename M> void apply(C* o, M m)
+ template<class C, typename M> auto apply(C* o, M m)
+ -> decltype(applyImpl(o, m, mArguments,
+ typename mozilla::IndexSequenceFor<Ts...>::Type()))
{
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter(),
- m2.PassAsParameter(), m3.PassAsParameter(),
- m4.PassAsParameter(), m5.PassAsParameter(),
- m6.PassAsParameter());
- }
-};
-template <typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7>
-struct nsRunnableMethodArguments<T0, T1, T2, T3, T4, T5, T6, T7>
-{
- typename ::detail::ParameterStorage<T0>::Type m0;
- typename ::detail::ParameterStorage<T1>::Type m1;
- typename ::detail::ParameterStorage<T2>::Type m2;
- typename ::detail::ParameterStorage<T3>::Type m3;
- typename ::detail::ParameterStorage<T4>::Type m4;
- typename ::detail::ParameterStorage<T5>::Type m5;
- typename ::detail::ParameterStorage<T6>::Type m6;
- typename ::detail::ParameterStorage<T7>::Type m7;
- template<typename A0, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
- nsRunnableMethodArguments(A0&& a0, A1&& a1, A2&& a2, A3&& a3, A4&& a4,
- A5&& a5, A6&& a6, A7&& a7)
- : m0(mozilla::Forward<A0>(a0))
- , m1(mozilla::Forward<A1>(a1))
- , m2(mozilla::Forward<A2>(a2))
- , m3(mozilla::Forward<A3>(a3))
- , m4(mozilla::Forward<A4>(a4))
- , m5(mozilla::Forward<A5>(a5))
- , m6(mozilla::Forward<A6>(a6))
- , m7(mozilla::Forward<A7>(a7))
- {}
- template<class C, typename M> void apply(C* o, M m)
- {
- ((*o).*m)(m0.PassAsParameter(), m1.PassAsParameter(),
- m2.PassAsParameter(), m3.PassAsParameter(),
- m4.PassAsParameter(), m5.PassAsParameter(),
- m6.PassAsParameter(), m7.PassAsParameter());
+ return applyImpl(o, m, mArguments,
+ typename mozilla::IndexSequenceFor<Ts...>::Type());
}
};
template<typename Method, bool Owning, typename... Storages>
class nsRunnableMethodImpl
: public nsRunnableMethodTraits<Method, Owning>::base_type
{
typedef typename nsRunnableMethodTraits<Method, Owning>::class_type