diff options
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 13 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.h | 19 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/qvariant.pro | 3 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 42 |
4 files changed, 75 insertions, 2 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 9473ecbdf5..24f36b3b01 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3892,6 +3892,19 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) \sa setValue(), value() */ +/*! \fn static inline QVariant fromStdVariant(const std::variant<T, Types...> &value) + \since 5.11 + + Returns a QVariant with the type and value of the active variant of \a value. If + the active type is std::monostate a default QVariant is returned. + + \note With this method you do not need to register the variant as a Qt metatype, + since the std::variant is resolved before being stored. The component types + should be registered however. + + \sa fromValue() +*/ + /*! \fn template<typename T> QVariant qVariantFromValue(const T &value) \relates QVariant diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 29e67e9dd8..fe1ef1bdfc 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -53,6 +53,10 @@ #include <QtCore/qbytearraylist.h> #endif +#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +#include <variant> +#endif + QT_BEGIN_NAMESPACE @@ -355,6 +359,16 @@ class Q_CORE_EXPORT QVariant static inline QVariant fromValue(const T &value) { return qVariantFromValue(value); } +#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L + template<typename... Types> + static inline QVariant fromStdVariant(const std::variant<Types...> &value) + { + if (value.valueless_by_exception()) + return QVariant(); + return std::visit([](const auto &arg) { return fromValue(arg); }, value); + } +#endif + template<typename T> bool canConvert() const { return canConvert(qMetaTypeId<T>()); } @@ -503,6 +517,11 @@ inline QVariant qVariantFromValue(const T &t) template <> inline QVariant qVariantFromValue(const QVariant &t) { return t; } +#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +template <> +inline QVariant qVariantFromValue(const std::monostate &) { return QVariant(); } +#endif + template <typename T> inline void qVariantSetValue(QVariant &v, const T &t) { diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro index 96071f9f73..a620be0091 100644 --- a/tests/auto/corelib/kernel/qvariant/qvariant.pro +++ b/tests/auto/corelib/kernel/qvariant/qvariant.pro @@ -5,7 +5,8 @@ INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qvariant.cpp RESOURCES += qvariant.qrc DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -qtConfig(c++11): CONFIG += c++11 +qtConfig(c++14): CONFIG += c++14 +qtConfig(c++1z): CONFIG += c++1z !qtConfig(doubleconversion):!qtConfig(system-doubleconversion) { DEFINES += QT_NO_DOUBLECONVERSION } diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 5d19cb8428..9eb8071ff3 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -45,7 +45,9 @@ #include <limits.h> #include <float.h> #include <cmath> - +#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +#include <variant> +#endif #include <QLinkedList> #include <QRegularExpression> #include <QDir> @@ -281,6 +283,8 @@ private slots: void accessSequentialContainerKey(); + void fromStdVariant(); + private: void dataStream_data(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version); @@ -4944,5 +4948,41 @@ void tst_QVariant::accessSequentialContainerKey() QCOMPARE(nameResult, QStringLiteral("Seven")); } +void tst_QVariant::fromStdVariant() +{ +#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L + { + typedef std::variant<int, bool> intorbool_t; + intorbool_t stdvar = 5; + QVariant qvar = QVariant::fromStdVariant(stdvar); + QVERIFY(!qvar.isNull()); + QCOMPARE(qvar.type(), QVariant::Int); + QCOMPARE(qvar.value<int>(), std::get<int>(stdvar)); + stdvar = true; + qvar = QVariant::fromStdVariant(stdvar); + QVERIFY(!qvar.isNull()); + QCOMPARE(qvar.type(), QVariant::Bool); + QCOMPARE(qvar.value<bool>(), std::get<bool>(stdvar)); + } + { + std::variant<std::monostate, int> stdvar; + QVariant qvar = QVariant::fromStdVariant(stdvar); + QVERIFY(!qvar.isValid()); + stdvar = -4; + qvar = QVariant::fromStdVariant(stdvar); + QVERIFY(!qvar.isNull()); + QCOMPARE(qvar.type(), QVariant::Int); + QCOMPARE(qvar.value<int>(), std::get<int>(stdvar)); + } + { + std::variant<int, bool, QChar> stdvar = QChar::fromLatin1(' '); + QVariant qvar = QVariant::fromStdVariant(stdvar); + QVERIFY(!qvar.isNull()); + QCOMPARE(qvar.type(), QVariant::Char); + QCOMPARE(qvar.value<QChar>(), std::get<QChar>(stdvar)); + } +#endif +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" |