Add qOverload to select overloaded functions
[ChangeLog][QtCore][Global] qOverload added to select overloaded functions. Change-Id: I7c9b1b054e6631eca0b5594db59e1202ef552c33 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
e41e034669
commit
ab8cc8387f
@ -568,6 +568,29 @@ struct A : public B {
|
||||
template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
|
||||
//! [51]
|
||||
|
||||
//! [52]
|
||||
struct Foo {
|
||||
void overloadedFunction();
|
||||
void overloadedFunction(int, QString);
|
||||
};
|
||||
... qOverload<>(&Foo:overloadedFunction)
|
||||
... qOverload<int, QString>(&Foo:overloadedFunction)
|
||||
//! [52]
|
||||
|
||||
//! [53]
|
||||
... QOverload<>::of(&Foo:overloadedFunction)
|
||||
... QOverload<int, QString>::of(&Foo:overloadedFunction)
|
||||
//! [53]
|
||||
|
||||
//! [54]
|
||||
struct Foo {
|
||||
void overloadedFunction(int, QString);
|
||||
void overloadedFunction(int, QString) const;
|
||||
};
|
||||
... qConstOverload<>(&Foo:overloadedFunction)
|
||||
... qNonConstOverload<int, QString>(&Foo:overloadedFunction)
|
||||
//! [54]
|
||||
|
||||
//! [qlikely]
|
||||
// the condition inside the "if" will be successful most of the times
|
||||
for (int i = 1; i <= 365; i++) {
|
||||
|
@ -921,6 +921,49 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in
|
||||
\sa qMin(), qMax()
|
||||
*/
|
||||
|
||||
/*! \fn auto qOverload(T functionPointer)
|
||||
\relates <QtGlobal>
|
||||
\since 5.7
|
||||
|
||||
qOverload() returns a pointer to an overloaded function. The template
|
||||
parameter is the list of the argument types of the function.
|
||||
\a functionPointer is the pointer to the (member) function:
|
||||
|
||||
\snippet code/src_corelib_global_qglobal.cpp 52
|
||||
|
||||
If a member function is also const-overladed \l qConstOverload and
|
||||
\l qNonConstOverload needs to be used.
|
||||
|
||||
qOverload() needs C++14 enabled. In C++11 only code the helper
|
||||
classes QOverload, QConstOverload, and QNonConstOverload could be used directly:
|
||||
|
||||
\snippet code/src_corelib_global_qglobal.cpp 53
|
||||
|
||||
\sa qConstOverload(), qNonConstOverload()
|
||||
*/
|
||||
|
||||
/*! \fn auto qConstOverload(T memberFunctionPointer)
|
||||
\relates <QtGlobal>
|
||||
\since 5.7
|
||||
|
||||
qConstOverload() returns a pointer to an constant member function:
|
||||
|
||||
\snippet code/src_corelib_global_qglobal.cpp 54
|
||||
|
||||
\sa qOverload, qNonConstOverload
|
||||
*/
|
||||
|
||||
/*! \fn auto qNonConstOverload(T memberFunctionPointer)
|
||||
\relates <QtGlobal>
|
||||
\since 5.7
|
||||
|
||||
qNonConstOverload() eturns a pointer to an non constant member function:
|
||||
|
||||
\snippet code/src_corelib_global_qglobal.cpp 54
|
||||
|
||||
\sa qOverload, qNonConstOverload
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro QT_VERSION_CHECK
|
||||
\relates <QtGlobal>
|
||||
|
@ -1018,6 +1018,66 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
|
||||
{ return T::dynamic_cast_will_always_fail_because_rtti_is_disabled; }
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Q_QDOC
|
||||
|
||||
// Just for documentation generation
|
||||
auto qOverload(T functionPointer);
|
||||
auto qConstOverload(T memberFunctionPointer);
|
||||
auto qNonConstOverload(T memberFunctionPointer);
|
||||
|
||||
#elif defined(Q_COMPILER_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename... Args>
|
||||
struct QNonConstOverload
|
||||
{
|
||||
template <typename R, typename T>
|
||||
Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
|
||||
{ return ptr; }
|
||||
|
||||
template <typename R, typename T>
|
||||
static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
|
||||
{ return ptr; }
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct QConstOverload
|
||||
{
|
||||
template <typename R, typename T>
|
||||
Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr)
|
||||
{ return ptr; }
|
||||
|
||||
template <typename R, typename T>
|
||||
static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr)
|
||||
{ return ptr; }
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct QOverload : QConstOverload<Args...>, QNonConstOverload<Args...>
|
||||
{
|
||||
using QConstOverload<Args...>::of;
|
||||
using QConstOverload<Args...>::operator();
|
||||
using QNonConstOverload<Args...>::of;
|
||||
using QNonConstOverload<Args...>::operator();
|
||||
|
||||
template <typename R>
|
||||
Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr)
|
||||
{ return ptr; }
|
||||
|
||||
template <typename R>
|
||||
static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr)
|
||||
{ return ptr; }
|
||||
};
|
||||
|
||||
#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
|
||||
template <typename... Args> Q_CONSTEXPR QOverload<Args...> qOverload Q_DECL_UNUSED = {};
|
||||
template <typename... Args> Q_CONSTEXPR QConstOverload<Args...> qConstOverload Q_DECL_UNUSED = {};
|
||||
template <typename... Args> Q_CONSTEXPR QNonConstOverload<Args...> qNonConstOverload Q_DECL_UNUSED = {};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class QByteArray;
|
||||
Q_CORE_EXPORT QByteArray qgetenv(const char *varName);
|
||||
Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value);
|
||||
|
@ -4538,6 +4538,8 @@ void qDeleteInEventHandler(QObject *o)
|
||||
|
||||
make sure to declare the argument type with Q_DECLARE_METATYPE
|
||||
|
||||
Overloaded functions can be resolved with help of \l qOverload.
|
||||
|
||||
\note The number of arguments in the signal or slot are limited to 6 if
|
||||
the compiler does not support C++11 variadic templates.
|
||||
*/
|
||||
@ -4573,6 +4575,8 @@ void qDeleteInEventHandler(QObject *o)
|
||||
However, you should take care that any objects used within the functor
|
||||
are still alive when the signal is emitted.
|
||||
|
||||
Overloaded functions can be resolved with help of \l qOverload.
|
||||
|
||||
\note If the compiler does not support C++11 variadic templates, the number
|
||||
of arguments in the signal or slot are limited to 6, and the functor object
|
||||
must not have an overloaded or templated operator().
|
||||
@ -4612,6 +4616,8 @@ void qDeleteInEventHandler(QObject *o)
|
||||
However, you should take care that any objects used within the functor
|
||||
are still alive when the signal is emitted.
|
||||
|
||||
Overloaded functions can be resolved with help of \l qOverload.
|
||||
|
||||
\note If the compiler does not support C++11 variadic templates, the number
|
||||
of arguments in the signal or slot are limited to 6, and the functor object
|
||||
must not have an overloaded or templated operator().
|
||||
|
@ -55,6 +55,7 @@ private slots:
|
||||
void qprintable();
|
||||
void qprintable_data();
|
||||
void buildAbiEndianness();
|
||||
void testqOverload();
|
||||
};
|
||||
|
||||
void tst_QGlobal::qIsNull()
|
||||
@ -652,5 +653,126 @@ void tst_QGlobal::buildAbiEndianness()
|
||||
QVERIFY(QSysInfo::buildAbi().contains(endian));
|
||||
}
|
||||
|
||||
struct Overloaded
|
||||
{
|
||||
void foo() {}
|
||||
void foo(QByteArray) {}
|
||||
void foo(QByteArray, const QString &) {}
|
||||
|
||||
void constFoo() const {}
|
||||
void constFoo(QByteArray) const {}
|
||||
void constFoo(QByteArray, const QString &) const {}
|
||||
|
||||
void mixedFoo() {}
|
||||
void mixedFoo(QByteArray) const {}
|
||||
};
|
||||
|
||||
void freeOverloaded() {}
|
||||
void freeOverloaded(QByteArray) {}
|
||||
void freeOverloaded(QByteArray, const QString &) {}
|
||||
|
||||
void freeOverloadedGet(QByteArray) {}
|
||||
QByteArray freeOverloadedGet() { return QByteArray(); }
|
||||
|
||||
|
||||
void tst_QGlobal::testqOverload()
|
||||
{
|
||||
#ifdef Q_COMPILER_VARIADIC_TEMPLATES
|
||||
|
||||
// void returning free overloaded functions
|
||||
QVERIFY(QOverload<>::of(&freeOverloaded) ==
|
||||
static_cast<void (*)()>(&freeOverloaded));
|
||||
|
||||
QVERIFY(QOverload<QByteArray>::of(&freeOverloaded) ==
|
||||
static_cast<void (*)(QByteArray)>(&freeOverloaded));
|
||||
|
||||
QVERIFY((QOverload<QByteArray, const QString &>::of(&freeOverloaded)) ==
|
||||
static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded));
|
||||
|
||||
// value returning free overloaded functions
|
||||
QVERIFY(QOverload<>::of(&freeOverloadedGet) ==
|
||||
static_cast<QByteArray (*)()>(&freeOverloadedGet));
|
||||
|
||||
QVERIFY(QOverload<QByteArray>::of(&freeOverloadedGet) ==
|
||||
static_cast<void (*)(QByteArray)>(&freeOverloadedGet));
|
||||
|
||||
// void returning overloaded member functions
|
||||
QVERIFY(QOverload<>::of(&Overloaded::foo) ==
|
||||
static_cast<void (Overloaded::*)()>(&Overloaded::foo));
|
||||
|
||||
QVERIFY(QOverload<QByteArray>::of(&Overloaded::foo) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo));
|
||||
|
||||
QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::foo)) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo));
|
||||
|
||||
// void returning overloaded const member functions
|
||||
QVERIFY(QOverload<>::of(&Overloaded::constFoo) ==
|
||||
static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo));
|
||||
|
||||
QVERIFY(QOverload<QByteArray>::of(&Overloaded::constFoo) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo));
|
||||
|
||||
QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::constFoo)) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo));
|
||||
|
||||
// void returning overloaded const AND non-const member functions
|
||||
QVERIFY(QNonConstOverload<>::of(&Overloaded::mixedFoo) ==
|
||||
static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo));
|
||||
|
||||
QVERIFY(QConstOverload<QByteArray>::of(&Overloaded::mixedFoo) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo));
|
||||
|
||||
#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14
|
||||
|
||||
// void returning free overloaded functions
|
||||
QVERIFY(qOverload<>(&freeOverloaded) ==
|
||||
static_cast<void (*)()>(&freeOverloaded));
|
||||
|
||||
QVERIFY(qOverload<QByteArray>(&freeOverloaded) ==
|
||||
static_cast<void (*)(QByteArray)>(&freeOverloaded));
|
||||
|
||||
QVERIFY((qOverload<QByteArray, const QString &>(&freeOverloaded)),
|
||||
static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded));
|
||||
|
||||
// value returning free overloaded functions
|
||||
QVERIFY(qOverload<>(&freeOverloadedGet) ==
|
||||
static_cast<QByteArray (*)()>(&freeOverloadedGet));
|
||||
|
||||
QVERIFY(qOverload<QByteArray>(&freeOverloadedGet) ==
|
||||
static_cast<void (*)(QByteArray)>(&freeOverloadedGet));
|
||||
|
||||
// void returning overloaded member functions
|
||||
QVERIFY(qOverload<>(&Overloaded::foo) ==
|
||||
static_cast<void (Overloaded::*)()>(&Overloaded::foo));
|
||||
|
||||
QVERIFY(qOverload<QByteArray>(&Overloaded::foo) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo));
|
||||
|
||||
QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::foo)) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo));
|
||||
|
||||
// void returning overloaded const member functions
|
||||
QVERIFY(qOverload<>(&Overloaded::constFoo) ==
|
||||
static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo));
|
||||
|
||||
QVERIFY(qOverload<QByteArray>(&Overloaded::constFoo) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo));
|
||||
|
||||
QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::constFoo)) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo));
|
||||
|
||||
// void returning overloaded const AND non-const member functions
|
||||
QVERIFY(qNonConstOverload<>(&Overloaded::mixedFoo) ==
|
||||
static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo));
|
||||
|
||||
QVERIFY(qConstOverload<QByteArray>(&Overloaded::mixedFoo) ==
|
||||
static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QGlobal)
|
||||
#include "tst_qglobal.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user