forked from qt-creator/qt-creator
functionTraits: Add reusable "functionTakesArgument" type
Instead of doing the dispatch "function has enough arguments" + "argument is of correct type" for runAsync specifically, extract a reusable functionTakesArgument<Function, unsigned index, Type>, which is either of type std::true_type or std::false_type. Change-Id: Iecfa867a0230d29fd96ae500423a5bdd1d475106 Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
@@ -29,6 +29,26 @@
|
||||
|
||||
namespace Utils {
|
||||
|
||||
/*
|
||||
struct functionTraits<Function>
|
||||
{
|
||||
using ResultType; // Return type of Function
|
||||
struct argument<unsigned index>
|
||||
{
|
||||
using type; // type of Function argument at index (starting with 0)
|
||||
}
|
||||
}
|
||||
|
||||
struct functionTakesArgument<Function, unsigned index, ArgumentType>;
|
||||
|
||||
Is derived from std::true_type if Function takes an argument of type ArgumentType at index.
|
||||
Otherwise derived from std::false_type.
|
||||
*/
|
||||
|
||||
////////////////////
|
||||
// functionTraits
|
||||
////////////////////
|
||||
|
||||
// for callables. defined below.
|
||||
template <typename Callable>
|
||||
struct functionTraits;
|
||||
@@ -135,4 +155,34 @@ struct functionTraits<Callable&&> : public functionTraits<Callable>
|
||||
{
|
||||
};
|
||||
|
||||
////////////////////
|
||||
// functionTakesArgument
|
||||
////////////////////
|
||||
namespace Internal {
|
||||
|
||||
template <typename HasArity/*true_type or false_type*/,
|
||||
typename Function, unsigned index, typename T>
|
||||
struct functionTakesArgumentArityDispatch;
|
||||
|
||||
template <typename Function, unsigned index, typename T>
|
||||
struct functionTakesArgumentArityDispatch<std::false_type, Function, index, T>
|
||||
: public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Function, unsigned index, typename T>
|
||||
struct functionTakesArgumentArityDispatch<std::true_type, Function, index, T>
|
||||
: public std::is_same<T, typename functionTraits<Function>::template argument<index>::type>
|
||||
{
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
||||
template <typename Function, unsigned index, typename T>
|
||||
struct functionTakesArgument : public Internal::functionTakesArgumentArityDispatch<
|
||||
std::integral_constant<bool, (functionTraits<Function>::arity > index)>,
|
||||
Function, index, T>
|
||||
{
|
||||
};
|
||||
|
||||
} // Utils
|
||||
|
@@ -260,23 +260,6 @@ void runAsyncQFutureInterfaceDispatch(std::false_type, QFutureInterface<ResultTy
|
||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// function that takes at least one argument which could be QFutureInterface
|
||||
template <typename ResultType, typename Function, typename... Args>
|
||||
void runAsyncArityDispatch(std::true_type, QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args)
|
||||
{
|
||||
runAsyncQFutureInterfaceDispatch(std::is_same<QFutureInterface<ResultType>&,
|
||||
typename functionTraits<Function>::template argument<0>::type>(),
|
||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// function that does not take an argument, so it does not take a QFutureInterface
|
||||
template <typename ResultType, typename Function, typename... Args>
|
||||
void runAsyncArityDispatch(std::false_type, QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args)
|
||||
{
|
||||
runAsyncQFutureInterfaceDispatch(std::false_type(),
|
||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// function, function pointer, or other callable object that is no member pointer
|
||||
template <typename ResultType, typename Function, typename... Args,
|
||||
typename = typename std::enable_if<
|
||||
@@ -284,8 +267,8 @@ template <typename ResultType, typename Function, typename... Args,
|
||||
>::type>
|
||||
void runAsyncMemberDispatch(QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args)
|
||||
{
|
||||
runAsyncArityDispatch(std::integral_constant<bool, (functionTraits<Function>::arity > 0)>(),
|
||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
||||
runAsyncQFutureInterfaceDispatch(functionTakesArgument<Function, 0, QFutureInterface<ResultType>&>(),
|
||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Function = member function
|
||||
|
Reference in New Issue
Block a user