TaskTree: Simplify SFINAE code

Change-Id: Ic54be7ff780772f7c989b88aaab948f5fe9c3750
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2023-01-20 15:13:42 +01:00
parent b95fee74bb
commit 105fc92e19

View File

@@ -259,43 +259,28 @@ public:
static Adapter *createAdapter() { return new Adapter; } static Adapter *createAdapter() { return new Adapter; }
template <typename SetupFunction> template <typename SetupFunction>
CustomTask(SetupFunction &&function, const EndHandler &done = {}, const EndHandler &error = {}) CustomTask(SetupFunction &&function, const EndHandler &done = {}, const EndHandler &error = {})
: TaskItem({&createAdapter, wrapSetup(function), wrapEnd(done), wrapEnd(error)}) {} : TaskItem({&createAdapter, wrapSetup(std::forward<SetupFunction>(function)),
wrapEnd(done), wrapEnd(error)}) {}
private: private:
template<typename SetupFunction> template<typename SetupFunction>
using IsDynamic = typename std::is_same<TaskAction,
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
template<typename SetupFunction>
using IsVoid = typename std::is_same<void,
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
template<typename SetupFunction, std::enable_if_t<IsDynamic<SetupFunction>::value, bool> = true>
static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
return [=](TaskInterface &taskInterface) {
Adapter &adapter = static_cast<Adapter &>(taskInterface);
return std::invoke(function, *adapter.task());
};
};
template<typename SetupFunction, std::enable_if_t<IsVoid<SetupFunction>::value, bool> = true>
static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&function) { static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
constexpr bool isDynamic = std::is_same_v<TaskAction,
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
constexpr bool isVoid = std::is_same_v<void,
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
static_assert(isDynamic || isVoid,
"Task setup handler needs to take (Task &) as an argument and has to return "
"void or TaskAction. The passed handler doesn't fulfill these requirements.");
return [=](TaskInterface &taskInterface) { return [=](TaskInterface &taskInterface) {
Adapter &adapter = static_cast<Adapter &>(taskInterface); Adapter &adapter = static_cast<Adapter &>(taskInterface);
if constexpr (isDynamic)
return std::invoke(function, *adapter.task());
std::invoke(function, *adapter.task()); std::invoke(function, *adapter.task());
return TaskAction::Continue; return TaskAction::Continue;
}; };
}; };
template<typename SetupFunction, std::enable_if_t<!IsDynamic<SetupFunction>::value
&& !IsVoid<SetupFunction>::value, bool> = true>
static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&) {
static_assert(IsDynamic<SetupFunction>::value || IsVoid<SetupFunction>::value,
"Task setup handler needs to take (Task &) as an argument and has to return "
"void or TaskAction. The passed handler doesn't fulfill these requirements.");
return {};
};
static TaskEndHandler wrapEnd(const EndHandler &handler) { static TaskEndHandler wrapEnd(const EndHandler &handler) {
if (!handler) if (!handler)
return {}; return {};
@@ -331,13 +316,15 @@ public:
template <typename StorageStruct, typename StorageHandler> template <typename StorageStruct, typename StorageHandler>
void onStorageSetup(const Tasking::TreeStorage<StorageStruct> &storage, void onStorageSetup(const Tasking::TreeStorage<StorageStruct> &storage,
const StorageHandler &handler) { StorageHandler &&handler) {
setupStorageHandler(storage, wrapHandler<StorageStruct>(handler), {}); setupStorageHandler(storage,
wrapHandler<StorageStruct>(std::forward<StorageHandler>(handler)), {});
} }
template <typename StorageStruct, typename StorageHandler> template <typename StorageStruct, typename StorageHandler>
void onStorageDone(const Tasking::TreeStorage<StorageStruct> &storage, void onStorageDone(const Tasking::TreeStorage<StorageStruct> &storage,
const StorageHandler &handler) { StorageHandler &&handler) {
setupStorageHandler(storage, {}, wrapHandler<StorageStruct>(handler)); setupStorageHandler(storage,
{}, wrapHandler<StorageStruct>(std::forward<StorageHandler>(handler)));
} }
signals: signals:
@@ -351,13 +338,11 @@ private:
void setupStorageHandler(const Tasking::TreeStorageBase &storage, void setupStorageHandler(const Tasking::TreeStorageBase &storage,
StorageVoidHandler setupHandler, StorageVoidHandler setupHandler,
StorageVoidHandler doneHandler); StorageVoidHandler doneHandler);
template <typename StorageStruct> template <typename StorageStruct, typename StorageHandler>
StorageVoidHandler wrapHandler(const std::function<void(StorageStruct *)> &handler) { StorageVoidHandler wrapHandler(StorageHandler &&handler) {
if (!handler) return [=](void *voidStruct) {
return {};
return [handler](void *voidStruct) {
StorageStruct *storageStruct = static_cast<StorageStruct *>(voidStruct); StorageStruct *storageStruct = static_cast<StorageStruct *>(voidStruct);
handler(storageStruct); std::invoke(handler, storageStruct);
}; };
} }