Warning, file /include/QtCore/qdebug.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005 #ifndef QDEBUG_H
0006 #define QDEBUG_H
0007
0008 #if 0
0009 #pragma qt_class(QtDebug)
0010 #endif
0011
0012 #include <QtCore/qcontainerfwd.h>
0013 #include <QtCore/qtextstream.h>
0014 #include <QtCore/qtypes.h>
0015 #include <QtCore/qstring.h>
0016 #include <QtCore/qcontiguouscache.h>
0017 #include <QtCore/qsharedpointer.h>
0018
0019
0020 #include <chrono>
0021 #include <list>
0022 #include <map>
0023 #include <optional>
0024 #include <string>
0025 #include <string_view>
0026 #include <utility>
0027 #include <vector>
0028
0029 #if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1
0030 # include <QtCore/qlist.h>
0031 # include <QtCore/qmap.h>
0032 # include <QtCore/qset.h>
0033 # include <QtCore/qvarlengtharray.h>
0034 #endif
0035
0036 QT_BEGIN_NAMESPACE
0037
0038 class QT6_ONLY(Q_CORE_EXPORT) QDebug : public QIODeviceBase
0039 {
0040 friend class QMessageLogger;
0041 friend class QDebugStateSaver;
0042 friend class QDebugStateSaverPrivate;
0043 struct Stream {
0044 enum { VerbosityShift = 29, VerbosityMask = 0x7 };
0045
0046 Stream(QIODevice *device)
0047 : ts(device)
0048 {}
0049 Stream(QString *string)
0050 : ts(string, WriteOnly)
0051 {}
0052 Stream(QtMsgType t)
0053 : ts(&buffer, WriteOnly),
0054 type(t),
0055 message_output(true)
0056 {}
0057 QTextStream ts;
0058 QString buffer;
0059 int ref = 1;
0060 QtMsgType type = QtDebugMsg;
0061 bool space = true;
0062 bool noQuotes = false;
0063 bool message_output = false;
0064 int verbosity = DefaultVerbosity;
0065 QMessageLogContext context;
0066 } *stream;
0067
0068 enum Latin1Content { ContainsBinary = 0, ContainsLatin1 };
0069
0070 QT7_ONLY(Q_CORE_EXPORT) void putUcs4(uint ucs4);
0071 QT7_ONLY(Q_CORE_EXPORT) void putString(const QChar *begin, size_t length);
0072 QT7_ONLY(Q_CORE_EXPORT) void putByteArray(const char *begin, size_t length, Latin1Content content);
0073 QT7_ONLY(Q_CORE_EXPORT) void putTimeUnit(qint64 num, qint64 den);
0074 QT7_ONLY(Q_CORE_EXPORT) void putInt128(const void *i);
0075 QT7_ONLY(Q_CORE_EXPORT) void putUInt128(const void *i);
0076 public:
0077 explicit QDebug(QIODevice *device) : stream(new Stream(device)) {}
0078 explicit QDebug(QString *string) : stream(new Stream(string)) {}
0079 explicit QDebug(QtMsgType t) : stream(new Stream(t)) {}
0080 QDebug(const QDebug &o) : stream(o.stream) { ++stream->ref; }
0081 QDebug(QDebug &&other) noexcept : stream{std::exchange(other.stream, nullptr)} {}
0082 inline QDebug &operator=(const QDebug &other);
0083 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QDebug)
0084 ~QDebug();
0085 void swap(QDebug &other) noexcept { qt_ptr_swap(stream, other.stream); }
0086
0087 QT7_ONLY(Q_CORE_EXPORT) QDebug &resetFormat();
0088
0089 inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; }
0090 inline QDebug &nospace() { stream->space = false; return *this; }
0091 inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; }
0092 inline QDebug &verbosity(int verbosityLevel) { stream->verbosity = verbosityLevel; return *this; }
0093 int verbosity() const { return stream->verbosity; }
0094 void setVerbosity(int verbosityLevel) { stream->verbosity = verbosityLevel; }
0095 enum VerbosityLevel { MinimumVerbosity = 0, DefaultVerbosity = 2, MaximumVerbosity = 7 };
0096
0097 bool autoInsertSpaces() const { return stream->space; }
0098 void setAutoInsertSpaces(bool b) { stream->space = b; }
0099
0100 [[nodiscard]] bool quoteStrings() const noexcept { return !stream->noQuotes; }
0101 void setQuoteStrings(bool b) { stream->noQuotes = !b; }
0102
0103 inline QDebug "e() { stream->noQuotes = false; return *this; }
0104 inline QDebug &noquote() { stream->noQuotes = true; return *this; }
0105 inline QDebug &maybeQuote(char c = '"') { if (!stream->noQuotes) stream->ts << c; return *this; }
0106
0107 inline QDebug &operator<<(QChar t) { putUcs4(t.unicode()); return maybeSpace(); }
0108 inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); }
0109 inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); }
0110 inline QDebug &operator<<(signed short t) { stream->ts << t; return maybeSpace(); }
0111 inline QDebug &operator<<(unsigned short t) { stream->ts << t; return maybeSpace(); }
0112 inline QDebug &operator<<(char16_t t) { return *this << QChar(t); }
0113 inline QDebug &operator<<(char32_t t) { putUcs4(t); return maybeSpace(); }
0114 inline QDebug &operator<<(signed int t) { stream->ts << t; return maybeSpace(); }
0115 inline QDebug &operator<<(unsigned int t) { stream->ts << t; return maybeSpace(); }
0116 inline QDebug &operator<<(signed long t) { stream->ts << t; return maybeSpace(); }
0117 inline QDebug &operator<<(unsigned long t) { stream->ts << t; return maybeSpace(); }
0118 inline QDebug &operator<<(qint64 t) { stream->ts << t; return maybeSpace(); }
0119 inline QDebug &operator<<(quint64 t) { stream->ts << t; return maybeSpace(); }
0120 inline QDebug &operator<<(qfloat16 t) { stream->ts << t; return maybeSpace(); }
0121 inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); }
0122 inline QDebug &operator<<(double t) { stream->ts << t; return maybeSpace(); }
0123 inline QDebug &operator<<(const char* t) { stream->ts << QString::fromUtf8(t); return maybeSpace(); }
0124 inline QDebug &operator<<(const char16_t *t) { stream->ts << QStringView(t); return maybeSpace(); }
0125 inline QDebug &operator<<(const QString & t) { putString(t.constData(), size_t(t.size())); return maybeSpace(); }
0126 inline QDebug &operator<<(QStringView s) { putString(s.data(), size_t(s.size())); return maybeSpace(); }
0127 inline QDebug &operator<<(QUtf8StringView s) { putByteArray(reinterpret_cast<const char*>(s.data()), s.size(), ContainsBinary); return maybeSpace(); }
0128 inline QDebug &operator<<(QLatin1StringView t) { putByteArray(t.latin1(), t.size(), ContainsLatin1); return maybeSpace(); }
0129 inline QDebug &operator<<(const QByteArray & t) { putByteArray(t.constData(), t.size(), ContainsBinary); return maybeSpace(); }
0130 inline QDebug &operator<<(QByteArrayView t) { putByteArray(t.constData(), t.size(), ContainsBinary); return maybeSpace(); }
0131 inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); }
0132 inline QDebug &operator<<(std::nullptr_t) { stream->ts << "(nullptr)"; return maybeSpace(); }
0133 inline QDebug &operator<<(std::nullopt_t) { stream->ts << "nullopt"; return maybeSpace(); }
0134 inline QDebug &operator<<(QTextStreamFunction f) {
0135 stream->ts << f;
0136 return *this;
0137 }
0138
0139 inline QDebug &operator<<(QTextStreamManipulator m)
0140 { stream->ts << m; return *this; }
0141
0142 #ifdef Q_QDOC
0143 template <typename Char, typename...Args>
0144 QDebug &operator<<(const std::basic_string<Char, Args...> &s);
0145
0146 template <typename Char, typename...Args>
0147 QDebug &operator<<(std::basic_string_view<Char, Args...> s);
0148 #else
0149 template <typename...Args>
0150 QDebug &operator<<(const std::basic_string<char, Args...> &s)
0151 { return *this << QUtf8StringView(s); }
0152
0153 template <typename...Args>
0154 QDebug &operator<<(std::basic_string_view<char, Args...> s)
0155 { return *this << QUtf8StringView(s); }
0156
0157 #ifdef __cpp_char8_t
0158 template <typename...Args>
0159 QDebug &operator<<(const std::basic_string<char8_t, Args...> &s)
0160 { return *this << QUtf8StringView(s); }
0161
0162 template <typename...Args>
0163 QDebug &operator<<(std::basic_string_view<char8_t, Args...> s)
0164 { return *this << QUtf8StringView(s); }
0165 #endif
0166
0167 template <typename...Args>
0168 QDebug &operator<<(const std::basic_string<char16_t, Args...> &s)
0169 { return *this << QStringView(s); }
0170
0171 template <typename...Args>
0172 QDebug &operator<<(std::basic_string_view<char16_t, Args...> s)
0173 { return *this << QStringView(s); }
0174
0175 template <typename...Args>
0176 QDebug &operator<<(const std::basic_string<wchar_t, Args...> &s)
0177 {
0178 if constexpr (sizeof(wchar_t) == 2)
0179 return *this << QStringView(s);
0180 else
0181 return *this << QString::fromWCharArray(s.data(), s.size());
0182 }
0183
0184 template <typename...Args>
0185 QDebug &operator<<(std::basic_string_view<wchar_t, Args...> s)
0186 {
0187 if constexpr (sizeof(wchar_t) == 2)
0188 return *this << QStringView(s);
0189 else
0190 return *this << QString::fromWCharArray(s.data(), s.size());
0191 }
0192
0193 template <typename...Args>
0194 QDebug &operator<<(const std::basic_string<char32_t, Args...> &s)
0195 { return *this << QString::fromUcs4(s.data(), s.size()); }
0196
0197 template <typename...Args>
0198 QDebug &operator<<(std::basic_string_view<char32_t, Args...> s)
0199 { return *this << QString::fromUcs4(s.data(), s.size()); }
0200 #endif
0201
0202 template <typename Rep, typename Period>
0203 QDebug &operator<<(std::chrono::duration<Rep, Period> duration)
0204 {
0205 stream->ts << duration.count();
0206 putTimeUnit(Period::num, Period::den);
0207 return maybeSpace();
0208 }
0209
0210 #ifdef QT_SUPPORTS_INT128
0211 private:
0212
0213
0214 template <typename T>
0215 using if_qint128 = std::enable_if_t<std::is_same_v<T, qint128>, bool>;
0216 template <typename T>
0217 using if_quint128 = std::enable_if_t<std::is_same_v<T, quint128>, bool>;
0218 public:
0219 template <typename T, if_qint128<T> = true>
0220 QDebug &operator<<(T i128) { putInt128(&i128); return maybeSpace(); }
0221 template <typename T, if_quint128<T> = true>
0222 QDebug &operator<<(T u128) { putUInt128(&u128); return maybeSpace(); }
0223 #endif
0224
0225 template <typename T>
0226 static QString toString(T &&object)
0227 {
0228 QString buffer;
0229 QDebug stream(&buffer);
0230 stream.nospace() << std::forward<T>(object);
0231 return buffer;
0232 }
0233 };
0234
0235 Q_DECLARE_SHARED(QDebug)
0236
0237 class QDebugStateSaverPrivate;
0238 class QDebugStateSaver
0239 {
0240 public:
0241 Q_NODISCARD_CTOR Q_CORE_EXPORT
0242 QDebugStateSaver(QDebug &dbg);
0243 Q_CORE_EXPORT
0244 ~QDebugStateSaver();
0245 private:
0246 Q_DISABLE_COPY(QDebugStateSaver)
0247 QScopedPointer<QDebugStateSaverPrivate> d;
0248 };
0249
0250 class QNoDebug
0251 {
0252 public:
0253 inline QNoDebug &operator<<(QTextStreamFunction) { return *this; }
0254 inline QNoDebug &operator<<(QTextStreamManipulator) { return *this; }
0255 inline QNoDebug &space() { return *this; }
0256 inline QNoDebug &nospace() { return *this; }
0257 inline QNoDebug &maybeSpace() { return *this; }
0258 inline QNoDebug "e() { return *this; }
0259 inline QNoDebug &noquote() { return *this; }
0260 inline QNoDebug &maybeQuote(const char = '"') { return *this; }
0261 inline QNoDebug &verbosity(int) { return *this; }
0262
0263 template<typename T>
0264 inline QNoDebug &operator<<(const T &) { return *this; }
0265 };
0266
0267 inline QDebug &QDebug::operator=(const QDebug &other)
0268 {
0269 QDebug{other}.swap(*this);
0270 return *this;
0271 }
0272
0273 namespace QtPrivate {
0274
0275 template <typename SequentialContainer>
0276 inline QDebug printSequentialContainer(QDebug debug, const char *which, const SequentialContainer &c)
0277 {
0278 const QDebugStateSaver saver(debug);
0279 debug.nospace() << which << '(';
0280 typename SequentialContainer::const_iterator it = c.begin(), end = c.end();
0281 if (it != end) {
0282 debug << *it;
0283 ++it;
0284 }
0285 while (it != end) {
0286 debug << ", " << *it;
0287 ++it;
0288 }
0289 debug << ')';
0290 return debug;
0291 }
0292
0293 template <typename AssociativeContainer>
0294 inline QDebug printAssociativeContainer(QDebug debug, const char *which, const AssociativeContainer &c)
0295 {
0296 const QDebugStateSaver saver(debug);
0297 debug.nospace() << which << "(";
0298 for (typename AssociativeContainer::const_iterator it = c.constBegin();
0299 it != c.constEnd(); ++it) {
0300 debug << '(' << it.key() << ", " << it.value() << ')';
0301 }
0302 debug << ')';
0303 return debug;
0304 }
0305
0306 }
0307
0308 template<typename ...T>
0309 using QDebugIfHasDebugStream =
0310 std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDebug, T>...>, QDebug>;
0311
0312 template<typename Container, typename ...T>
0313 using QDebugIfHasDebugStreamContainer =
0314 std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator_container<QDebug, Container, T>...>, QDebug>;
0315
0316 #ifndef Q_QDOC
0317
0318 template<typename T>
0319 inline QDebugIfHasDebugStreamContainer<QList<T>, T> operator<<(QDebug debug, const QList<T> &vec)
0320 {
0321 return QtPrivate::printSequentialContainer(std::move(debug), "QList", vec);
0322 }
0323
0324 template<typename T, qsizetype P>
0325 inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QVarLengthArray<T, P> &vec)
0326 {
0327 return QtPrivate::printSequentialContainer(std::move(debug), "QVarLengthArray", vec);
0328 }
0329
0330 template <typename T, typename Alloc>
0331 inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
0332 {
0333 return QtPrivate::printSequentialContainer(std::move(debug), "std::vector", vec);
0334 }
0335
0336 template <typename T, typename Alloc>
0337 inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::list<T, Alloc> &vec)
0338 {
0339 return QtPrivate::printSequentialContainer(std::move(debug), "std::list", vec);
0340 }
0341
0342 template <typename T>
0343 inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, std::initializer_list<T> list)
0344 {
0345 return QtPrivate::printSequentialContainer(std::move(debug), "std::initializer_list", list);
0346 }
0347
0348 template <typename Key, typename T, typename Compare, typename Alloc>
0349 inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
0350 {
0351 return QtPrivate::printSequentialContainer(std::move(debug), "std::map", map);
0352 }
0353
0354 template <typename Key, typename T, typename Compare, typename Alloc>
0355 inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
0356 {
0357 return QtPrivate::printSequentialContainer(std::move(debug), "std::multimap", map);
0358 }
0359
0360 template <class Key, class T>
0361 inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
0362 {
0363 return QtPrivate::printAssociativeContainer(std::move(debug), "QMap", map);
0364 }
0365
0366 template <class Key, class T>
0367 inline QDebugIfHasDebugStreamContainer<QMultiMap<Key, T>, Key, T> operator<<(QDebug debug, const QMultiMap<Key, T> &map)
0368 {
0369 return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiMap", map);
0370 }
0371
0372 template <class Key, class T>
0373 inline QDebugIfHasDebugStreamContainer<QHash<Key, T>, Key, T> operator<<(QDebug debug, const QHash<Key, T> &hash)
0374 {
0375 return QtPrivate::printAssociativeContainer(std::move(debug), "QHash", hash);
0376 }
0377
0378 template <class Key, class T>
0379 inline QDebugIfHasDebugStreamContainer<QMultiHash<Key, T>, Key, T> operator<<(QDebug debug, const QMultiHash<Key, T> &hash)
0380 {
0381 return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiHash", hash);
0382 }
0383
0384 template <class T>
0385 inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::optional<T> &opt)
0386 {
0387 const QDebugStateSaver saver(debug);
0388 if (!opt)
0389 debug.nospace() << std::nullopt;
0390 else
0391 debug.nospace() << "std::optional(" << *opt << ')';
0392 return debug;
0393 }
0394
0395 template <class T1, class T2>
0396 inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T1, T2> &pair)
0397 {
0398 const QDebugStateSaver saver(debug);
0399 debug.nospace() << "std::pair(" << pair.first << ',' << pair.second << ')';
0400 return debug;
0401 }
0402
0403 template <typename T>
0404 inline QDebugIfHasDebugStreamContainer<QSet<T>, T> operator<<(QDebug debug, const QSet<T> &set)
0405 {
0406 return QtPrivate::printSequentialContainer(std::move(debug), "QSet", set);
0407 }
0408
0409 template <class T>
0410 inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QContiguousCache<T> &cache)
0411 {
0412 const QDebugStateSaver saver(debug);
0413 debug.nospace() << "QContiguousCache(";
0414 for (qsizetype i = cache.firstIndex(); i <= cache.lastIndex(); ++i) {
0415 debug << cache[i];
0416 if (i != cache.lastIndex())
0417 debug << ", ";
0418 }
0419 debug << ')';
0420 return debug;
0421 }
0422
0423 #else
0424 template <class T>
0425 QDebug operator<<(QDebug debug, const QList<T> &list);
0426
0427 template <class T, qsizetype P>
0428 QDebug operator<<(QDebug debug, const QVarLengthArray<T, P> &array);
0429
0430 template <typename T, typename Alloc>
0431 QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec);
0432
0433 template <typename T, typename Alloc>
0434 QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec);
0435
0436 template <typename Key, typename T, typename Compare, typename Alloc>
0437 QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map);
0438
0439 template <typename Key, typename T, typename Compare, typename Alloc>
0440 QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map);
0441
0442 template <class Key, class T>
0443 QDebug operator<<(QDebug debug, const QMap<Key, T> &map);
0444
0445 template <class Key, class T>
0446 QDebug operator<<(QDebug debug, const QMultiMap<Key, T> &map);
0447
0448 template <class Key, class T>
0449 QDebug operator<<(QDebug debug, const QHash<Key, T> &hash);
0450
0451 template <class Key, class T>
0452 QDebug operator<<(QDebug debug, const QMultiHash<Key, T> &hash);
0453
0454 template <typename T>
0455 QDebug operator<<(QDebug debug, const QSet<T> &set);
0456
0457 template <class T1, class T2>
0458 QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair);
0459
0460 template <typename T>
0461 QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache);
0462
0463 #endif
0464
0465 template <class T>
0466 inline QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
0467 {
0468 QDebugStateSaver saver(debug);
0469 debug.nospace() << "QSharedPointer(" << ptr.data() << ")";
0470 return debug;
0471 }
0472
0473 template <typename T, typename Tag> class QTaggedPointer;
0474
0475 template <typename T, typename Tag>
0476 inline QDebug operator<<(QDebug debug, const QTaggedPointer<T, Tag> &ptr)
0477 {
0478 QDebugStateSaver saver(debug);
0479 debug.nospace() << "QTaggedPointer(" << ptr.pointer() << ", " << ptr.tag() << ")";
0480 return debug;
0481 }
0482
0483 Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value);
0484
0485 template <typename Int>
0486 void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, Int value)
0487 {
0488 const QDebugStateSaver saver(debug);
0489 debug.resetFormat();
0490 debug.nospace() << "QFlags(" << Qt::hex << Qt::showbase;
0491 bool needSeparator = false;
0492 for (size_t i = 0; i < sizeofT * 8; ++i) {
0493 if (value & (Int(1) << i)) {
0494 if (needSeparator)
0495 debug << '|';
0496 else
0497 needSeparator = true;
0498 debug << (Int(1) << i);
0499 }
0500 }
0501 debug << ')';
0502 }
0503
0504 #if !defined(QT_NO_QOBJECT) && !defined(Q_QDOC)
0505 Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, qint64 value, const QMetaObject *meta, const char *name);
0506 Q_CORE_EXPORT QDebug qt_QMetaEnum_flagDebugOperator(QDebug &dbg, quint64 value, const QMetaObject *meta, const char *name);
0507
0508 template<typename T>
0509 typename std::enable_if<QtPrivate::IsQEnumHelper<T>::Value, QDebug>::type
0510 operator<<(QDebug dbg, T value)
0511 {
0512 const QMetaObject *obj = qt_getEnumMetaObject(value);
0513 const char *name = qt_getEnumName(value);
0514 return qt_QMetaEnum_debugOperator(dbg, static_cast<typename std::underlying_type<T>::type>(value), obj, name);
0515 }
0516
0517 template<typename T,
0518 typename A = typename std::enable_if<std::is_enum<T>::value, void>::type,
0519 typename B = typename std::enable_if<sizeof(T) <= sizeof(int), void>::type,
0520 typename C = typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value, void>::type,
0521 typename D = typename std::enable_if<QtPrivate::IsQEnumHelper<QFlags<T>>::Value, void>::type>
0522 inline QDebug operator<<(QDebug dbg, T value)
0523 {
0524 typedef QFlags<T> FlagsT;
0525 const QMetaObject *obj = qt_getEnumMetaObject(FlagsT());
0526 const char *name = qt_getEnumName(FlagsT());
0527 return qt_QMetaEnum_debugOperator(dbg, typename FlagsT::Int(value), obj, name);
0528 }
0529
0530 template <class T>
0531 inline typename std::enable_if<
0532 QtPrivate::IsQEnumHelper<T>::Value || QtPrivate::IsQEnumHelper<QFlags<T> >::Value,
0533 QDebug>::type
0534 qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags)
0535 {
0536 const QMetaObject *obj = qt_getEnumMetaObject(T());
0537 const char *name = qt_getEnumName(T());
0538 return qt_QMetaEnum_flagDebugOperator(debug, flags.toInt(), obj, name);
0539 }
0540
0541 template <class T>
0542 inline typename std::enable_if<
0543 !QtPrivate::IsQEnumHelper<T>::Value && !QtPrivate::IsQEnumHelper<QFlags<T> >::Value,
0544 QDebug>::type
0545 qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags)
0546 #else
0547 template <class T>
0548 inline QDebug qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags)
0549 #endif
0550 {
0551 qt_QMetaEnum_flagDebugOperator(debug, sizeof(T), typename QFlags<T>::Int(flags));
0552 return debug;
0553 }
0554
0555 template<typename T>
0556 inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
0557 {
0558
0559
0560 return qt_QMetaEnum_flagDebugOperator_helper(debug, flags);
0561 }
0562
0563 inline QDebug operator<<(QDebug debug, QKeyCombination combination)
0564 {
0565 QDebugStateSaver saver(debug);
0566 debug.nospace() << "QKeyCombination("
0567 << combination.keyboardModifiers()
0568 << ", "
0569 << combination.key()
0570 << ")";
0571 return debug;
0572 }
0573
0574 #ifdef Q_OS_DARWIN
0575
0576
0577
0578
0579
0580 #define QT_FOR_EACH_CORE_FOUNDATION_TYPE(F) \
0581 F(CFArray) \
0582 F(CFURL) \
0583 F(CFData) \
0584 F(CFNumber) \
0585 F(CFDictionary) \
0586 F(CFLocale) \
0587 F(CFDate) \
0588 F(CFBoolean) \
0589 F(CFTimeZone) \
0590
0591 #define QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(F) \
0592 F(CFError) \
0593 F(CFBundle) \
0594
0595 #define QT_FOR_EACH_CORE_GRAPHICS_TYPE(F) \
0596 F(CGPath) \
0597
0598 #define QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(F) \
0599 F(CGColorSpace) \
0600 F(CGImage) \
0601 F(CGFont) \
0602 F(CGColor) \
0603
0604 #define QT_FORWARD_DECLARE_CF_TYPE(type) Q_FORWARD_DECLARE_CF_TYPE(type);
0605 #define QT_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type);
0606 #define QT_FORWARD_DECLARE_CG_TYPE(type) Q_FORWARD_DECLARE_CG_TYPE(type);
0607 #define QT_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(type);
0608
0609 QT_END_NAMESPACE
0610 Q_FORWARD_DECLARE_CF_TYPE(CFString);
0611 struct objc_object;
0612 Q_FORWARD_DECLARE_OBJC_CLASS(NSObject);
0613 QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_CF_TYPE)
0614 QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_MUTABLE_CF_TYPE)
0615 QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_CG_TYPE)
0616 QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_MUTABLE_CG_TYPE)
0617 QT_BEGIN_NAMESPACE
0618
0619 #define QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
0620 Q_CORE_EXPORT QDebug operator<<(QDebug, CFType##Ref);
0621
0622 #define Q_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE(CFType) \
0623 QDebug operator<<(QDebug debug, CFType##Ref ref) \
0624 { \
0625 if (!ref) \
0626 return debug << QT_STRINGIFY(CFType) "Ref(0x0)"; \
0627 if (CFStringRef description = CFCopyDescription(ref)) { \
0628 QDebugStateSaver saver(debug); \
0629 debug.noquote() << description; \
0630 CFRelease(description); \
0631 } \
0632 return debug; \
0633 }
0634
0635
0636 #if defined(__OBJC__)
0637 Q_CORE_EXPORT QDebug operator<<(QDebug, id);
0638 #endif
0639 Q_CORE_EXPORT QDebug operator<<(QDebug, objc_object *);
0640 Q_CORE_EXPORT QDebug operator<<(QDebug, const NSObject *);
0641 Q_CORE_EXPORT QDebug operator<<(QDebug, CFStringRef);
0642
0643 QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE)
0644 QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE)
0645 QT_FOR_EACH_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE)
0646 QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_FORWARD_DECLARE_QDEBUG_OPERATOR_FOR_CF_TYPE)
0647
0648 #undef QT_FORWARD_DECLARE_CF_TYPE
0649 #undef QT_FORWARD_DECLARE_MUTABLE_CF_TYPE
0650 #undef QT_FORWARD_DECLARE_CG_TYPE
0651 #undef QT_FORWARD_DECLARE_MUTABLE_CG_TYPE
0652
0653 #endif
0654
0655 QT_END_NAMESPACE
0656
0657 #endif