Future-proof QGenericRunnableHelper

Collapse the two function pointers into a single one, taking an Op
enum. Add a possible return value (void*) and extra argument (also
void*). The intent is to allow extensions in a BC way,
e.g. cloning. We can't add new function pointers (sizeof changes), so
we need to fold everything into a single function.

Change-Id: Id0f3f74149c61e4e65622aeabfd2fcea3c6d7fb3
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2023-05-04 14:51:15 +02:00
parent fb2fccc534
commit 3c4743c66c

View File

@ -38,27 +38,38 @@ protected:
// Type erasure, to only instantiate a non-virtual class per Callable:
class QGenericRunnableHelperBase
{
using OpFn = void(*)(QGenericRunnableHelperBase *);
OpFn runFn;
OpFn destroyFn;
protected:
constexpr explicit QGenericRunnableHelperBase(OpFn fn, OpFn del) noexcept : runFn(fn), destroyFn(del) {}
enum class Op {
Run,
Destroy,
};
using OpFn = void* (*)(Op, QGenericRunnableHelperBase *, void*);
OpFn fn;
protected:
constexpr explicit QGenericRunnableHelperBase(OpFn f) noexcept : fn(f) {}
~QGenericRunnableHelperBase() = default;
public:
void run() { runFn(this); }
void destroy() { destroyFn(this); }
void run() { fn(Op::Run, this, nullptr); }
void destroy() { fn(Op::Destroy, this, nullptr); }
};
template <typename Callable>
class QGenericRunnableHelper : public QGenericRunnableHelperBase
{
Callable m_functionToRun;
static void *impl(Op op, QGenericRunnableHelperBase *that, [[maybe_unused]] void *arg)
{
const auto _this = static_cast<QGenericRunnableHelper*>(that);
switch (op) {
case Op::Run: _this->m_functionToRun(); break;
case Op::Destroy: delete _this; break;
}
return nullptr;
}
public:
template <typename UniCallable>
QGenericRunnableHelper(UniCallable &&functionToRun) noexcept :
QGenericRunnableHelperBase(
[](QGenericRunnableHelperBase *that) { static_cast<QGenericRunnableHelper*>(that)->m_functionToRun(); },
[](QGenericRunnableHelperBase *that) { delete static_cast<QGenericRunnableHelper*>(that); }),
explicit QGenericRunnableHelper(UniCallable &&functionToRun) noexcept
: QGenericRunnableHelperBase(&impl),
m_functionToRun(std::forward<UniCallable>(functionToRun))
{
}