From b7657ddccbe0a5ab1cdfc61ae6b7f0501dbfb24a Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 20 Nov 2023 20:46:23 +0100 Subject: [PATCH] qDebug: add support for std::optional and std::nullopt_t [ChangeLog][QtCore][QDebug] Added support for std::optional and std::nullopt_t Change-Id: I1e6196adb408401cae8776cd0c60af294a39a83f Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz Reviewed-by: Volker Hilsheimer --- src/corelib/io/qdebug.cpp | 16 ++++++++++++++ src/corelib/io/qdebug.h | 12 +++++++++++ tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 23 +++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index 5c42ee2e1cf..4f6b1696eb9 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -1018,6 +1018,15 @@ QDebug &QDebug::resetFormat() \c T2 need to support streaming into QDebug. */ +/*! + \since 6.7 + \fn template QDebug operator<<(QDebug debug, const std::optional &opt) + \relates QDebug + + Writes the contents of \a opt (or \c nullopt if not set) to \a debug. + \c T needs to support streaming into QDebug. +*/ + /*! \fn template QDebug operator<<(QDebug debug, const QContiguousCache &cache) \relates QDebug @@ -1050,6 +1059,13 @@ QDebug &QDebug::resetFormat() \internal */ +/*! + \since 6.7 + \fn QDebug &QDebug::operator<<(std::nullopt_t) + + Writes nullopt to the stream. +*/ + /*! \class QDebugStateSaver \inmodule QtCore diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index f5a35236e1a..770f4fac9a8 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -126,6 +126,7 @@ public: inline QDebug &operator<<(QByteArrayView t) { putByteArray(t.constData(), t.size(), ContainsBinary); return maybeSpace(); } inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(std::nullptr_t) { stream->ts << "(nullptr)"; return maybeSpace(); } + inline QDebug &operator<<(std::nullopt_t) { stream->ts << "nullopt"; return maybeSpace(); } inline QDebug &operator<<(QTextStreamFunction f) { stream->ts << f; return *this; @@ -361,6 +362,17 @@ inline QDebugIfHasDebugStreamContainer, Key, T> operator<<(QD return QtPrivate::printAssociativeContainer(debug, "QMultiHash", hash); } +template +inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::optional &opt) +{ + const QDebugStateSaver saver(debug); + if (!opt) + debug.nospace() << std::nullopt; + else + debug.nospace() << "std::optional(" << *opt << ')'; + return debug; +} + template inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::pair &pair) { diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 6c976e4a63f..2137604457d 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -89,6 +89,7 @@ private slots: void qDebugQFlags() const; void qDebugStdChrono_data() const; void qDebugStdChrono() const; + void qDebugStdOptional() const; void textStreamModifiers() const; void resetFormat() const; void defaultMessagehandler() const; @@ -1215,6 +1216,28 @@ void tst_QDebug::qDebugStdChrono() const QCOMPARE(fn(), expected); } +void tst_QDebug::qDebugStdOptional() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + std::optional notSet = std::nullopt; + std::optional set("foo"); + auto no = std::nullopt; + QDebug d = qDebug(); + d << notSet << set << no; + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 4; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("nullopt std::optional(\"foo\") nullopt")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); +} + void tst_QDebug::textStreamModifiers() const { QString file, function;