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 {
|
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.
|
// for callables. defined below.
|
||||||
template <typename Callable>
|
template <typename Callable>
|
||||||
struct functionTraits;
|
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
|
} // Utils
|
||||||
|
@@ -260,23 +260,6 @@ void runAsyncQFutureInterfaceDispatch(std::false_type, QFutureInterface<ResultTy
|
|||||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
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
|
// function, function pointer, or other callable object that is no member pointer
|
||||||
template <typename ResultType, typename Function, typename... Args,
|
template <typename ResultType, typename Function, typename... Args,
|
||||||
typename = typename std::enable_if<
|
typename = typename std::enable_if<
|
||||||
@@ -284,7 +267,7 @@ template <typename ResultType, typename Function, typename... Args,
|
|||||||
>::type>
|
>::type>
|
||||||
void runAsyncMemberDispatch(QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args)
|
void runAsyncMemberDispatch(QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args)
|
||||||
{
|
{
|
||||||
runAsyncArityDispatch(std::integral_constant<bool, (functionTraits<Function>::arity > 0)>(),
|
runAsyncQFutureInterfaceDispatch(functionTakesArgument<Function, 0, QFutureInterface<ResultType>&>(),
|
||||||
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user