summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@qt.io>2022-09-21 00:08:45 +0300
committerVille Voutilainen <ville.voutilainen@qt.io>2022-09-27 14:12:11 +0300
commite08f05ac6e785c39ac257ee67b03572e3194bc0e (patch)
treef82a00a4b8b4609f33a6931fbffa2f798bb8f376
parent9a23a3d1b44fbd30097b9c7c7eb5a63e93d8751b (diff)
QDebug: Support standard strings and string views directly
[ChangeLog][QtCore][QDebug] QDebug now supports printing std::strings and std::string_views (and their wide, u16, and u32 variants) directly. Task-number: QTBUG-96878 Change-Id: I7baf4fe688bfff50580b1cee9417af13949374cc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/io/qdebug.cpp73
-rw-r--r--src/corelib/io/qdebug.h28
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp256
3 files changed, 356 insertions, 1 deletions
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index f07bb05c5b..61d67ecee5 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -764,6 +764,79 @@ QDebug &QDebug::resetFormat()
*/
/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(const std::string &s)
+
+ Converts \a s to a QUtf8StringView,
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(std::string_view s)
+
+ Converts \a s to a QUtf8StringView,
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(const std::wstring &s)
+
+ Converts \a s to a QString via QString::fromStdWString(),
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(std::wstring_view s)
+
+ Converts \a s to a QString via QString::fromWCharArray(),
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(const std::u16string &s)
+
+ Converts \a s to a QStringView,
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(std::u16string_view s)
+
+ Converts \a s to a QStringView,
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(const std::u32string &s)
+
+ Converts \a s to a QString via QString::fromUcs4(),
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \since 6.5
+ \fn QDebug &QDebug::operator<<(std::u32string_view s)
+
+ Converts \a s to a QString via QString::fromUcs4(),
+ writes the result to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
\fn template <class T> QString QDebug::toString(T &&object)
\since 6.0
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index c95c03f0d1..b7cdd67568 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -16,10 +16,12 @@
#include <QtCore/qsharedpointer.h>
// all these have already been included by various headers above, but don't rely on indirect includes:
-#include <vector>
#include <list>
#include <map>
+#include <string>
+#include <string_view>
#include <utility>
+#include <vector>
#if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1
# include <QtCore/qlist.h>
@@ -126,6 +128,30 @@ public:
inline QDebug &operator<<(QTextStreamManipulator m)
{ stream->ts << m; return *this; }
+ inline QDebug &operator<<(const std::string &s)
+ { return *this << QUtf8StringView(s); }
+
+ inline QDebug &operator<<(std::string_view s)
+ { return *this << QUtf8StringView(s); }
+
+ inline QDebug &operator<<(const std::wstring &s)
+ { return *this << QString::fromStdWString(s); }
+
+ inline QDebug &operator<<(std::wstring_view s)
+ { return *this << QString::fromWCharArray(s.data(), s.size()); }
+
+ inline QDebug &operator<<(const std::u16string &s)
+ { return *this << QStringView(s); }
+
+ inline QDebug &operator<<(std::u16string_view s)
+ { return *this << QStringView(s); }
+
+ inline QDebug &operator<<(const std::u32string &s)
+ { return *this << QString::fromUcs4(s.data(), s.size()); }
+
+ inline QDebug &operator<<(std::u32string_view s)
+ { return *this << QString::fromUcs4(s.data(), s.size()); }
+
template <typename T>
static QString toString(T &&object)
{
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index 7be4c92002..989f5fcde8 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -63,6 +63,14 @@ private slots:
void qDebugQStringView() const;
void qDebugQUtf8StringView() const;
void qDebugQLatin1String() const;
+ void qDebugStdString() const;
+ void qDebugStdStringView() const;
+ void qDebugStdWString() const;
+ void qDebugStdWStringView() const;
+ void qDebugStdU16String() const;
+ void qDebugStdU16StringView() const;
+ void qDebugStdU32String() const;
+ void qDebugStdU32StringView() const;
void qDebugQByteArray() const;
void qDebugQByteArrayView() const;
void qDebugQFlags() const;
@@ -648,6 +656,254 @@ void tst_QDebug::qDebugQLatin1String() const
QCOMPARE(s_msg, QString("\"\\nSm\\u00F8rg\\u00E5sbord\\\\\""));
}
+void tst_QDebug::qDebugStdString() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::string("foo") << std::string("") << std::string("barbaz", 3);
+ d.nospace().noquote() << std::string("baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::string string("\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdString(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdString(string));
+}
+
+void tst_QDebug::qDebugStdStringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::string_view("foo") << std::string_view("") << std::string_view("barbaz", 3);
+ d.nospace().noquote() << std::string_view("baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::string_view string("\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdString(std::string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdString(std::string(string)));
+}
+
+void tst_QDebug::qDebugStdWString() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::wstring(L"foo") << std::wstring(L"") << std::wstring(L"barbaz", 3);
+ d.nospace().noquote() << std::wstring(L"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::wstring string(L"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdWString(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdWString(string));
+}
+
+void tst_QDebug::qDebugStdWStringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::wstring_view(L"foo") << std::wstring_view(L"") << std::wstring_view(L"barbaz", 3);
+ d.nospace().noquote() << std::wstring_view(L"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::wstring_view string(L"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdWString(std::wstring(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdWString(std::wstring(string)));
+}
+
+void tst_QDebug::qDebugStdU16String() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u16string(u"foo") << std::u16string(u"") << std::u16string(u"barbaz", 3);
+ d.nospace().noquote() << std::u16string(u"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u16string string(u"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU16String(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU16String(string));
+}
+
+void tst_QDebug::qDebugStdU16StringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u16string_view(u"foo") << std::u16string_view(u"") << std::u16string_view(u"barbaz", 3);
+ d.nospace().noquote() << std::u16string_view(u"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u16string_view string(u"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU16String(std::u16string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU16String(std::u16string(string)));
+}
+
+void tst_QDebug::qDebugStdU32String() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u32string(U"foo") << std::u32string(U"") << std::u32string(U"barbaz", 3);
+ d.nospace().noquote() << std::u32string(U"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u32string string(U"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU32String(string));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU32String(string));
+}
+
+void tst_QDebug::qDebugStdU32StringView() const
+{
+ QString file, function;
+ int line = 0;
+ MessageHandlerSetter mhs(myMessageHandler);
+ {
+ QDebug d = qDebug();
+ d << std::u32string_view(U"foo") << std::u32string_view(U"") << std::u32string_view(U"barbaz", 3);
+ d.nospace().noquote() << std::u32string_view(U"baz");
+ }
+#ifndef QT_NO_MESSAGELOGCONTEXT
+ file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
+#endif
+ QCOMPARE(s_msgType, QtDebugMsg);
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz"));
+ QCOMPARE(QString::fromLatin1(s_file), file);
+ QCOMPARE(s_line, line);
+ QCOMPARE(QString::fromLatin1(s_function), function);
+
+ /* simpler tests from now on */
+ std::u32string_view string(U"\"Hello\"");
+ qDebug() << string;
+ QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\""));
+
+ qDebug().noquote().nospace() << string;
+ QCOMPARE(s_msg, QString::fromStdU32String(std::u32string(string)));
+
+ qDebug().noquote().nospace() << qSetFieldWidth(8) << string;
+ QCOMPARE(s_msg, " " + QString::fromStdU32String(std::u32string(string)));
+}
+
void tst_QDebug::qDebugQByteArray() const
{
QString file, function;