diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index be215263395..2f7bb414b54 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE +class QDebug; + /* QTypeInfo - type trait functionality */ @@ -445,6 +447,23 @@ using compare_eq_result = std::enable_if_t using compare_lt_result = std::enable_if_t...>, bool>; +namespace detail { + +template +const T const_value(); +template +T &reference(); + +} + +template +struct has_ostream_operator : std::false_type {}; +template +struct has_ostream_operator() << detail::const_value())>> + : std::true_type {}; +template +constexpr bool has_ostream_operator_v = has_ostream_operator::value; + } diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 77004ef9522..d858eb933b7 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -262,62 +262,66 @@ inline QDebug printAssociativeContainer(QDebug debug, const char *which, const A } // namespace QtPrivate +template +using QDebugIfHasDebugStream = + std::enable_if_t...>, QDebug>; + template -inline QDebug operator<<(QDebug debug, const QList &vec) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QList &vec) { return QtPrivate::printSequentialContainer(debug, "QList", vec); } template -inline QDebug operator<<(QDebug debug, const std::vector &vec) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::vector &vec) { return QtPrivate::printSequentialContainer(debug, "std::vector", vec); } template -inline QDebug operator<<(QDebug debug, const std::list &vec) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::list &vec) { return QtPrivate::printSequentialContainer(debug, "std::list", vec); } template -inline QDebug operator<<(QDebug debug, const std::map &map) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::map &map) { return QtPrivate::printSequentialContainer(debug, "std::map", map); // yes, sequential: *it is std::pair } template -inline QDebug operator<<(QDebug debug, const std::multimap &map) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::multimap &map) { return QtPrivate::printSequentialContainer(debug, "std::multimap", map); // yes, sequential: *it is std::pair } template -inline QDebug operator<<(QDebug debug, const QMap &map) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QMap &map) { return QtPrivate::printAssociativeContainer(debug, "QMap", map); } template -inline QDebug operator<<(QDebug debug, const QMultiMap &map) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QMultiMap &map) { return QtPrivate::printAssociativeContainer(debug, "QMultiMap", map); } template -inline QDebug operator<<(QDebug debug, const QHash &hash) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QHash &hash) { return QtPrivate::printAssociativeContainer(debug, "QHash", hash); } template -inline QDebug operator<<(QDebug debug, const QMultiHash &hash) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QMultiHash &hash) { return QtPrivate::printAssociativeContainer(debug, "QMultiHash", hash); } template -inline QDebug operator<<(QDebug debug, const std::pair &pair) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const std::pair &pair) { const QDebugStateSaver saver(debug); debug.nospace() << "std::pair(" << pair.first << ',' << pair.second << ')'; @@ -325,13 +329,13 @@ inline QDebug operator<<(QDebug debug, const std::pair &pair) } template -inline QDebug operator<<(QDebug debug, const QSet &set) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QSet &set) { return QtPrivate::printSequentialContainer(debug, "QSet", set); } template -inline QDebug operator<<(QDebug debug, const QContiguousCache &cache) +inline QDebugIfHasDebugStream operator<<(QDebug debug, const QContiguousCache &cache) { const QDebugStateSaver saver(debug); debug.nospace() << "QContiguousCache("; diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index ece9be642a1..72412aa44d4 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -35,6 +35,12 @@ #include #include +static_assert(QTypeTraits::has_ostream_v); +static_assert(QTypeTraits::has_ostream_v>); +struct NonStreamable {}; +static_assert(!QTypeTraits::has_ostream_v); +static_assert(!QTypeTraits::has_ostream_v>); + class tst_QDebug: public QObject { Q_OBJECT