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:
Marc Mutz 2022-06-10 08:07:22 +02:00
parent 6345929115
commit fa4d18b86c
2 changed files with 45 additions and 3 deletions

View File

@ -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)...);
})
{}

View File

@ -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) \