QDebug: add streaming operators for std::unordered_map
The stream insertion operator for QDebug is not overloaded to handle std::unordered_map Overload the stream insertion operator for QDebug to handle std::unordered_map [ChangeLog][QtCore][QDebug] Added support for std::unordered_map. Fixes: QTBUG-130290 Change-Id: I96e82f90c310dcac4a6e4d35651fb1adb6d6293a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
4f9cbd5b28
commit
a9fe57fefa
@ -1188,6 +1188,15 @@ QDebug &QDebug::putTupleLikeImplImpl(const char *ns, const char *what,
|
|||||||
\c T need to support streaming into QDebug.
|
\c T need to support streaming into QDebug.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn template <typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc> QDebug operator<<(QDebug debug, const std::unordered_map<Key, T, Compare, Alloc> &unordered_map)
|
||||||
|
\relates QDebug
|
||||||
|
\since 6.9
|
||||||
|
|
||||||
|
Writes the contents of \a map to \a debug. Both \c Key and
|
||||||
|
\c T need to support streaming into QDebug.
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
|
\fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
|
||||||
\relates QDebug
|
\relates QDebug
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <QtCore/q20type_traits.h>
|
#include <QtCore/q20type_traits.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1
|
#if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1
|
||||||
@ -436,6 +437,12 @@ inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::multim
|
|||||||
return QtPrivate::printSequentialContainer(std::move(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 <typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc>
|
||||||
|
inline QDebug operator<<(QDebug debug, const std::unordered_map<Key, T, Hash, KeyEqual, Alloc> &unordered_map)
|
||||||
|
{
|
||||||
|
return QtPrivate::printSequentialContainer(std::move(debug), "std::unordered_map", unordered_map); // yes, sequential: *it is std::pair
|
||||||
|
}
|
||||||
|
|
||||||
template <class Key, class T>
|
template <class Key, class T>
|
||||||
inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
|
inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ namespace pmr = std::pmr;
|
|||||||
namespace pmr = std;
|
namespace pmr = std;
|
||||||
#endif
|
#endif
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
using namespace q20::chrono;
|
using namespace q20::chrono;
|
||||||
@ -36,6 +37,7 @@ static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMetaType>);
|
|||||||
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QList<int>>);
|
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QList<int>>);
|
||||||
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, QString>>);
|
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, QString>>);
|
||||||
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, std::tuple<int, QString, QMap<int, QString>>>);
|
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, std::tuple<int, QString, QMap<int, QString>>>);
|
||||||
|
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, std::unordered_map<int, QString>>);
|
||||||
struct NonStreamable {};
|
struct NonStreamable {};
|
||||||
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, NonStreamable>);
|
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, NonStreamable>);
|
||||||
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QList<NonStreamable>>);
|
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QList<NonStreamable>>);
|
||||||
@ -84,6 +86,7 @@ private slots:
|
|||||||
void qDebugQLatin1String() const;
|
void qDebugQLatin1String() const;
|
||||||
void qDebugStdPair() const;
|
void qDebugStdPair() const;
|
||||||
void qDebugStdTuple() const;
|
void qDebugStdTuple() const;
|
||||||
|
void qDebugStdUnorderedMap() const;
|
||||||
void qDebugStdString() const;
|
void qDebugStdString() const;
|
||||||
void qDebugStdStringView() const;
|
void qDebugStdStringView() const;
|
||||||
void qDebugStdWString() const;
|
void qDebugStdWString() const;
|
||||||
@ -770,6 +773,46 @@ void tst_QDebug::qDebugStdTuple() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QDebug::qDebugStdUnorderedMap() const
|
||||||
|
{
|
||||||
|
QByteArray file, function;
|
||||||
|
int line = 0;
|
||||||
|
MessageHandlerSetter mhs(myMessageHandler);
|
||||||
|
|
||||||
|
{
|
||||||
|
QDebug d = qDebug();
|
||||||
|
std::unordered_map<int, QString> unorderedMap{{1, "One"}, {2, "Two"}, {3, "Three"}};
|
||||||
|
d.nospace().noquote() << unorderedMap;
|
||||||
|
}
|
||||||
|
#ifndef QT_NO_MESSAGELOGCONTEXT
|
||||||
|
file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
|
||||||
|
#endif
|
||||||
|
QCOMPARE(s_msgType, QtDebugMsg);
|
||||||
|
|
||||||
|
QStringList expectedValues = {"std::unordered_map","std::pair(1, One)","std::pair(2, Two)","std::pair(3, Three)"};
|
||||||
|
for (const QString &expextedValue : expectedValues) {
|
||||||
|
QVERIFY(s_msg.contains(expextedValue));
|
||||||
|
}
|
||||||
|
QCOMPARE(s_file, file);
|
||||||
|
QCOMPARE(s_line, line);
|
||||||
|
QCOMPARE(s_function, function);
|
||||||
|
|
||||||
|
{
|
||||||
|
qDebug() << std::unordered_map<std::string, float>{{"quarter", 0.25f}, {"half", 0.5f}};
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedValues= {"std::unordered_map","std::pair(\"quarter\", 0.25)","std::pair(\"half\", 0.5)"};
|
||||||
|
for (const QString &expextedValue : expectedValues) {
|
||||||
|
QVERIFY(s_msg.contains(expextedValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
qDebug()<< std::unordered_map<int, QString> {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QCOMPARE(s_msg, "std::unordered_map()"_L1);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QDebug::qDebugStdString() const
|
void tst_QDebug::qDebugStdString() const
|
||||||
{
|
{
|
||||||
QString file, function;
|
QString file, function;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user