Skip to content

Commit

Permalink
QDebug: add streaming operators for std::unordered_set
Browse files Browse the repository at this point in the history
The stream insertion operator for QDebug is not overloaded
to handle std::unordered_set

Overload the stream insertion operator for QDebug
to handle std::unordered_set

[ChangeLog][QtCOre][QDebug] Added support for std::unordered_set.

Fixes: QTBUG-130481
Change-Id: I75a1f62f9ecb6b06ba45cc00d789cd3f3886b4c7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
  • Loading branch information
QtDheeru committed Nov 20, 2024
1 parent 7be9b59 commit a8c9a56
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/corelib/io/qdebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,16 @@ QDebug &QDebug::putTupleLikeImplImpl(const char *ns, const char *what,
\c T need to support streaming into QDebug.
*/

/*!
\fn template <typename Key, typename Hash, typename KeyEqual, typename Alloc> QDebug operator<<(QDebug debug, const std::unordered_set<Key, Hash, KeyEqual, Alloc> &unordered_set)
\relates QDebug
\since 6.9
Writes the contents of \a unordered_set to \a debug. The \c Key type
needs to support streaming into QDebug.
*/


/*!
\fn template <class Key, class T> QDebug operator<<(QDebug debug, const QHash<Key, T> &hash)
\relates QDebug
Expand Down
7 changes: 7 additions & 0 deletions src/corelib/io/qdebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <QtCore/q20type_traits.h>
#include <utility>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 1
Expand Down Expand Up @@ -443,6 +444,12 @@ inline QDebug operator<<(QDebug debug, const std::unordered_map<Key, T, Hash, Ke
return QtPrivate::printSequentialContainer(std::move(debug), "std::unordered_map", unordered_map); // yes, sequential: *it is std::pair
}

template <typename Key, typename Hash, typename KeyEqual, typename Alloc>
inline QDebug operator<<(QDebug debug, const std::unordered_set<Key, Hash, KeyEqual, Alloc>& unordered_set)
{
return QtPrivate::printSequentialContainer(std::move(debug), "std::unordered_set", unordered_set);
}

template <class Key, class T>
inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map)
{
Expand Down
43 changes: 43 additions & 0 deletions tests/auto/corelib/io/qdebug/tst_qdebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace pmr = std;
#endif
#include <tuple>
#include <unordered_map>
#include <unordered_set>

using namespace std::chrono;
using namespace q20::chrono;
Expand All @@ -38,6 +39,7 @@ 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>>);
static_assert(QTypeTraits::has_ostream_operator_v<QDebug, std::unordered_set<int>>);
struct NonStreamable {};
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, NonStreamable>);
static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QList<NonStreamable>>);
Expand Down Expand Up @@ -87,6 +89,7 @@ private slots:
void qDebugStdPair() const;
void qDebugStdTuple() const;
void qDebugStdUnorderedMap() const;
void qDebugStdUnorderedSet() const;
void qDebugStdString() const;
void qDebugStdStringView() const;
void qDebugStdWString() const;
Expand Down Expand Up @@ -813,6 +816,46 @@ void tst_QDebug::qDebugStdUnorderedMap() const
QCOMPARE(s_msg, "std::unordered_map()"_L1);
}

void tst_QDebug::qDebugStdUnorderedSet() const
{
QByteArray file, function;
int line = 0;
MessageHandlerSetter mhs(myMessageHandler);

{
QDebug d = qDebug();
std::unordered_set<int> unorderedSet{1, 2, 3, 2, 1};
d.nospace().noquote() << unorderedSet;
}
#ifndef QT_NO_MESSAGELOGCONTEXT
file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO;
#endif
QCOMPARE(s_msgType, QtDebugMsg);

QStringList expectedValues = {"std::unordered_set", "1", "2", "3"};
for (const QString &expectedValue : expectedValues) {
QVERIFY(s_msg.contains(expectedValue));
}
QCOMPARE(s_file, file);
QCOMPARE(s_line, line);
QCOMPARE(s_function, function);

{
qDebug() << std::unordered_set<std::string>{"apple", "banana", "cherry", "banana", "apple"};
}

expectedValues = {"std::unordered_set", "\"apple\"", "\"banana\"", "\"cherry\""};
for (const QString &expectedValue : expectedValues) {
QVERIFY(s_msg.contains(expectedValue));
}

{
qDebug() << std::unordered_set<int>{}; // Empty set
}

QCOMPARE(s_msg, "std::unordered_set()"_L1);
}

void tst_QDebug::qDebugStdString() const
{
QString file, function;
Expand Down

0 comments on commit a8c9a56

Please sign in to comment.