Revert "qxp::function_ref: drop use of q23::invoke_r"
This reverts commit b9cce12e76
, which
broke
function_ref<void(int)> f = [](int i) { return i; };
ie. swallowing of return types.
We could maybe implement the same without invoke_r, with the same
manual if-constexpr that invoke_r has, but it would be a pointless
duplication across the two thunks we have, so just use invoke_r.
Add tests.
Pick-to: 6.4
Task-number: QTBUG-103739
Change-Id: I6034f05d813c06a25e8058ded5b6b62f3ca858b4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
6345929115
commit
fa4d18b86c
@ -21,7 +21,7 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/q20functional.h>
|
||||
#include <QtCore/q23functional.h>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@ -99,7 +99,8 @@ public:
|
||||
Q_IMPLICIT function_ref_base(F* f) noexcept
|
||||
: m_bound_entity(f),
|
||||
m_thunk_ptr([](BoundEntityType ctx, ArgTypes&&... args) noexcept(noex) -> R {
|
||||
return reinterpret_cast<F*>(ctx.fun)(std::forward<ArgTypes>(args)...);
|
||||
return q23::invoke_r<R>(reinterpret_cast<F*>(ctx.fun),
|
||||
std::forward<ArgTypes>(args)...);
|
||||
})
|
||||
{}
|
||||
|
||||
@ -115,7 +116,8 @@ public:
|
||||
: m_bound_entity(std::addressof(f)),
|
||||
m_thunk_ptr([](BoundEntityType ctx, ArgTypes&&... args) noexcept(noex) -> R {
|
||||
using That = copy_const_t<Const, std::remove_reference_t<F>>;
|
||||
return (*static_cast<That*>(ctx.obj))(std::forward<ArgTypes>(args)...);
|
||||
return q23::invoke_r<R>(*static_cast<That*>(ctx.obj),
|
||||
std::forward<ArgTypes>(args)...);
|
||||
})
|
||||
{}
|
||||
|
||||
|
@ -42,6 +42,7 @@ private Q_SLOTS:
|
||||
void basics();
|
||||
void constOverloads();
|
||||
void constExpr();
|
||||
void voidReturning();
|
||||
void ctad();
|
||||
};
|
||||
|
||||
@ -195,6 +196,45 @@ void v_f_i_ex(int) {}
|
||||
int i_f_v_ex() { return 42; }
|
||||
void v_f_v_ex() {}
|
||||
|
||||
void tst_qxp_function_ref::voidReturning()
|
||||
{
|
||||
// check that "casting" int to void returns works:
|
||||
|
||||
using Fi = qxp::function_ref<void(int)>;
|
||||
using Fv = qxp::function_ref<void()>;
|
||||
|
||||
{
|
||||
Fi fi = i_f_i_nx;
|
||||
fi(42);
|
||||
Fv fv = i_f_v_nx;
|
||||
fv();
|
||||
}
|
||||
|
||||
{
|
||||
Fi fi = i_f_i_ex;
|
||||
fi(42);
|
||||
Fv fv = i_f_v_ex;
|
||||
fv();
|
||||
}
|
||||
|
||||
// now with lambdas
|
||||
|
||||
bool ok = false; // prevent lambdas from decaying to function pointers
|
||||
{
|
||||
Fi fi = [&](int i) noexcept { return i + int(ok); };
|
||||
fi(42);
|
||||
Fv fv = [&]() noexcept { return int(ok); };
|
||||
fv();
|
||||
}
|
||||
|
||||
{
|
||||
Fi fi = [&](int i) { return i + int(ok); };
|
||||
fi(42);
|
||||
Fv fv = [&]() { return int(ok); };
|
||||
fv();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qxp_function_ref::ctad()
|
||||
{
|
||||
#define CHECK(fun, sig) \
|
||||
|
Loading…
Reference in New Issue
Block a user