summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdebug.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qdebug.h')
-rw-r--r--src/corelib/io/qdebug.h142
1 files changed, 111 insertions, 31 deletions
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 6c693ad142..4797bcd169 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -11,13 +11,16 @@
#include <QtCore/qcontainerfwd.h>
#include <QtCore/qtextstream.h>
+#include <QtCore/qtypes.h>
#include <QtCore/qstring.h>
#include <QtCore/qcontiguouscache.h>
#include <QtCore/qsharedpointer.h>
// all these have already been included by various headers above, but don't rely on indirect includes:
+#include <chrono>
#include <list>
#include <map>
+#include <optional>
#include <string>
#include <string_view>
#include <utility>
@@ -67,6 +70,9 @@ class QT6_ONLY(Q_CORE_EXPORT) QDebug : public QIODeviceBase
QT7_ONLY(Q_CORE_EXPORT) void putUcs4(uint ucs4);
QT7_ONLY(Q_CORE_EXPORT) void putString(const QChar *begin, size_t length);
QT7_ONLY(Q_CORE_EXPORT) void putByteArray(const char *begin, size_t length, Latin1Content content);
+ QT7_ONLY(Q_CORE_EXPORT) void putTimeUnit(qint64 num, qint64 den);
+ QT7_ONLY(Q_CORE_EXPORT) void putInt128(const void *i);
+ QT7_ONLY(Q_CORE_EXPORT) void putUInt128(const void *i);
public:
explicit QDebug(QIODevice *device) : stream(new Stream(device)) {}
explicit QDebug(QString *string) : stream(new Stream(string)) {}
@@ -91,6 +97,9 @@ public:
bool autoInsertSpaces() const { return stream->space; }
void setAutoInsertSpaces(bool b) { stream->space = b; }
+ [[nodiscard]] bool quoteStrings() const noexcept { return !stream->noQuotes; }
+ void setQuoteStrings(bool b) { stream->noQuotes = !b; }
+
inline QDebug &quote() { stream->noQuotes = false; return *this; }
inline QDebug &noquote() { stream->noQuotes = true; return *this; }
inline QDebug &maybeQuote(char c = '"') { if (!stream->noQuotes) stream->ts << c; return *this; }
@@ -100,7 +109,7 @@ public:
inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(unsigned short t) { stream->ts << t; return maybeSpace(); }
- inline QDebug &operator<<(char16_t t) { return *this << QChar(ushort(t)); }
+ inline QDebug &operator<<(char16_t t) { return *this << QChar(t); }
inline QDebug &operator<<(char32_t t) { putUcs4(t); return maybeSpace(); }
inline QDebug &operator<<(signed int t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(unsigned int t) { stream->ts << t; return maybeSpace(); }
@@ -108,6 +117,7 @@ public:
inline QDebug &operator<<(unsigned long t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(qint64 t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(quint64 t) { stream->ts << t; return maybeSpace(); }
+ inline QDebug &operator<<(qfloat16 t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(double t) { stream->ts << t; return maybeSpace(); }
inline QDebug &operator<<(const char* t) { stream->ts << QString::fromUtf8(t); return maybeSpace(); }
@@ -120,6 +130,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;
@@ -128,29 +139,88 @@ public:
inline QDebug &operator<<(QTextStreamManipulator m)
{ stream->ts << m; return *this; }
- inline QDebug &operator<<(const std::string &s)
+#ifdef Q_QDOC
+ template <typename Char, typename...Args>
+ QDebug &operator<<(const std::basic_string<Char, Args...> &s);
+
+ template <typename Char, typename...Args>
+ QDebug &operator<<(std::basic_string_view<Char, Args...> s);
+#else
+ template <typename...Args>
+ QDebug &operator<<(const std::basic_string<char, Args...> &s)
{ return *this << QUtf8StringView(s); }
- inline QDebug &operator<<(std::string_view s)
+ template <typename...Args>
+ QDebug &operator<<(std::basic_string_view<char, Args...> s)
{ return *this << QUtf8StringView(s); }
- inline QDebug &operator<<(const std::wstring &s)
- { return *this << QString::fromStdWString(s); }
+#ifdef __cpp_char8_t
+ template <typename...Args>
+ QDebug &operator<<(const std::basic_string<char8_t, Args...> &s)
+ { return *this << QUtf8StringView(s); }
- inline QDebug &operator<<(std::wstring_view s)
- { return *this << QString::fromWCharArray(s.data(), s.size()); }
+ template <typename...Args>
+ QDebug &operator<<(std::basic_string_view<char8_t, Args...> s)
+ { return *this << QUtf8StringView(s); }
+#endif // __cpp_char8_t
- inline QDebug &operator<<(const std::u16string &s)
+ template <typename...Args>
+ QDebug &operator<<(const std::basic_string<char16_t, Args...> &s)
{ return *this << QStringView(s); }
- inline QDebug &operator<<(std::u16string_view s)
+ template <typename...Args>
+ QDebug &operator<<(std::basic_string_view<char16_t, Args...> s)
{ return *this << QStringView(s); }
- inline QDebug &operator<<(const std::u32string &s)
+ template <typename...Args>
+ QDebug &operator<<(const std::basic_string<wchar_t, Args...> &s)
+ {
+ if constexpr (sizeof(wchar_t) == 2)
+ return *this << QStringView(s);
+ else
+ return *this << QString::fromWCharArray(s.data(), s.size()); // ### optimize
+ }
+
+ template <typename...Args>
+ QDebug &operator<<(std::basic_string_view<wchar_t, Args...> s)
+ {
+ if constexpr (sizeof(wchar_t) == 2)
+ return *this << QStringView(s);
+ else
+ return *this << QString::fromWCharArray(s.data(), s.size()); // ### optimize
+ }
+
+ template <typename...Args>
+ QDebug &operator<<(const std::basic_string<char32_t, Args...> &s)
{ return *this << QString::fromUcs4(s.data(), s.size()); }
- inline QDebug &operator<<(std::u32string_view s)
+ template <typename...Args>
+ QDebug &operator<<(std::basic_string_view<char32_t, Args...> s)
{ return *this << QString::fromUcs4(s.data(), s.size()); }
+#endif // !Q_QDOC
+
+ template <typename Rep, typename Period>
+ QDebug &operator<<(std::chrono::duration<Rep, Period> duration)
+ {
+ stream->ts << duration.count();
+ putTimeUnit(Period::num, Period::den);
+ return maybeSpace();
+ }
+
+#ifdef QT_SUPPORTS_INT128
+private:
+ // Constrained templates so they only match q(u)int128 without conversions.
+ // Also keeps these operators out of the ABI.
+ template <typename T>
+ using if_qint128 = std::enable_if_t<std::is_same_v<T, qint128>, bool>;
+ template <typename T>
+ using if_quint128 = std::enable_if_t<std::is_same_v<T, quint128>, bool>;
+public:
+ template <typename T, if_qint128<T> = true>
+ QDebug &operator<<(T i128) { putInt128(&i128); return maybeSpace(); }
+ template <typename T, if_quint128<T> = true>
+ QDebug &operator<<(T u128) { putUInt128(&u128); return maybeSpace(); }
+#endif // QT_SUPPORTS_INT128
template <typename T>
static QString toString(T &&object)
@@ -165,10 +235,12 @@ public:
Q_DECLARE_SHARED(QDebug)
class QDebugStateSaverPrivate;
-class Q_CORE_EXPORT QDebugStateSaver
+class QDebugStateSaver
{
public:
+ Q_NODISCARD_CTOR Q_CORE_EXPORT
QDebugStateSaver(QDebug &dbg);
+ Q_CORE_EXPORT
~QDebugStateSaver();
private:
Q_DISABLE_COPY(QDebugStateSaver)
@@ -241,72 +313,83 @@ template<typename Container, typename ...T>
using QDebugIfHasDebugStreamContainer =
std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator_container<QDebug, Container, T>...>, QDebug>;
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
template<typename T>
inline QDebugIfHasDebugStreamContainer<QList<T>, T> operator<<(QDebug debug, const QList<T> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "QList", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "QList", vec);
}
template<typename T, qsizetype P>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QVarLengthArray<T, P> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "QVarLengthArray", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "QVarLengthArray", vec);
}
template <typename T, typename Alloc>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "std::vector", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::vector", vec);
}
template <typename T, typename Alloc>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::list<T, Alloc> &vec)
{
- return QtPrivate::printSequentialContainer(debug, "std::list", vec);
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::list", vec);
}
template <typename T>
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, std::initializer_list<T> list)
{
- return QtPrivate::printSequentialContainer(debug, "std::initializer_list", list);
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::initializer_list", list);
}
template <typename Key, typename T, typename Compare, typename Alloc>
inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
{
- return QtPrivate::printSequentialContainer(debug, "std::map", map); // yes, sequential: *it is std::pair
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::map", map); // yes, sequential: *it is std::pair
}
template <typename Key, typename T, typename Compare, typename Alloc>
inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
{
- return QtPrivate::printSequentialContainer(debug, "std::multimap", map); // yes, sequential: *it is std::pair
+ return QtPrivate::printSequentialContainer(std::move(debug), "std::multimap", map); // yes, sequential: *it is std::pair
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
{
- return QtPrivate::printAssociativeContainer(debug, "QMap", map);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QMap", map);
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMultiMap<Key, T>, Key, T> operator<<(QDebug debug, const QMultiMap<Key, T> &map)
{
- return QtPrivate::printAssociativeContainer(debug, "QMultiMap", map);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiMap", map);
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QHash<Key, T>, Key, T> operator<<(QDebug debug, const QHash<Key, T> &hash)
{
- return QtPrivate::printAssociativeContainer(debug, "QHash", hash);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QHash", hash);
}
template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMultiHash<Key, T>, Key, T> operator<<(QDebug debug, const QMultiHash<Key, T> &hash)
{
- return QtPrivate::printAssociativeContainer(debug, "QMultiHash", hash);
+ return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiHash", hash);
+}
+
+template <class T>
+inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::optional<T> &opt)
+{
+ const QDebugStateSaver saver(debug);
+ if (!opt)
+ debug.nospace() << std::nullopt;
+ else
+ debug.nospace() << "std::optional(" << *opt << ')';
+ return debug;
}
template <class T1, class T2>
@@ -320,7 +403,7 @@ inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T
template <typename T>
inline QDebugIfHasDebugStreamContainer<QSet<T>, T> operator<<(QDebug debug, const QSet<T> &set)
{
- return QtPrivate::printSequentialContainer(debug, "QSet", set);
+ return QtPrivate::printSequentialContainer(std::move(debug), "QSet", set);
}
template <class T>
@@ -372,15 +455,12 @@ template <typename T>
QDebug operator<<(QDebug debug, const QSet<T> &set);
template <class T1, class T2>
-QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair);
-
-template <class T1, class T2>
QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair);
template <typename T>
QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache);
-#endif // Q_CLANG_QDOC
+#endif // Q_QDOC
template <class T>
inline QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
@@ -491,7 +571,7 @@ inline QDebug operator<<(QDebug debug, QKeyCombination combination)
return debug;
}
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
// We provide QDebug stream operators for commonly used Core Foundation
// and Core Graphics types, as well as NSObject. Additional CF/CG types
@@ -570,7 +650,7 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF
#undef QT_FORWARD_DECLARE_CG_TYPE
#undef QT_FORWARD_DECLARE_MUTABLE_CG_TYPE
-#endif // Q_OS_MAC
+#endif // Q_OS_DARWIN
QT_END_NAMESPACE