Constrain QCoreApplication::requestPermission to compatible functors
The 6.5 versions of the overload not taking a context/receiver object were constrained by requiring a functor to be free function or lambda. 207aae5560aa2865ec55ddb9ecbb50048060c0c0 removed that constraint, which might be source incomaptible if wrapper functions in user code forward the constraint using Expression SFINAE. Those wrappers would no longer be removed from the overload set based on the same criteria as the function they wrap. We can't constrain the new functions based on the same predicate as before, as after the simplification we have only one overload with, and one without context object. But we can still remove overloads for incompatible functors. Add the respective scenario to the QPermission test as a compile-time test. Found during 6.6 header review. Change-Id: Id21391b4a6b78a29de2f8fa04374f4262e5fafa7 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit d027b0c8162ac888de233cf3a41e3254ba2d7cc8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
50d9ed401b
commit
fbafac20af
@ -60,6 +60,10 @@ class Q_CORE_EXPORT QCoreApplication
|
||||
|
||||
Q_DECLARE_PRIVATE(QCoreApplication)
|
||||
friend class QEventLoopLocker;
|
||||
#if QT_CONFIG(permissions)
|
||||
using RequestPermissionPrototype = void(*)(QPermission);
|
||||
#endif
|
||||
|
||||
public:
|
||||
enum { ApplicationFlags = QT_VERSION
|
||||
};
|
||||
@ -122,21 +126,25 @@ public:
|
||||
# else
|
||||
// requestPermission with context or receiver object; need to require here that receiver is the
|
||||
// right type to avoid ambiguity with the private implementation function.
|
||||
template <typename Functor>
|
||||
template <typename Functor,
|
||||
std::enable_if_t<
|
||||
QtPrivate::AreFunctionsCompatible<RequestPermissionPrototype, Functor>::value,
|
||||
bool> = true>
|
||||
void requestPermission(const QPermission &permission,
|
||||
const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *receiver,
|
||||
Functor &&func)
|
||||
{
|
||||
using Prototype = void(*)(QPermission);
|
||||
QtPrivate::AssertCompatibleFunctions<Prototype, Functor>();
|
||||
requestPermission(permission,
|
||||
QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(func)),
|
||||
QtPrivate::makeCallableObject<RequestPermissionPrototype>(std::forward<Functor>(func)),
|
||||
receiver);
|
||||
}
|
||||
# endif // Q_QDOC
|
||||
|
||||
// requestPermission to a functor or function pointer (without context)
|
||||
template <typename Functor>
|
||||
template <typename Functor,
|
||||
std::enable_if_t<
|
||||
QtPrivate::AreFunctionsCompatible<RequestPermissionPrototype, Functor>::value,
|
||||
bool> = true>
|
||||
void requestPermission(const QPermission &permission, Functor &&func)
|
||||
{
|
||||
requestPermission(permission, nullptr, std::forward<Functor>(func));
|
||||
|
@ -146,6 +146,19 @@ void tst_QPermission::conversionMaintainsState() const
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Func,
|
||||
typename T = std::void_t<decltype(qApp->requestPermission(std::declval<DummyPermission>(),
|
||||
std::declval<Func>()))>
|
||||
>
|
||||
void wrapRequestPermission(const QPermission &p, Func &&f)
|
||||
{
|
||||
qApp->requestPermission(p, std::forward<Func>(f));
|
||||
}
|
||||
|
||||
template <typename Functor>
|
||||
using CompatibleTest = decltype(wrapRequestPermission(std::declval<QPermission>(), std::declval<Functor>()));
|
||||
|
||||
|
||||
// Compile test for context-less functor overloads
|
||||
void tst_QPermission::functorWithoutContext()
|
||||
{
|
||||
@ -161,6 +174,17 @@ void tst_QPermission::functorWithoutContext()
|
||||
qApp->requestPermission(dummy, [](const QPermission &permission){
|
||||
QVERIFY(permission.value<DummyPermission>());
|
||||
});
|
||||
wrapRequestPermission(dummy, [](const QPermission &permission){
|
||||
QVERIFY(permission.value<DummyPermission>());
|
||||
});
|
||||
|
||||
auto compatible = [](const QPermission &) {};
|
||||
using Compatible = decltype(compatible);
|
||||
auto incompatible = [](const QString &) {};
|
||||
using Incompatible = decltype(incompatible);
|
||||
|
||||
static_assert(qxp::is_detected_v<CompatibleTest, Compatible>);
|
||||
static_assert(!qxp::is_detected_v<CompatibleTest, Incompatible>);
|
||||
}
|
||||
|
||||
void tst_QPermission::functorWithContextInThread()
|
||||
|
Loading…
x
Reference in New Issue
Block a user