summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-08-09 15:57:00 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-25 11:21:32 +0000
commit5927acaf652e2dfacd777a7491c217aefd1118ef (patch)
tree654205ef8bb116f9c20dd86a5a17cff7e254936b
parent43c44d05ca6af4ec78c1dea84635375a637ff80d (diff)
Add support for converting from std::variant
Adds inline handling of the C++17 type std::variant, so the type will be resolved if converted into a QVariant. Change-Id: I31809d70d7f347277389d42a3695836ec7a32d02 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/kernel/qvariant.cpp13
-rw-r--r--src/corelib/kernel/qvariant.h19
-rw-r--r--tests/auto/corelib/kernel/qvariant/qvariant.pro3
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp42
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"