diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-07-06 13:08:40 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-08-15 14:43:23 +0200 |
commit | 8ad9e81694fda39fbecebb9f97491004e9ac8c41 (patch) | |
tree | b5a5e9bc6bd95dea730cb466627e8a225bd1ab94 /src/corelib/io | |
parent | 6c36fd8af7e873defa3843f49848a14980561647 (diff) |
Constrain the debug stream operators for containers
Check that we can successfully instantiate the debug
stream operator for a container before we actually try.
This is required so we can automate registration of debug
stream operators with QMetaType.
Change-Id: I3943e7a443751d250c33b2ca1b9cf29207cfe6c4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qdebug.h | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 77004ef952..d858eb933b 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<typename ...T> +using QDebugIfHasDebugStream = + std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDebug, T>...>, QDebug>; + template<typename T> -inline QDebug operator<<(QDebug debug, const QList<T> &vec) +inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QList<T> &vec) { return QtPrivate::printSequentialContainer(debug, "QList", vec); } template <typename T, typename Alloc> -inline QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec) +inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::vector<T, Alloc> &vec) { return QtPrivate::printSequentialContainer(debug, "std::vector", vec); } template <typename T, typename Alloc> -inline QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec) +inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::list<T, Alloc> &vec) { return QtPrivate::printSequentialContainer(debug, "std::list", vec); } template <typename Key, typename T, typename Compare, typename Alloc> -inline QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map) +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 } template <typename Key, typename T, typename Compare, typename Alloc> -inline QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map) +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 } template <class Key, class T> -inline QDebug operator<<(QDebug debug, const QMap<Key, T> &map) +inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QMap<Key, T> &map) { return QtPrivate::printAssociativeContainer(debug, "QMap", map); } template <class Key, class T> -inline QDebug operator<<(QDebug debug, const QMultiMap<Key, T> &map) +inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QMultiMap<Key, T> &map) { return QtPrivate::printAssociativeContainer(debug, "QMultiMap", map); } template <class Key, class T> -inline QDebug operator<<(QDebug debug, const QHash<Key, T> &hash) +inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QHash<Key, T> &hash) { return QtPrivate::printAssociativeContainer(debug, "QHash", hash); } template <class Key, class T> -inline QDebug operator<<(QDebug debug, const QMultiHash<Key, T> &hash) +inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QMultiHash<Key, T> &hash) { return QtPrivate::printAssociativeContainer(debug, "QMultiHash", hash); } template <class T1, class T2> -inline QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair) +inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T1, T2> &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<T1, T2> &pair) } template <typename T> -inline QDebug operator<<(QDebug debug, const QSet<T> &set) +inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QSet<T> &set) { return QtPrivate::printSequentialContainer(debug, "QSet", set); } template <class T> -inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache) +inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QContiguousCache<T> &cache) { const QDebugStateSaver saver(debug); debug.nospace() << "QContiguousCache("; |