Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdebug.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qdebug.h"
6#include "private/qdebug_p.h"
7#include "qmetaobject.h"
8#include <private/qlogging_p.h>
9#include <private/qtextstream_p.h>
10#include <private/qtools_p.h>
11
12#include <array>
13#include <q20chrono.h>
14#include <cstdio>
15
17
18using namespace QtMiscUtils;
19
20/*
21 Returns a human readable representation of the first \a maxSize
22 characters in \a data. The size, \a len, is a 64-bit quantity to
23 avoid truncation due to implicit conversions in callers.
24*/
25QByteArray QtDebugUtils::toPrintable(const char *data, qint64 len, qsizetype maxSize)
26{
27 if (!data)
28 return "(null)";
29
30 QByteArray out;
31 for (qsizetype i = 0; i < qMin(len, maxSize); ++i) {
32 char c = data[i];
33 if (isAsciiPrintable(c)) {
34 out += c;
35 } else {
36 switch (c) {
37 case '\n':
38 out += "\\n";
39 break;
40 case '\r':
41 out += "\\r";
42 break;
43 case '\t':
44 out += "\\t";
45 break;
46 default: {
47 const char buf[] = {
48 '\\',
49 'x',
50 toHexLower(uchar(c) / 16),
51 toHexLower(uchar(c) % 16),
52 0
53 };
54 out += buf;
55 }
56 }
57 }
58 }
59
60 if (maxSize < len)
61 out += "...";
62
63 return out;
64}
65
66// This file is needed to force compilation of QDebug into the kernel library.
67
68/*!
69 \class QDebug
70 \inmodule QtCore
71 \ingroup shared
72
73 \brief The QDebug class provides an output stream for debugging information.
74
75 QDebug is used whenever the developer needs to write out debugging or tracing
76 information to a device, file, string or console.
77
78 \section1 Basic Use
79
80 In the common case, it is useful to call the qDebug() function to obtain a
81 default QDebug object to use for writing debugging information.
82
83 \snippet qdebug/qdebugsnippet.cpp 1
84
85 This constructs a QDebug object using the constructor that accepts a QtMsgType
86 value of QtDebugMsg. Similarly, the qWarning(), qCritical() and qFatal()
87 functions also return QDebug objects for the corresponding message types.
88
89 The class also provides several constructors for other situations, including
90 a constructor that accepts a QFile or any other QIODevice subclass that is
91 used to write debugging information to files and other devices. The constructor
92 that accepts a QString is used to write to a string for display or serialization.
93
94 \section1 Formatting Options
95
96 QDebug formats output so that it's easily readable. It automatically adds spaces
97 between arguments, and adds quotes around QString, QByteArray, QChar arguments.
98
99 You can tweak these options through the space(), nospace() and quote(), noquote()
100 methods. Furthermore, \l{QTextStream manipulators} can be piped into a QDebug
101 stream.
102
103 QDebugStateSaver limits changes to the formatting to the current scope.
104 resetFormat() resets the options to the default ones.
105
106 \section1 Writing Custom Types to a Stream
107
108 Many standard types can be written to QDebug objects, and Qt provides support for
109 most Qt value types. To add support for custom types, you need to implement a
110 streaming operator, as in the following example:
111
112 \snippet qdebug/qdebugsnippet.cpp 0
113
114 This is described in the \l{Debugging Techniques} and
115 \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
116 documents.
117*/
118
119/*!
120 \fn QDebug::QDebug(QIODevice *device)
121
122 Constructs a debug stream that writes to the given \a device.
123*/
124
125/*!
126 \fn QDebug::QDebug(QString *string)
127
128 Constructs a debug stream that writes to the given \a string.
129*/
130
131/*!
132 \fn QDebug::QDebug(QtMsgType t)
133
134 Constructs a debug stream that writes to the handler for the message type \a t.
135*/
136
137/*!
138 \fn QDebug::QDebug(const QDebug &o)
139
140 Constructs a copy of the other debug stream \a o.
141*/
142
143/*!
144 \fn QDebug &QDebug::operator=(const QDebug &other)
145
146 Assigns the \a other debug stream to this stream and returns a reference to
147 this stream.
148*/
149
150/*!
151 \fn QDebug::~QDebug()
152
153 Flushes any pending data to be written and destroys the debug stream.
154*/
155QDebug::~QDebug()
156{
157 if (stream && !--stream->ref) {
158 if (stream->space && stream->buffer.endsWith(u' '))
159 stream->buffer.chop(1);
160 if (stream->message_output) {
161 QInternalMessageLogContext ctxt(stream->context);
162 qt_message_output(stream->type,
163 ctxt,
164 stream->buffer);
165 }
166 delete stream;
167 }
168}
169
170/*!
171 \internal
172*/
173void QDebug::putUcs4(uint ucs4)
174{
175 maybeQuote('\'');
176 if (ucs4 < 0x20) {
177 stream->ts << "\\x" << Qt::hex << ucs4 << Qt::reset;
178 } else if (ucs4 < 0x80) {
179 stream->ts << char(ucs4);
180 } else {
181 if (ucs4 < 0x10000)
182 stream->ts << "\\u" << qSetFieldWidth(4);
183 else
184 stream->ts << "\\U" << qSetFieldWidth(8);
185 stream->ts << Qt::hex << qSetPadChar(u'0') << ucs4 << Qt::reset;
186 }
187 maybeQuote('\'');
188}
189
190// These two functions return true if the character should be printed by QDebug.
191// For QByteArray, this is technically identical to US-ASCII isprint();
192// for QString, we use QChar::isPrint, which requires a full UCS-4 decode.
193static inline bool isPrintable(char32_t ucs4) { return QChar::isPrint(ucs4); }
194static inline bool isPrintable(char16_t uc) { return QChar::isPrint(uc); }
195static inline bool isPrintable(uchar c)
196{ return isAsciiPrintable(c); }
197
198template <typename Char>
199static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode = true)
200{
201 QChar quote(u'"');
202 d->write(&quote, 1);
203
204 bool lastWasHexEscape = false;
205 const Char *end = begin + length;
206 for (const Char *p = begin; p != end; ++p) {
207 // check if we need to insert "" to break an hex escape sequence
208 if (Q_UNLIKELY(lastWasHexEscape)) {
209 if (fromHex(*p) != -1) {
210 // yes, insert it
211 QChar quotes[] = { quote, quote };
212 d->write(quotes, 2);
213 }
214 lastWasHexEscape = false;
215 }
216
217 if (sizeof(Char) == sizeof(QChar)) {
218 // Surrogate characters are category Cs (Other_Surrogate), so isPrintable = false for them
219 qsizetype runLength = 0;
220 while (p + runLength != end &&
221 isPrintable(p[runLength]) && p[runLength] != '\\' && p[runLength] != '"')
222 ++runLength;
223 if (runLength) {
224 d->write(reinterpret_cast<const QChar *>(p), runLength);
225 p += runLength - 1;
226 continue;
227 }
228 } else if (isPrintable(*p) && *p != '\\' && *p != '"') {
229 QChar c = QLatin1Char(*p);
230 d->write(&c, 1);
231 continue;
232 }
233
234 // print as an escape sequence (maybe, see below for surrogate pairs)
235 qsizetype buflen = 2;
236 char16_t buf[std::char_traits<char>::length("\\U12345678")];
237 buf[0] = '\\';
238
239 switch (*p) {
240 case '"':
241 case '\\':
242 buf[1] = *p;
243 break;
244 case '\b':
245 buf[1] = 'b';
246 break;
247 case '\f':
248 buf[1] = 'f';
249 break;
250 case '\n':
251 buf[1] = 'n';
252 break;
253 case '\r':
254 buf[1] = 'r';
255 break;
256 case '\t':
257 buf[1] = 't';
258 break;
259 default:
260 if (!isUnicode) {
261 // print as hex escape
262 buf[1] = 'x';
263 buf[2] = toHexUpper(uchar(*p) >> 4);
264 buf[3] = toHexUpper(uchar(*p));
265 buflen = 4;
266 lastWasHexEscape = true;
267 break;
268 }
269 if (QChar::isHighSurrogate(*p)) {
270 if ((p + 1) != end && QChar::isLowSurrogate(p[1])) {
271 // properly-paired surrogates
272 char32_t ucs4 = QChar::surrogateToUcs4(*p, p[1]);
273 if (isPrintable(ucs4)) {
274 buf[0] = *p;
275 buf[1] = p[1];
276 buflen = 2;
277 } else {
278 buf[1] = 'U';
279 buf[2] = '0'; // toHexUpper(ucs4 >> 32);
280 buf[3] = '0'; // toHexUpper(ucs4 >> 28);
281 buf[4] = toHexUpper(ucs4 >> 20);
282 buf[5] = toHexUpper(ucs4 >> 16);
283 buf[6] = toHexUpper(ucs4 >> 12);
284 buf[7] = toHexUpper(ucs4 >> 8);
285 buf[8] = toHexUpper(ucs4 >> 4);
286 buf[9] = toHexUpper(ucs4);
287 buflen = 10;
288 }
289 ++p;
290 break;
291 }
292 // improperly-paired surrogates, fall through
293 }
294 buf[1] = 'u';
295 buf[2] = toHexUpper(char16_t(*p) >> 12);
296 buf[3] = toHexUpper(char16_t(*p) >> 8);
297 buf[4] = toHexUpper(*p >> 4);
298 buf[5] = toHexUpper(*p);
299 buflen = 6;
300 }
301 d->write(reinterpret_cast<QChar *>(buf), buflen);
302 }
303
304 d->write(&quote, 1);
305}
306
307/*!
308 \internal
309 Duplicated from QtTest::toPrettyUnicode().
310*/
311void QDebug::putString(const QChar *begin, size_t length)
312{
313 if (stream->noQuotes) {
314 // no quotes, write the string directly too (no pretty-printing)
315 // this respects the QTextStream state, though
316 stream->ts.d_ptr->putString(begin, qsizetype(length));
317 } else {
318 // we'll reset the QTextStream formatting mechanisms, so save the state
319 QDebugStateSaver saver(*this);
320 stream->ts.d_ptr->params.reset();
321 putEscapedString(stream->ts.d_ptr.get(), reinterpret_cast<const char16_t *>(begin), length);
322 }
323}
324
325/*!
326 \internal
327 Duplicated from QtTest::toPrettyCString().
328*/
329void QDebug::putByteArray(const char *begin, size_t length, Latin1Content content)
330{
331 if (stream->noQuotes) {
332 // no quotes, write the string directly too (no pretty-printing)
333 // this respects the QTextStream state, though
334 QString string = content == ContainsLatin1 ? QString::fromLatin1(begin, qsizetype(length))
335 : QString::fromUtf8(begin, qsizetype(length));
336 stream->ts.d_ptr->putString(string);
337 } else {
338 // we'll reset the QTextStream formatting mechanisms, so save the state
339 QDebugStateSaver saver(*this);
340 stream->ts.d_ptr->params.reset();
341 putEscapedString(stream->ts.d_ptr.get(), reinterpret_cast<const uchar *>(begin),
342 length, content == ContainsLatin1);
343 }
344}
345
346static QByteArray timeUnit(qint64 num, qint64 den)
347{
348 using namespace std::chrono;
349 using namespace q20::chrono;
350
351 if (num == 1 && den > 1) {
352 // sub-multiple of seconds
353 char prefix = '\0';
354 auto tryprefix = [&](auto d, char c) {
355 static_assert(decltype(d)::num == 1, "not an SI prefix");
356 if (den == decltype(d)::den)
357 prefix = c;
358 };
359
360 // "u" should be "ยต", but debugging output is not always UTF-8-safe
361 tryprefix(std::milli{}, 'm');
362 tryprefix(std::micro{}, 'u');
363 tryprefix(std::nano{}, 'n');
364 tryprefix(std::pico{}, 'p');
365 tryprefix(std::femto{}, 'f');
366 tryprefix(std::atto{}, 'a');
367 // uncommon ones later
368 tryprefix(std::centi{}, 'c');
369 tryprefix(std::deci{}, 'd');
370 if (prefix) {
371 char unit[3] = { prefix, 's' };
372 return QByteArray(unit, sizeof(unit) - 1);
373 }
374 }
375
376 const char *unit = nullptr;
377 if (num > 1 && den == 1) {
378 // multiple of seconds - but we don't use SI prefixes
379 auto tryunit = [&](auto d, const char *name) {
380 static_assert(decltype(d)::period::den == 1, "not a multiple of a second");
381 if (unit || num % decltype(d)::period::num)
382 return;
383 unit = name;
384 num /= decltype(d)::period::num;
385 };
386 tryunit(years{}, "yr");
387 tryunit(weeks{}, "wk");
388 tryunit(days{}, "d");
389 tryunit(hours{}, "h");
390 tryunit(minutes{}, "min");
391 }
392 if (!unit)
393 unit = "s";
394
395 if (num == 1 && den == 1)
396 return unit;
397 if (Q_UNLIKELY(num < 1 || den < 1))
398 return QString::asprintf("<invalid time unit %lld/%lld>", num, den).toLatin1();
399
400 // uncommon units: will return something like "[2/3]s"
401 // strlen("[/]min") = 6
402 char buf[2 * (std::numeric_limits<qint64>::digits10 + 2) + 10];
403 size_t len = 0;
404 auto appendChar = [&](char c) {
405 Q_ASSERT(len < sizeof(buf));
406 buf[len++] = c;
407 };
408 auto appendNumber = [&](qint64 value) {
409 if (value >= 10'000 && (value % 1000) == 0)
410 len += std::snprintf(buf + len, sizeof(buf) - len, "%.6g", double(value)); // "1e+06"
411 else
412 len += std::snprintf(buf + len, sizeof(buf) - len, "%lld", value);
413 };
414 appendChar('[');
415 appendNumber(num);
416 if (den != 1) {
417 appendChar('/');
418 appendNumber(den);
419 }
420 appendChar(']');
421 memcpy(buf + len, unit, strlen(unit));
422 return QByteArray(buf, len + strlen(unit));
423}
424
425/*!
426 \since 6.6
427 \internal
428 Helper to the std::chrono::duration debug streaming output.
429 */
430void QDebug::putTimeUnit(qint64 num, qint64 den)
431{
432 stream->ts << timeUnit(num, den); // ### optimize
433}
434
435namespace {
436
437#ifdef QT_SUPPORTS_INT128
438
439constexpr char Q_INT128_MIN_STR[] = "-170141183460469231731687303715884105728";
440
441constexpr int Int128BufferSize = sizeof(Q_INT128_MIN_STR);
442using Int128Buffer = std::array<char, Int128BufferSize>;
443 // numeric_limits<qint128>::digits10 may not exist
444
445static char *i128ToStringHelper(Int128Buffer &buffer, quint128 n)
446{
447 auto dst = buffer.data() + buffer.size();
448 *--dst = '\0'; // NUL-terminate
449 if (n == 0) {
450 *--dst = '0'; // and done
451 } else {
452 while (n != 0) {
453 *--dst = "0123456789"[n % 10];
454 n /= 10;
455 }
456 }
457 return dst;
458}
459#endif // QT_SUPPORTS_INT128
460
461[[maybe_unused]]
462static const char *int128Warning()
463{
464 const char *msg = "Qt was not compiled with int128 support.";
465 qWarning("%s", msg);
466 return msg;
467}
468
469} // unnamed namespace
470
471/*!
472 \since 6.7
473 \internal
474 Helper to the qint128 debug streaming output.
475 */
476void QDebug::putInt128([[maybe_unused]] const void *p)
477{
478#ifdef QT_SUPPORTS_INT128
479 Q_ASSERT(p);
480 qint128 i;
481 memcpy(&i, p, sizeof(i)); // alignment paranoia
482 if (i == Q_INT128_MIN) {
483 // -i is not representable, hardcode the result:
484 stream->ts << Q_INT128_MIN_STR;
485 } else {
486 Int128Buffer buffer;
487 auto dst = i128ToStringHelper(buffer, i < 0 ? -i : i);
488 if (i < 0)
489 *--dst = '-';
490 stream->ts << dst;
491 }
492 return;
493#endif // QT_SUPPORTS_INT128
494 stream->ts << int128Warning();
495}
496
497/*!
498 \since 6.7
499 \internal
500 Helper to the quint128 debug streaming output.
501 */
502void QDebug::putUInt128([[maybe_unused]] const void *p)
503{
504#ifdef QT_SUPPORTS_INT128
505 Q_ASSERT(p);
506 quint128 i;
507 memcpy(&i, p, sizeof(i)); // alignment paranoia
508 Int128Buffer buffer;
509 stream->ts << i128ToStringHelper(buffer, i);
510 return;
511#endif // QT_SUPPORTS_INT128
512 stream->ts << int128Warning();
513}
514
515/*!
516 \since 6.9
517 \internal
518 Helper to the <Std/Qt>::<>_ordering debug output.
519 It generates the string in following format:
520 <Qt/Std>::<weak/partial/strong>_ordering::<less/equal/greater/unordered>
521 */
522void QDebug::putQtOrdering(QtOrderingPrivate::QtOrderingTypeFlag flags, Qt::partial_ordering order)
523{
524 using QtOrderingPrivate::QtOrderingType;
525 std::string result;
526 if ((flags & QtOrderingType::StdOrder) == QtOrderingType::StdOrder)
527 result += "std";
528 else if ((flags & QtOrderingType::QtOrder) == QtOrderingType::QtOrder)
529 result += "Qt";
530
531 result += "::";
532 const bool isStrong = ((flags & QtOrderingType::Strong) == QtOrderingType::Strong);
533 if (isStrong)
534 result += "strong";
535 else if ((flags & QtOrderingType::Weak) == QtOrderingType::Weak)
536 result += "weak";
537 else if ((flags & QtOrderingType::Partial) == QtOrderingType::Partial)
538 result += "partial";
539 result += "_ordering::";
540
541 if (order == Qt::partial_ordering::equivalent) {
542 if (isStrong)
543 result += "equal";
544 else
545 result += "equivalent";
546 } else if (order == Qt::partial_ordering::greater) {
547 result += "greater";
548 } else if (order == Qt::partial_ordering::less) {
549 result += "less";
550 } else {
551 result += "unordered";
552 }
553 stream->ts << result.data();
554}
555
556/*!
557 \fn QDebug::swap(QDebug &other)
558 \since 5.0
559 \memberswap{debug stream instance}
560*/
561
562/*!
563 Resets the stream formatting options, bringing it back to its original constructed state.
564
565 \sa space(), quote()
566 \since 5.4
567*/
568QDebug &QDebug::resetFormat()
569{
570 stream->ts.reset();
571 stream->space = true;
572 stream->noQuotes = false;
573 stream->verbosity = DefaultVerbosity;
574 return *this;
575}
576
577/*!
578 \fn QDebug &QDebug::space()
579
580 Writes a space character to the debug stream and returns a reference to
581 the stream.
582
583 The stream remembers that automatic insertion of spaces is
584 enabled for future writes.
585
586 \sa nospace(), maybeSpace()
587*/
588
589/*!
590 \fn QDebug &QDebug::nospace()
591
592 Disables automatic insertion of spaces and returns a reference to the stream.
593
594 \sa space(), maybeSpace()
595*/
596
597/*!
598 \fn QDebug &QDebug::maybeSpace()
599
600 Writes a space character to the debug stream, depending on the current
601 setting for automatic insertion of spaces, and returns a reference to the stream.
602
603 \sa space(), nospace()
604*/
605
606/*!
607 \fn bool QDebug::autoInsertSpaces() const
608
609 Returns \c true if this QDebug instance will automatically insert spaces
610 between writes.
611
612 \since 5.0
613
614 \sa QDebugStateSaver
615*/
616
617/*!
618 \fn void QDebug::setAutoInsertSpaces(bool b)
619
620 Enables automatic insertion of spaces between writes if \a b is true; otherwise
621 automatic insertion of spaces is disabled.
622
623 \since 5.0
624
625 \sa QDebugStateSaver
626*/
627
628
629/*!
630 \fn bool QDebug::quoteStrings() const
631 \since 6.7
632
633 Returns \c true if this QDebug instance will quote strings streamed into
634 it (which is the default).
635
636 \sa QDebugStateSaver, quote(), noquote(), setQuoteStrings()
637*/
638
639/*!
640 \fn void QDebug::setQuoteStrings(bool b)
641 \since 6.7
642
643 Enables quoting of strings streamed into this QDebug instance if \a b is
644 \c true; otherwise quoting is disabled.
645
646 The default is to quote strings.
647
648 \sa QDebugStateSaver, quote(), noquote(), quoteStrings()
649*/
650
651
652/*!
653 \fn QDebug &QDebug::quote()
654 \since 5.4
655
656 Enables automatic insertion of quotation characters around QChar, QString and QByteArray
657 contents and returns a reference to the stream.
658
659 Quoting is enabled by default.
660
661 \sa noquote(), maybeQuote()
662*/
663
664/*!
665 \fn QDebug &QDebug::noquote()
666 \since 5.4
667
668 Disables automatic insertion of quotation characters around QChar, QString and QByteArray
669 contents and returns a reference to the stream.
670
671 When quoting is disabled, these types are printed without quotation
672 characters and without escaping of non-printable characters.
673
674 \sa quote(), maybeQuote()
675*/
676
677/*!
678 \fn QDebug &QDebug::maybeQuote(char c)
679 \since 5.4
680
681 Writes a character \a c to the debug stream, depending on the
682 current setting for automatic insertion of quotes, and returns a reference to the stream.
683
684 The default character is a double quote \c{"}.
685
686 \sa quote(), noquote()
687*/
688
689/*!
690 \fn int QDebug::verbosity() const
691 \since 5.6
692
693 Returns the verbosity of the debug stream.
694
695 Streaming operators can check the value to decide whether
696 verbose output is desired and print more information depending on the
697 level. Higher values indicate that more information is desired.
698
699 The allowed range is from 0 to 7. The default value is 2.
700
701 \sa setVerbosity(), VerbosityLevel
702*/
703
704/*!
705 \fn void QDebug::setVerbosity(int verbosityLevel)
706 \since 5.6
707
708 Sets the verbosity of the stream to \a verbosityLevel.
709
710 The allowed range is from 0 to 7. The default value is 2.
711
712 \sa verbosity(), VerbosityLevel
713*/
714
715/*!
716 \fn QDebug &QDebug::verbosity(int verbosityLevel)
717 \since 5.13
718
719 Sets the verbosity of the stream to \a verbosityLevel and returns a reference to the stream.
720
721 The allowed range is from 0 to 7. The default value is 2.
722
723 \sa verbosity(), setVerbosity(), VerbosityLevel
724*/
725
726/*!
727 \enum QDebug::VerbosityLevel
728 \since 5.13
729
730 This enum describes the range of verbosity levels.
731
732 \value MinimumVerbosity
733 \value DefaultVerbosity
734 \value MaximumVerbosity
735
736 \sa verbosity(), setVerbosity()
737*/
738
739/*!
740 \fn QDebug &QDebug::operator<<(QChar t)
741
742 Writes the character, \a t, to the stream and returns a reference to the
743 stream. Normally, QDebug prints control characters and non-US-ASCII
744 characters as their C escape sequences or their Unicode value (\\u1234). To
745 print non-printable characters without transformation, enable the noquote()
746 functionality, but note that some QDebug backends may not be 8-bit clean
747 and may not be able to represent \c t.
748*/
749
750/*!
751 \fn QDebug &QDebug::operator<<(bool t)
752
753 Writes the boolean value, \a t, to the stream and returns a reference to the
754 stream.
755*/
756
757/*!
758 \fn QDebug &QDebug::operator<<(char t)
759
760 Writes the character, \a t, to the stream and returns a reference to the
761 stream.
762*/
763
764/*!
765 \fn QDebug &QDebug::operator<<(signed short t)
766
767 Writes the signed short integer, \a t, to the stream and returns a reference
768 to the stream.
769*/
770
771/*!
772 \fn QDebug &QDebug::operator<<(unsigned short t)
773
774 Writes then unsigned short integer, \a t, to the stream and returns a
775 reference to the stream.
776*/
777
778/*!
779 \fn QDebug &QDebug::operator<<(signed int t)
780
781 Writes the signed integer, \a t, to the stream and returns a reference
782 to the stream.
783*/
784
785/*!
786 \fn QDebug &QDebug::operator<<(unsigned int t)
787
788 Writes then unsigned integer, \a t, to the stream and returns a reference to
789 the stream.
790*/
791
792/*!
793 \fn QDebug &QDebug::operator<<(signed long t)
794
795 Writes the signed long integer, \a t, to the stream and returns a reference
796 to the stream.
797*/
798
799/*!
800 \fn QDebug &QDebug::operator<<(unsigned long t)
801
802 Writes then unsigned long integer, \a t, to the stream and returns a reference
803 to the stream.
804*/
805
806/*!
807 \fn QDebug &QDebug::operator<<(qint64 t)
808
809 Writes the signed 64-bit integer, \a t, to the stream and returns a reference
810 to the stream.
811*/
812
813/*!
814 \fn QDebug &QDebug::operator<<(quint64 t)
815
816 Writes then unsigned 64-bit integer, \a t, to the stream and returns a
817 reference to the stream.
818*/
819
820/*!
821 \fn QDebug &QDebug::operator<<(float t)
822
823 Writes the 32-bit floating point number, \a t, to the stream and returns a
824 reference to the stream.
825*/
826
827/*!
828 \fn QDebug &QDebug::operator<<(double t)
829
830 Writes the 64-bit floating point number, \a t, to the stream and returns a
831 reference to the stream.
832*/
833
834/*!
835 \fn QDebug &QDebug::operator<<(const char *t)
836
837 Writes the '\\0'-terminated UTF-8 string, \a t, to the stream and returns a
838 reference to the stream. The string is never quoted or escaped for the
839 output. Note that QDebug buffers internally as UTF-16 and may need to
840 transform to 8-bit using the locale's codec in order to use some backends,
841 which may cause garbled output (mojibake). Restricting to US-ASCII strings
842 is recommended.
843*/
844
845/*!
846 \fn QDebug &QDebug::operator<<(const char16_t *t)
847 \since 6.0
848
849 Writes the u'\\0'-terminated UTF-16 string, \a t, to the stream and returns
850 a reference to the stream. The string is never quoted or escaped for the
851 output. Note that QDebug buffers internally as UTF-16 and may need to
852 transform to 8-bit using the locale's codec in order to use some backends,
853 which may cause garbled output (mojibake). Restricting to US-ASCII strings
854 is recommended.
855*/
856
857/*!
858 \fn QDebug &QDebug::operator<<(char16_t t)
859 \since 5.5
860
861 Writes the UTF-16 character, \a t, to the stream and returns a reference
862 to the stream.
863*/
864
865/*!
866 \fn QDebug &QDebug::operator<<(char32_t t)
867 \since 5.5
868
869 Writes the UTF-32 character, \a t, to the stream and returns a reference
870 to the stream.
871*/
872
873/*!
874 \fn QDebug &QDebug::operator<<(const QString &t)
875
876 Writes the string, \a t, to the stream and returns a reference to the
877 stream. Normally, QDebug prints the string inside quotes and transforms
878 non-printable characters to their Unicode values (\\u1234).
879
880 To print non-printable characters without transformation, enable the
881 noquote() functionality. Note that some QDebug backends might not be 8-bit
882 clean.
883
884 Output examples:
885 \snippet code/src_corelib_io_qdebug.cpp 0
886*/
887
888/*!
889 \since 5.10
890 \fn QDebug &QDebug::operator<<(QStringView s)
891
892 Writes the string view, \a s, to the stream and returns a reference to the
893 stream. Normally, QDebug prints the string inside quotes and transforms
894 non-printable characters to their Unicode values (\\u1234).
895
896 To print non-printable characters without transformation, enable the
897 noquote() functionality. Note that some QDebug backends might not be 8-bit
898 clean.
899
900 See the QString overload for examples.
901*/
902
903/*!
904 \since 6.0
905 \fn QDebug &QDebug::operator<<(QUtf8StringView s)
906
907 Writes the string view, \a s, to the stream and returns a reference to the
908 stream.
909
910 Normally, QDebug prints the data inside quotes and transforms control or
911 non-US-ASCII characters to their C escape sequences (\\xAB). This way, the
912 output is always 7-bit clean and the string can be copied from the output
913 and pasted back into C++ sources, if necessary.
914
915 To print non-printable characters without transformation, enable the
916 noquote() functionality. Note that some QDebug backends might not be 8-bit
917 clean.
918*/
919
920/*!
921 \fn QDebug &QDebug::operator<<(QLatin1StringView t)
922
923 Writes the string, \a t, to the stream and returns a reference to the
924 stream. Normally, QDebug prints the string inside quotes and transforms
925 non-printable characters to their Unicode values (\\u1234).
926
927 To print non-printable characters without transformation, enable the
928 noquote() functionality. Note that some QDebug backends might not be 8-bit
929 clean.
930
931 See the QString overload for examples.
932*/
933
934/*!
935 \fn QDebug &QDebug::operator<<(const QByteArray &t)
936
937 Writes the byte array, \a t, to the stream and returns a reference to the
938 stream. Normally, QDebug prints the array inside quotes and transforms
939 control or non-US-ASCII characters to their C escape sequences (\\xAB). This
940 way, the output is always 7-bit clean and the string can be copied from the
941 output and pasted back into C++ sources, if necessary.
942
943 To print non-printable characters without transformation, enable the
944 noquote() functionality. Note that some QDebug backends might not be 8-bit
945 clean.
946
947 Output examples:
948 \snippet code/src_corelib_io_qdebug.cpp 1
949
950 Note how QDebug needed to close and reopen the string in the way C and C++
951 languages concatenate string literals so that the letter 'b' is not
952 interpreted as part of the previous hexadecimal escape sequence.
953*/
954
955/*!
956 \since 6.0
957 \fn QDebug &QDebug::operator<<(QByteArrayView t)
958
959 Writes the data of the observed byte array, \a t, to the stream and returns
960 a reference to the stream.
961
962 Normally, QDebug prints the data inside quotes and transforms control or
963 non-US-ASCII characters to their C escape sequences (\\xAB). This way, the
964 output is always 7-bit clean and the string can be copied from the output
965 and pasted back into C++ sources, if necessary.
966
967 To print non-printable characters without transformation, enable the
968 noquote() functionality. Note that some QDebug backends might not be 8-bit
969 clean.
970
971 See the QByteArray overload for examples.
972*/
973
974/*!
975 \fn QDebug &QDebug::operator<<(const void *t)
976
977 Writes a pointer, \a t, to the stream and returns a reference to the stream.
978*/
979
980/*!
981 \fn QDebug &QDebug::operator<<(QTextStreamFunction f)
982 \internal
983*/
984
985/*!
986 \fn QDebug &QDebug::operator<<(QTextStreamManipulator m)
987 \internal
988*/
989
990/*!
991 \fn template <typename T, QDebug::if_ordering_type<T>> QDebug::operator<<(QDebug debug, T t)
992 \since 6.9
993 Prints the Qt or std ordering value \a t to the \a debug object.
994
995 \constraints \c T is one of <Qt/Std>::<weak/partial/strong>_ordering.
996*/
997
998/*!
999 \since 6.5
1000 \fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(const std::basic_string<Char, Args...> &s)
1001 \fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(std::basic_string_view<Char, Args...> s)
1002
1003 Writes the string or string-view \a s to the stream and returns a reference
1004 to the stream.
1005
1006 These operators only participate in overload resolution if \c Char is one of
1007 \list
1008 \li char
1009 \li char8_t (C++20 only)
1010 \li char16_t
1011 \li char32_t
1012 \li wchar_t
1013 \endlist
1014*/
1015
1016/*!
1017 \since 6.6
1018 \fn template <typename Rep, typename Period> QDebug &QDebug::operator<<(std::chrono::duration<Rep, Period> duration)
1019
1020 Prints the time duration \a duration to the stream and returns a reference
1021 to the stream. The printed string is the numeric representation of the
1022 period followed by the time unit, similar to what the C++ Standard Library
1023 would produce with \c{std::ostream}.
1024
1025 The unit is not localized.
1026*/
1027
1028/*!
1029 \fn template <typename T, QDebug::if_qint128<T>> QDebug::operator<<(T i)
1030 \fn template <typename T, QDebug::if_quint128<T>> QDebug::operator<<(T i)
1031 \since 6.7
1032
1033 Prints the textual representation of the 128-bit integer \a i.
1034
1035 \note This operator is only available if Qt supports 128-bit integer types.
1036 If 128-bit integer types are available in your build, but the Qt libraries
1037 were compiled without, the operator will print a warning instead.
1038
1039 \note Because the operator is a function template, no implicit conversions
1040 are performed on its argument. It must be exactly qint128/quint128.
1041
1042 \sa QT_SUPPORTS_INT128
1043*/
1044
1045/*!
1046 \fn template <class T> QString QDebug::toString(const T &object)
1047 \since 6.0
1048
1049 \include qdebug-toString.qdocinc
1050
1051 \sa toBytes()
1052*/
1053
1054/*! \internal */
1055QString QDebug::toStringImpl(StreamTypeErased s, const void *obj)
1056{
1057 QString result;
1058 {
1059 QDebug d(&result);
1060 s(d.nospace(), obj);
1061 }
1062 return result;
1063}
1064
1065/*!
1066 \fn template <class T> QByteArray QDebug::toBytes(const T &object)
1067 \since 6.9
1068
1069 This is equivalent to passing \a object to
1070 \c{QDebug::toString(object).toUtf8()}, but more efficient.
1071
1072 \sa toString()
1073*/
1074
1075/*! \internal */
1076QByteArray QDebug::toBytesImpl(StreamTypeErased s, const void *obj)
1077{
1078 QByteArray result;
1079 {
1080 QDebug d(&result);
1081 s(d.nospace(), obj);
1082 }
1083 return result;
1084}
1085
1086/*!
1087 \internal
1088 \since 6.9
1089
1090 Outputs a heterogeneous product type (pair, tuple, or anything that
1091 implements the Tuple Protocol). The class name is described by "\a ns
1092 \c{::} \a what", while the addresses of the \a n elements are stored in the
1093 array \a data. The formatters are stored in the array \a ops.
1094
1095 If \a ns is empty, only \a what is used.
1096*/
1097QDebug &QDebug::putTupleLikeImplImpl(const char *ns, const char *what,
1098 size_t n, StreamTypeErased *ops, const void **data)
1099{
1100 const QDebugStateSaver saver(*this);
1101 nospace();
1102 if (ns && *ns)
1103 *this << ns << "::";
1104 *this << what << '(';
1105 while (n--) {
1106 (*ops++)(*this, *data++);
1107 if (n)
1108 *this << ", ";
1109 }
1110 return *this << ')';
1111}
1112
1113/*!
1114 \fn template <class T> QDebug operator<<(QDebug debug, const QList<T> &list)
1115 \relates QDebug
1116
1117 Writes the contents of \a list to \a debug. \c T needs to
1118 support streaming into QDebug.
1119*/
1120
1121/*!
1122 \fn template <class T, qsizetype P> QDebug operator<<(QDebug debug, const QVarLengthArray<T,P> &array)
1123 \relates QDebug
1124 \since 6.3
1125
1126 Writes the contents of \a array to \a debug. \c T needs to
1127 support streaming into QDebug.
1128*/
1129
1130/*!
1131 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec)
1132 \relates QDebug
1133 \since 5.7
1134
1135 Writes the contents of list \a vec to \a debug. \c T needs to
1136 support streaming into QDebug.
1137*/
1138
1139/*!
1140 \fn template <typename T, typename Alloc> QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
1141 \relates QDebug
1142 \since 5.7
1143
1144 Writes the contents of vector \a vec to \a debug. \c T needs to
1145 support streaming into QDebug.
1146*/
1147
1148/*!
1149 \fn template <typename T, std::size_t N> QDebug operator<<(QDebug debug, const std::array<T, N> &array)
1150 \relates QDebug
1151 \since 6.9
1152
1153 Writes the contents of \a array to \a debug. \c T needs to
1154 support streaming into QDebug.
1155*/
1156
1157/*!
1158 \fn template <typename T> QDebug operator<<(QDebug debug, const QSet<T> &set)
1159 \relates QDebug
1160
1161 Writes the contents of \a set to \a debug. \c T needs to
1162 support streaming into QDebug.
1163*/
1164
1165/*!
1166 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMap<Key, T> &map)
1167 \relates QDebug
1168
1169 Writes the contents of \a map to \a debug. Both \c Key and
1170 \c T need to support streaming into QDebug.
1171*/
1172
1173/*!
1174 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMultiMap<Key, T> &map)
1175 \relates QDebug
1176
1177 Writes the contents of \a map to \a debug. Both \c Key and
1178 \c T need to support streaming into QDebug.
1179*/
1180
1181/*!
1182 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
1183 \relates QDebug
1184 \since 5.7
1185
1186 Writes the contents of \a map to \a debug. Both \c Key and
1187 \c T need to support streaming into QDebug.
1188*/
1189
1190/*!
1191 \fn template <typename Key, typename T, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
1192 \relates QDebug
1193 \since 5.7
1194
1195 Writes the contents of \a map to \a debug. Both \c Key and
1196 \c T need to support streaming into QDebug.
1197*/
1198
1199/*!
1200 \fn template <typename Key, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::multiset<Key, Compare, Alloc> &multiset)
1201 \relates QDebug
1202 \since 6.9
1203
1204 Writes the contents of \a multiset to \a debug. The \c Key type
1205 needs to support streaming into QDebug.
1206*/
1207
1208/*!
1209 \fn template <typename Key, typename Compare, typename Alloc> QDebug operator<<(QDebug debug, const std::set<Key, Compare, Alloc> &set)
1210 \relates QDebug
1211 \since 6.9
1212
1213 Writes the contents of \a set to \a debug. The \c Key type
1214 needs to support streaming into QDebug.
1215*/
1216
1217/*!
1218 \fn template <typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc> QDebug operator<<(QDebug debug, const std::unordered_map<Key, T, Hash, KeyEqual, Alloc> &map)
1219 \relates QDebug
1220 \since 6.9
1221
1222 Writes the contents of \a map to \a debug. Both \c Key and
1223 \c T need to support streaming into QDebug.
1224*/
1225
1226/*!
1227 \fn template <typename Key, typename Hash, typename KeyEqual, typename Alloc> QDebug operator<<(QDebug debug, const std::unordered_set<Key, Hash, KeyEqual, Alloc> &unordered_set)
1228 \relates QDebug
1229 \since 6.9
1230
1231 Writes the contents of \a unordered_set to \a debug. The \c Key type
1232 needs to support streaming into QDebug.
1233*/
1234
1235/*!
1236 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
1237 \relates QDebug
1238
1239 Writes the contents of \a hash to \a debug. Both \c Key and
1240 \c T need to support streaming into QDebug.
1241*/
1242
1243/*!
1244 \fn template <class Key, class T> QDebug operator<<(QDebug debug, const QMultiHash<Key, T> &hash)
1245 \relates QDebug
1246
1247 Writes the contents of \a hash to \a debug. Both \c Key and
1248 \c T need to support streaming into QDebug.
1249*/
1250
1251/*!
1252 \fn template <class...Ts, QDebug::if_streamable<Ts...>> QDebug &QDebug::operator<<(const std::tuple<Ts...> &tuple)
1253 \since 6.9
1254
1255 Writes the contents of \a tuple to the stream. All \c Ts... need to support
1256 streaming into QDebug.
1257*/
1258
1259/*!
1260 \fn template <class T1, class T2> QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair)
1261 \relates QDebug
1262
1263 Writes the contents of \a pair to \a debug. Both \c T1 and
1264 \c T2 need to support streaming into QDebug.
1265*/
1266
1267/*!
1268 \since 6.7
1269 \fn template <class T, QDebug::if_streamable<T>> QDebug::operator<<(const std::optional<T> &opt)
1270
1271 Writes the contents of \a opt (or \c nullopt if not set) to this stream.
1272 \c T needs to support streaming into QDebug.
1273*/
1274
1275/*!
1276 \fn template <typename T> QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
1277 \relates QDebug
1278
1279 Writes the contents of \a cache to \a debug. \c T needs to
1280 support streaming into QDebug.
1281*/
1282
1283/*!
1284 \fn template<typename T> QDebug operator<<(QDebug debug, const QFlags<T> &flags)
1285 \relates QDebug
1286 \since 4.7
1287
1288 Writes \a flags to \a debug.
1289*/
1290
1291/*!
1292 \fn template<typename T> QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
1293 \relates QSharedPointer
1294 \since 5.7
1295
1296 Writes the pointer tracked by \a ptr into the debug object \a debug for
1297 debugging purposes.
1298
1299 \sa {Debugging Techniques}
1300*/
1301
1302/*!
1303 \fn QDebug &QDebug::operator<<(std::nullptr_t)
1304 \internal
1305 */
1306
1307/*!
1308 \since 6.7
1309 \fn QDebug &QDebug::operator<<(std::nullopt_t)
1310
1311 Writes nullopt to the stream.
1312*/
1313
1314/*!
1315 \class QDebugStateSaver
1316 \inmodule QtCore
1317 \brief Convenience class for custom QDebug operators.
1318
1319 Saves the settings used by QDebug, and restores them upon destruction,
1320 then calls \l {QDebug::maybeSpace()}{maybeSpace()}, to separate arguments with a space if
1321 \l {QDebug::autoInsertSpaces()}{autoInsertSpaces()} was true at the time of constructing the QDebugStateSaver.
1322
1323 The automatic insertion of spaces between writes is one of the settings
1324 that QDebugStateSaver stores for the duration of the current block.
1325
1326 The settings of the internal QTextStream are also saved and restored,
1327 so that using << Qt::hex in a QDebug operator doesn't affect other QDebug
1328 operators.
1329
1330 QDebugStateSaver is typically used in the implementation of an operator<<() for debugging:
1331
1332 \snippet customtype/customtypeexample.cpp custom type streaming operator
1333
1334 \since 5.1
1335*/
1336
1338{
1339public:
1349 {
1350 const bool currentSpaces = m_stream->space;
1351 if (currentSpaces && !m_spaces)
1352 if (m_stream->buffer.endsWith(u' '))
1353 m_stream->buffer.chop(1);
1354
1355 m_stream->space = m_spaces;
1356 m_stream->noQuotes = m_noQuotes;
1357 m_stream->ts.d_ptr->params = m_streamParams;
1358 m_stream->verbosity = m_verbosity;
1359
1360 if (!currentSpaces && m_spaces)
1361 m_stream->ts << ' ';
1362 }
1363
1365
1366 // QDebug state
1367 const bool m_spaces;
1368 const bool m_noQuotes;
1369 const int m_verbosity;
1370
1371 // QTextStream state
1373};
1374
1375
1376/*!
1377 Creates a QDebugStateSaver instance, which saves the settings
1378 currently used by \a dbg.
1379
1380 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
1381*/
1382QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
1383 : d(new QDebugStateSaverPrivate(dbg.stream))
1384{
1385}
1386
1387/*!
1388 Destroys a QDebugStateSaver instance, which restores the settings
1389 used when the QDebugStateSaver instance was created.
1390
1391 \sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
1392*/
1393QDebugStateSaver::~QDebugStateSaver()
1394{
1395 d->restoreState();
1396}
1397
1398/*!
1399 \internal
1400
1401 Specialization of the primary template in qdebug.h to out-of-line
1402 the common case of QFlags<T>::Int being 32-bit.
1403
1404 Just call the generic version so the two don't get out of sync.
1405*/
1406void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value)
1407{
1408 qt_QMetaEnum_flagDebugOperator(debug, sizeofT, quint64(value));
1409}
1410
1411/*!
1412 \internal
1413 Ditto, for 64-bit.
1414*/
1415void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, quint64 value)
1416{
1417 qt_QMetaEnum_flagDebugOperator<quint64>(debug, sizeofT, value);
1418}
1419
1420
1421#ifndef QT_NO_QOBJECT
1422/*!
1423 \internal
1424
1425 Formats the given enum \a value for debug output.
1426
1427 The supported verbosity are:
1428
1429 0: Just the key, or value with enum name if no key is found:
1430
1431 MyEnum2
1432 MyEnum(123)
1433 MyScopedEnum::Enum3
1434 MyScopedEnum(456)
1435
1436 1: Same as 0, but treating all enums as scoped:
1437
1438 MyEnum::MyEnum2
1439 MyEnum(123)
1440 MyScopedEnum::Enum3
1441 MyScopedEnum(456)
1442
1443 2: The QDebug default. Same as 0, and includes class/namespace scope:
1444
1445 MyNamespace::MyClass::MyEnum2
1446 MyNamespace::MyClass::MyEnum(123)
1447 MyNamespace::MyClass::MyScopedEnum::Enum3
1448 MyNamespace::MyClass::MyScopedEnum(456)
1449
1450 3: Same as 2, but treating all enums as scoped:
1451
1452 MyNamespace::MyClass::MyEnum::MyEnum2
1453 MyNamespace::MyClass::MyEnum(123)
1454 MyNamespace::MyClass::MyScopedEnum::Enum3
1455 MyNamespace::MyClass::MyScopedEnum(456)
1456 */
1457QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, qint64 value, const QMetaObject *meta, const char *name)
1458{
1459 QDebugStateSaver saver(dbg);
1460 dbg.nospace();
1461 QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
1462
1463 const int verbosity = dbg.verbosity();
1464 if (verbosity >= QDebug::DefaultVerbosity) {
1465 if (const char *scope = me.scope())
1466 dbg << scope << u"::";
1467 }
1468
1469 const char *key = me.valueToKey(static_cast<int>(value));
1470 const bool scoped = me.isScoped() || verbosity & 1;
1471 if (scoped || !key)
1472 dbg << me.enumName() << (!key ? u"(" : u"::");
1473
1474 if (key)
1475 dbg << key;
1476 else
1477 dbg << value << ')';
1478
1479 return dbg;
1480}
1481
1482/*!
1483 \fn QDebug qt_QMetaEnum_flagDebugOperator(QDebug &, quint64 value, const QMetaObject *, const char *name)
1484 \internal
1485
1486 Formats the given flag \a value for debug output.
1487
1488 The supported verbosity are:
1489
1490 0: Just the key(s):
1491
1492 MyFlag1
1493 MyFlag2|MyFlag3
1494 MyScopedFlag(MyFlag2)
1495 MyScopedFlag(MyFlag2|MyFlag3)
1496
1497 1: Same as 0, but treating all flags as scoped:
1498
1499 MyFlag(MyFlag1)
1500 MyFlag(MyFlag2|MyFlag3)
1501 MyScopedFlag(MyFlag2)
1502 MyScopedFlag(MyFlag2|MyFlag3)
1503
1504 2: The QDebug default. Same as 1, and includes class/namespace scope:
1505
1506 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1)
1507 QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)
1508 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)
1509 QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)
1510 */
1511QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaObject *meta, const char *name)
1512{
1513 const int verbosity = debug.verbosity();
1514
1515 QDebugStateSaver saver(debug);
1516 debug.resetFormat();
1517 debug.noquote();
1518 debug.nospace();
1519
1520 const QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
1521
1522 const bool classScope = verbosity >= QDebug::DefaultVerbosity;
1523 if (classScope) {
1524 debug << u"QFlags<";
1525
1526 if (const char *scope = me.scope())
1527 debug << scope << u"::";
1528 }
1529
1530 const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity;
1531 if (enumScope) {
1532 debug << me.enumName();
1533 if (classScope)
1534 debug << '>';
1535 debug << '(';
1536 }
1537
1538 debug << me.valueToKeys(value);
1539
1540 if (enumScope)
1541 debug << ')';
1542
1543 return debug;
1544}
1545#endif // !QT_NO_QOBJECT
1546
1547QT_END_NAMESPACE
const QTextStreamPrivate::Params m_streamParams
Definition qdebug.cpp:1372
QDebugStateSaverPrivate(QDebug::Stream *stream)
Definition qdebug.cpp:1340
Combined button and popup list for selecting options.
QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, qint64 value, const QMetaObject *meta, const char *name)
Definition qdebug.cpp:1457
static void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode=true)
Definition qdebug.cpp:199
static bool isPrintable(char16_t uc)
Definition qdebug.cpp:194
static QByteArray timeUnit(qint64 num, qint64 den)
Definition qdebug.cpp:346
static bool isPrintable(uchar c)
Definition qdebug.cpp:195
static bool isPrintable(char32_t ucs4)
Definition qdebug.cpp:193
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, uint value)
Definition qdebug.cpp:1406