mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1212745 - Part 1 - Make mozilla::Function support pointer to member function. r=nfroyd
This commit is contained in:
parent
74670a2e32
commit
6ed090b633
@ -44,23 +44,80 @@ class FunctionImplBase
|
||||
{
|
||||
public:
|
||||
virtual ~FunctionImplBase() {}
|
||||
virtual ReturnType call(Arguments... arguments) = 0;
|
||||
virtual ReturnType call(Arguments... aArguments) = 0;
|
||||
};
|
||||
|
||||
// Normal Callable Object.
|
||||
template <typename Callable, typename ReturnType, typename... Arguments>
|
||||
class FunctionImpl : public FunctionImplBase<ReturnType, Arguments...>
|
||||
{
|
||||
public:
|
||||
explicit FunctionImpl(const Callable& aCallable)
|
||||
: mCallable(aCallable) {}
|
||||
|
||||
ReturnType call(Arguments... aArguments) override
|
||||
{
|
||||
return mCallable(Forward<Arguments>(aArguments)...);
|
||||
}
|
||||
private:
|
||||
Callable mCallable;
|
||||
};
|
||||
|
||||
// Base class for passing pointer to member function.
|
||||
template <typename Callable, typename ReturnType, typename... Arguments>
|
||||
class MemberFunctionImplBase : public FunctionImplBase<ReturnType, Arguments...>
|
||||
{
|
||||
public:
|
||||
explicit FunctionImpl(const Callable& aCallable) : mCallable(aCallable) {}
|
||||
explicit MemberFunctionImplBase(const Callable& aCallable)
|
||||
: mCallable(aCallable) {}
|
||||
|
||||
ReturnType call(Arguments... aArguments) override
|
||||
{
|
||||
return mCallable(Forward<Arguments>(aArguments)...);
|
||||
return callInternal(Forward<Arguments>(aArguments)...);
|
||||
}
|
||||
private:
|
||||
template<typename ThisType, typename... Args>
|
||||
ReturnType callInternal(ThisType* aThis, Args&&... aArguments)
|
||||
{
|
||||
return (aThis->*mCallable)(Forward<Args>(aArguments)...);
|
||||
}
|
||||
|
||||
template<typename ThisType, typename... Args>
|
||||
ReturnType callInternal(ThisType&& aThis, Args&&... aArguments)
|
||||
{
|
||||
return (aThis.*mCallable)(Forward<Args>(aArguments)...);
|
||||
}
|
||||
Callable mCallable;
|
||||
};
|
||||
|
||||
// For non-const member function specialization of FunctionImpl.
|
||||
template <typename ThisType, typename... Args, typename ReturnType, typename... Arguments>
|
||||
class FunctionImpl<ReturnType(ThisType::*)(Args...),
|
||||
ReturnType, Arguments...>
|
||||
: public MemberFunctionImplBase<ReturnType(ThisType::*)(Args...),
|
||||
ReturnType, Arguments...>
|
||||
{
|
||||
public:
|
||||
explicit FunctionImpl(ReturnType(ThisType::*aMemberFunc)(Args...))
|
||||
: MemberFunctionImplBase<ReturnType(ThisType::*)(Args...),
|
||||
ReturnType, Arguments...>(aMemberFunc)
|
||||
{}
|
||||
};
|
||||
|
||||
// For const member function specialization of FunctionImpl.
|
||||
template <typename ThisType, typename... Args, typename ReturnType, typename... Arguments>
|
||||
class FunctionImpl<ReturnType(ThisType::*)(Args...) const,
|
||||
ReturnType, Arguments...>
|
||||
: public MemberFunctionImplBase<ReturnType(ThisType::*)(Args...) const,
|
||||
ReturnType, Arguments...>
|
||||
{
|
||||
public:
|
||||
explicit FunctionImpl(ReturnType(ThisType::*aConstMemberFunc)(Args...) const)
|
||||
: MemberFunctionImplBase<ReturnType(ThisType::*)(Args...) const,
|
||||
ReturnType, Arguments...>(aConstMemberFunc)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// The primary template is never defined. As |Signature| is required to be
|
||||
|
@ -23,7 +23,10 @@ struct ConvertibleToInt
|
||||
int increment(int arg) { return arg + 1; }
|
||||
|
||||
struct S {
|
||||
S() {}
|
||||
static int increment(int arg) { return arg + 1; }
|
||||
int decrement(int arg) { return arg - 1;}
|
||||
int sum(int arg1, int arg2) const { return arg1 + arg2;}
|
||||
};
|
||||
|
||||
struct Incrementor {
|
||||
@ -82,6 +85,21 @@ TestReassignment()
|
||||
CHECK(f(42) == 44);
|
||||
}
|
||||
|
||||
static void
|
||||
TestMemberFunction()
|
||||
{
|
||||
Function<int(S&, int)> f = &S::decrement;
|
||||
S s;
|
||||
CHECK((f(s, 1) == 0));
|
||||
}
|
||||
|
||||
static void
|
||||
TestConstMemberFunction()
|
||||
{
|
||||
Function<int(const S*, int, int)> f = &S::sum;
|
||||
const S s;
|
||||
CHECK((f(&s, 1, 1) == 2));
|
||||
}
|
||||
int
|
||||
main()
|
||||
{
|
||||
@ -91,5 +109,7 @@ main()
|
||||
TestLambda();
|
||||
TestDefaultConstructionAndAssignmentLater();
|
||||
TestReassignment();
|
||||
TestMemberFunction();
|
||||
TestConstMemberFunction();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user