From ab8cc8387f1891ccf99721bfe5a6182c507e332f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Tue, 10 Nov 2015 18:57:40 +0100 Subject: Add qOverload to select overloaded functions [ChangeLog][QtCore][Global] qOverload added to select overloaded functions. Change-Id: I7c9b1b054e6631eca0b5594db59e1202ef552c33 Reviewed-by: Olivier Goffart (Woboq GmbH) --- .../snippets/code/src_corelib_global_qglobal.cpp | 23 +++++++++ src/corelib/global/qglobal.cpp | 43 ++++++++++++++++ src/corelib/global/qglobal.h | 60 ++++++++++++++++++++++ src/corelib/kernel/qobject.cpp | 6 +++ 4 files changed, 132 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index ccf8399e0d..ba02f75963 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -568,6 +568,29 @@ struct A : public B { template<> class QTypeInfo : public QTypeInfoMerger {}; //! [51] +//! [52] + struct Foo { + void overloadedFunction(); + void overloadedFunction(int, QString); + }; + ... qOverload<>(&Foo:overloadedFunction) + ... qOverload(&Foo:overloadedFunction) +//! [52] + +//! [53] + ... QOverload<>::of(&Foo:overloadedFunction) + ... QOverload::of(&Foo:overloadedFunction) +//! [53] + +//! [54] + struct Foo { + void overloadedFunction(int, QString); + void overloadedFunction(int, QString) const; + }; + ... qConstOverload<>(&Foo:overloadedFunction) + ... qNonConstOverload(&Foo:overloadedFunction) +//! [54] + //! [qlikely] // the condition inside the "if" will be successful most of the times for (int i = 1; i <= 365; i++) { diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index a7ed29d859..e4fa0f7391 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -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 + \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 + \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 + \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 diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 69840996dc..d607b04192 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -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 +struct QNonConstOverload +{ + template + Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } + + template + static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } +}; + +template +struct QConstOverload +{ + template + Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } + + template + static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } +}; + +template +struct QOverload : QConstOverload, QNonConstOverload +{ + using QConstOverload::of; + using QConstOverload::operator(); + using QNonConstOverload::of; + using QNonConstOverload::operator(); + + template + Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } + + template + 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 Q_CONSTEXPR QOverload qOverload Q_DECL_UNUSED = {}; +template Q_CONSTEXPR QConstOverload qConstOverload Q_DECL_UNUSED = {}; +template Q_CONSTEXPR QNonConstOverload 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); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index dea8c200ef..6702f78a04 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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(). -- cgit v1.2.3