diff options
Diffstat (limited to 'src/corelib/io/qdebug.h')
-rw-r--r-- | src/corelib/io/qdebug.h | 242 |
1 files changed, 163 insertions, 79 deletions
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 2647f3da0f..4797bcd169 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -1,67 +1,41 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QDEBUG_H #define QDEBUG_H -#include <QtCore/qalgorithms.h> -#include <QtCore/qhash.h> -#include <QtCore/qlist.h> -#include <QtCore/qmap.h> +#if 0 +#pragma qt_class(QtDebug) +#endif + +#include <QtCore/qcontainerfwd.h> #include <QtCore/qtextstream.h> +#include <QtCore/qtypes.h> #include <QtCore/qstring.h> -#include <QtCore/qset.h> -#include <QtCore/qvarlengtharray.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 <vector> +#include <chrono> #include <list> #include <map> +#include <optional> +#include <string> +#include <string_view> #include <utility> +#include <vector> -QT_BEGIN_NAMESPACE +#if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1 +# include <QtCore/qlist.h> +# include <QtCore/qmap.h> +# include <QtCore/qset.h> +# include <QtCore/qvarlengtharray.h> +#endif +QT_BEGIN_NAMESPACE -class Q_CORE_EXPORT QDebug : public QIODeviceBase +class QT6_ONLY(Q_CORE_EXPORT) QDebug : public QIODeviceBase { friend class QMessageLogger; friend class QDebugStateSaver; @@ -93,21 +67,24 @@ class Q_CORE_EXPORT QDebug : public QIODeviceBase enum Latin1Content { ContainsBinary = 0, ContainsLatin1 }; - void putUcs4(uint ucs4); - void putString(const QChar *begin, size_t length); - void putByteArray(const char *begin, size_t length, Latin1Content content); + 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)) {} explicit QDebug(QtMsgType t) : stream(new Stream(t)) {} QDebug(const QDebug &o) : stream(o.stream) { ++stream->ref; } - QDebug(QDebug &&other) noexcept : stream{qExchange(other.stream, nullptr)} {} + QDebug(QDebug &&other) noexcept : stream{std::exchange(other.stream, nullptr)} {} inline QDebug &operator=(const QDebug &other); QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QDebug) ~QDebug(); void swap(QDebug &other) noexcept { qt_ptr_swap(stream, other.stream); } - QDebug &resetFormat(); + QT7_ONLY(Q_CORE_EXPORT) QDebug &resetFormat(); inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; } inline QDebug &nospace() { stream->space = false; return *this; } @@ -120,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 "e() { 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; } @@ -129,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(); } @@ -137,20 +117,20 @@ 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(); } inline QDebug &operator<<(const char16_t *t) { stream->ts << QStringView(t); return maybeSpace(); } -#if QT_STRINGVIEW_LEVEL < 2 - inline QDebug &operator<<(const QString & t) { putString(t.constData(), uint(t.length())); return maybeSpace(); } -#endif + inline QDebug &operator<<(const QString & t) { putString(t.constData(), size_t(t.size())); return maybeSpace(); } inline QDebug &operator<<(QStringView s) { putString(s.data(), size_t(s.size())); return maybeSpace(); } inline QDebug &operator<<(QUtf8StringView s) { putByteArray(reinterpret_cast<const char*>(s.data()), s.size(), ContainsBinary); return maybeSpace(); } - inline QDebug &operator<<(QLatin1String t) { putByteArray(t.latin1(), t.size(), ContainsLatin1); return maybeSpace(); } + inline QDebug &operator<<(QLatin1StringView t) { putByteArray(t.latin1(), t.size(), ContainsLatin1); return maybeSpace(); } inline QDebug &operator<<(const QByteArray & t) { putByteArray(t.constData(), t.size(), ContainsBinary); return maybeSpace(); } 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; @@ -159,6 +139,89 @@ public: inline QDebug &operator<<(QTextStreamManipulator m) { stream->ts << m; return *this; } +#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); } + + template <typename...Args> + QDebug &operator<<(std::basic_string_view<char, Args...> s) + { return *this << QUtf8StringView(s); } + +#ifdef __cpp_char8_t + template <typename...Args> + QDebug &operator<<(const std::basic_string<char8_t, Args...> &s) + { return *this << QUtf8StringView(s); } + + template <typename...Args> + QDebug &operator<<(std::basic_string_view<char8_t, Args...> s) + { return *this << QUtf8StringView(s); } +#endif // __cpp_char8_t + + template <typename...Args> + QDebug &operator<<(const std::basic_string<char16_t, Args...> &s) + { return *this << QStringView(s); } + + template <typename...Args> + QDebug &operator<<(std::basic_string_view<char16_t, Args...> s) + { return *this << QStringView(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()); } + + 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) { @@ -172,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) @@ -248,66 +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(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> @@ -321,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> @@ -329,7 +411,7 @@ inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QContiguousCache { const QDebugStateSaver saver(debug); debug.nospace() << "QContiguousCache("; - for (int i = cache.firstIndex(); i <= cache.lastIndex(); ++i) { + for (qsizetype i = cache.firstIndex(); i <= cache.lastIndex(); ++i) { debug << cache[i]; if (i != cache.lastIndex()) debug << ", "; @@ -373,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) @@ -410,7 +489,7 @@ void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, Int value) debug.resetFormat(); debug.nospace() << "QFlags(" << Qt::hex << Qt::showbase; bool needSeparator = false; - for (uint i = 0; i < sizeofT * 8; ++i) { + for (size_t i = 0; i < sizeofT * 8; ++i) { if (value & (Int(1) << i)) { if (needSeparator) debug << '|'; @@ -492,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 @@ -529,6 +608,7 @@ inline QDebug operator<<(QDebug debug, QKeyCombination combination) QT_END_NAMESPACE Q_FORWARD_DECLARE_CF_TYPE(CFString); +struct objc_object; Q_FORWARD_DECLARE_OBJC_CLASS(NSObject); QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_CF_TYPE) QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_MUTABLE_CF_TYPE) @@ -553,6 +633,10 @@ QT_BEGIN_NAMESPACE } // Defined in qcore_mac_objc.mm +#if defined(__OBJC__) +Q_CORE_EXPORT QDebug operator<<(QDebug, id); +#endif +Q_CORE_EXPORT QDebug operator<<(QDebug, objc_object *); Q_CORE_EXPORT QDebug operator<<(QDebug, const NSObject *); Q_CORE_EXPORT QDebug operator<<(QDebug, CFStringRef); @@ -566,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 |