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:
Dheerendra Purohit 2024-10-18 18:34:42 +05:30 committed by Thiago Macieira
parent 4f9cbd5b28
commit a9fe57fefa
3 changed files with 59 additions and 0 deletions

View File

@ -1188,6 +1188,15 @@ QDebug &QDebug::putTupleLikeImplImpl(const char *ns, const char *what,
\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)
\relates QDebug

View File

@ -30,6 +30,7 @@
#include <tuple>
#include <QtCore/q20type_traits.h>
#include <utility>
#include <unordered_map>
#include <vector>
#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
}
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>
inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
{

View File

@ -26,6 +26,7 @@ namespace pmr = std::pmr;
namespace pmr = std;
#endif
#include <tuple>
#include <unordered_map>
using namespace std::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, 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 {};
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, NonStreamable>);
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QList<NonStreamable>>);
@ -84,6 +86,7 @@ private slots:
void qDebugQLatin1String() const;
void qDebugStdPair() const;
void qDebugStdTuple() const;
void qDebugStdUnorderedMap() const;
void qDebugStdString() const;
void qDebugStdStringView() 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
{
QString file, function;