Add QDebug printing for the std/Qt::<name>_ordering types
[ChangeLog][QtCore][QDebug] Added possibility to print {std/Qt} weak/partial/strong_ordering values with QDebug << operator. Change-Id: Ie880cb34c19f79a404c692c2322b3460d72bfde4 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
1442a9ea47
commit
2aa39be4c2
@ -14,6 +14,7 @@
|
||||
#pragma qt_sync_stop_processing
|
||||
#endif
|
||||
|
||||
#include <QtCore/qflags.h>
|
||||
#include <QtCore/qoverload.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
#include <QtCore/qtypeinfo.h>
|
||||
@ -31,16 +32,34 @@ QT_BEGIN_NAMESPACE
|
||||
class QPartialOrdering;
|
||||
|
||||
namespace QtOrderingPrivate {
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
template <typename T> struct is_std_ordering_type : std::false_type {};
|
||||
template <typename T> struct is_qt_ordering_type : std::false_type {};
|
||||
|
||||
template <typename T> constexpr bool is_std_ordering_type_v = is_std_ordering_type<T>::value;
|
||||
template <typename T> constexpr bool is_qt_ordering_type_v = is_qt_ordering_type<T>::value;
|
||||
|
||||
enum class QtOrderingType {
|
||||
QtOrder = 0x00,
|
||||
StdOrder = 0x01,
|
||||
Partial = 0x00,
|
||||
Weak = 0x20,
|
||||
Strong = 0x40,
|
||||
StrengthMask = Weak|Strong,
|
||||
};
|
||||
Q_DECLARE_FLAGS(QtOrderingTypeFlag, QtOrderingType)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QtOrderingPrivate::QtOrderingTypeFlag)
|
||||
|
||||
template <typename QtOrdering> struct StdOrdering;
|
||||
template <typename StdOrdering> struct QtOrdering;
|
||||
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
#define QT_STD_MAP(x) \
|
||||
template <> struct StdOrdering< Qt::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
|
||||
template <> struct StdOrdering<std::x##_ordering> : q20::type_identity<std::x##_ordering> {};\
|
||||
template <> struct QtOrdering<std::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
|
||||
template <> struct QtOrdering< Qt::x##_ordering> : q20::type_identity< Qt::x##_ordering> {};\
|
||||
template <> struct is_std_ordering_type<std::x##_ordering> : std::true_type {};\
|
||||
template <> struct is_qt_ordering_type< Qt::x##_ordering> : std::true_type {};\
|
||||
/* end */
|
||||
QT_STD_MAP(partial)
|
||||
QT_STD_MAP(weak)
|
||||
@ -49,6 +68,11 @@ QT_STD_MAP(strong)
|
||||
|
||||
template <> struct StdOrdering<QPartialOrdering> : q20::type_identity<std::partial_ordering> {};
|
||||
template <> struct QtOrdering<QPartialOrdering> : q20::type_identity< Qt::partial_ordering> {};
|
||||
#else
|
||||
template <> struct is_qt_ordering_type< Qt::partial_ordering> : std::true_type {};
|
||||
template <> struct is_qt_ordering_type< Qt::weak_ordering> : std::true_type {};
|
||||
template <> struct is_qt_ordering_type< Qt::strong_ordering> : std::true_type {};
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
|
||||
template <typename In> constexpr auto to_std(In in) noexcept
|
||||
-> typename QtOrderingPrivate::StdOrdering<In>::type
|
||||
@ -58,7 +82,33 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
|
||||
-> typename QtOrderingPrivate::QtOrdering<In>::type
|
||||
{ return in; }
|
||||
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
template <typename T>
|
||||
constexpr bool is_ordering_type_v
|
||||
= std::disjunction_v<is_qt_ordering_type<T>, is_std_ordering_type<T>>;
|
||||
|
||||
template <typename T>
|
||||
constexpr std::enable_if_t<is_qt_ordering_type_v<T>, QtOrderingTypeFlag>
|
||||
orderingFlagsFor(T t) noexcept
|
||||
{
|
||||
QtOrderingTypeFlag flags = QtOrderingType::QtOrder;
|
||||
Qt::partial_ordering convertedOrder(t);
|
||||
if constexpr (std::is_same_v<T, Qt::strong_ordering>)
|
||||
flags = flags | QtOrderingType::Strong;
|
||||
else if constexpr (std::is_same_v<T, Qt::partial_ordering>)
|
||||
flags = flags | QtOrderingType::Partial;
|
||||
else if constexpr (std::is_same_v<T, Qt::weak_ordering>)
|
||||
flags = flags | QtOrderingType::Weak;
|
||||
return flags;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr std::enable_if_t<is_std_ordering_type_v<T>, QtOrderingTypeFlag>
|
||||
orderingFlagsFor(T t) noexcept
|
||||
{
|
||||
QtOrderingPrivate::QtOrderingTypeFlag flags = QtOrderingPrivate::QtOrderingType::StdOrder;
|
||||
return QtOrderingTypeFlag(flags
|
||||
| QtOrderingPrivate::orderingFlagsFor(QtOrderingPrivate::to_Qt(t)));
|
||||
}
|
||||
} // namespace QtOrderingPrivate
|
||||
|
||||
/*
|
||||
|
@ -511,6 +511,46 @@ void QDebug::putUInt128([[maybe_unused]] const void *p)
|
||||
stream->ts << int128Warning();
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.9
|
||||
\internal
|
||||
Helper to the <Std/Qt>::<>_ordering debug output.
|
||||
It generates the string in following format:
|
||||
<Qt/Std>::<weak/partial/strong>_ordering::<less/equal/greater/unordered>
|
||||
*/
|
||||
void QDebug::putQtOrdering(QtOrderingPrivate::QtOrderingTypeFlag flags, Qt::partial_ordering order)
|
||||
{
|
||||
using QtOrderingPrivate::QtOrderingType;
|
||||
std::string result;
|
||||
if ((flags & QtOrderingType::StdOrder) == QtOrderingType::StdOrder)
|
||||
result += "std";
|
||||
else if ((flags & QtOrderingType::QtOrder) == QtOrderingType::QtOrder)
|
||||
result += "Qt";
|
||||
|
||||
result += "::";
|
||||
const bool isStrong = ((flags & QtOrderingType::Strong) == QtOrderingType::Strong);
|
||||
if (isStrong)
|
||||
result += "strong";
|
||||
else if ((flags & QtOrderingType::Weak) == QtOrderingType::Weak)
|
||||
result += "weak";
|
||||
else if ((flags & QtOrderingType::Partial) == QtOrderingType::Partial)
|
||||
result += "partial";
|
||||
result += "_ordering::";
|
||||
|
||||
if (order == Qt::partial_ordering::equivalent) {
|
||||
if (isStrong)
|
||||
result += "equal";
|
||||
else
|
||||
result += "equivalent";
|
||||
} else if (order == Qt::partial_ordering::greater) {
|
||||
result += "greater";
|
||||
} else if (order == Qt::partial_ordering::less) {
|
||||
result += "less";
|
||||
} else {
|
||||
result += "unordered";
|
||||
}
|
||||
stream->ts << result.data();
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QDebug::swap(QDebug &other)
|
||||
@ -948,6 +988,15 @@ QDebug &QDebug::resetFormat()
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, QDebug::if_ordering_type<T>> QDebug::operator<<(QDebug debug, T t)
|
||||
\since 6.9
|
||||
Prints the Qt or std ordering value \a t to the \a debug object.
|
||||
|
||||
\note This function only participates in overload resolution if \c T
|
||||
is one of <Qt/Std>::<weak/partial/strong>_ordering.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 6.5
|
||||
\fn template <typename Char, typename...Args> QDebug &QDebug::operator<<(const std::basic_string<Char, Args...> &s)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#pragma qt_class(QtDebug)
|
||||
#endif
|
||||
|
||||
#include <QtCore/qcompare.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
#include <QtCore/qtextstream.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
@ -79,6 +80,8 @@ class QT6_ONLY(Q_CORE_EXPORT) QDebug : public QIODeviceBase
|
||||
QT7_ONLY(Q_CORE_EXPORT) void putTimeUnit(qint64 num, qint64 den);
|
||||
QT7_ONLY(Q_CORE_EXPORT) void putInt128(const void *i);
|
||||
QT7_ONLY(Q_CORE_EXPORT) void putUInt128(const void *i);
|
||||
QT7_ONLY(Q_CORE_EXPORT) void putQtOrdering(QtOrderingPrivate::QtOrderingTypeFlag flags,
|
||||
Qt::partial_ordering order);
|
||||
public:
|
||||
explicit QDebug(QIODevice *device) : stream(new Stream(device)) {}
|
||||
explicit QDebug(QString *string) : stream(new Stream(string)) {}
|
||||
@ -250,6 +253,17 @@ public:
|
||||
{
|
||||
return toBytesImpl(&streamTypeErased<T>, std::addressof(object));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
using if_ordering_type = std::enable_if_t<QtOrderingPrivate::is_ordering_type_v<T>, bool>;
|
||||
|
||||
template <typename T, if_ordering_type<T> = true>
|
||||
friend QDebug operator<<(QDebug debug, T t)
|
||||
{
|
||||
debug.putQtOrdering(QtOrderingPrivate::orderingFlagsFor(t), Qt::partial_ordering(t));
|
||||
return debug;
|
||||
}
|
||||
};
|
||||
|
||||
Q_DECLARE_SHARED(QDebug)
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QtCompare>
|
||||
#include <QtCore/QtDebug>
|
||||
|
||||
#include <QTest>
|
||||
@ -90,6 +91,7 @@ private slots:
|
||||
void qDebugStdChrono_data() const;
|
||||
void qDebugStdChrono() const;
|
||||
void qDebugStdOptional() const;
|
||||
void qDebugStdOrdering() const;
|
||||
void textStreamModifiers() const;
|
||||
void resetFormat() const;
|
||||
void defaultMessagehandler() const;
|
||||
@ -1239,6 +1241,36 @@ void tst_QDebug::qDebugStdOptional() const
|
||||
QCOMPARE(QString::fromLatin1(s_function), function);
|
||||
}
|
||||
|
||||
void tst_QDebug::qDebugStdOrdering() const
|
||||
{
|
||||
QLatin1StringView file, function;
|
||||
MessageHandlerSetter mhs(myMessageHandler);
|
||||
{
|
||||
QDebug d = qDebug();
|
||||
d << Qt::partial_ordering::less
|
||||
<< Qt::partial_ordering::unordered
|
||||
<< Qt::weak_ordering::greater
|
||||
<< Qt::strong_ordering::equal;
|
||||
}
|
||||
#ifndef QT_NO_MESSAGELOGCONTEXT
|
||||
file = QLatin1StringView(__FILE__);
|
||||
function = QLatin1StringView(Q_FUNC_INFO);
|
||||
#endif
|
||||
const auto cmpStr = "Qt::partial_ordering::lessQt::partial_ordering::unorderedQt::weak_ordering::greaterQt::strong_ordering::equal"_L1;
|
||||
QCOMPARE(s_msgType, QtDebugMsg);
|
||||
QCOMPARE(s_msg, cmpStr);
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
qDebug() << std::partial_ordering::less
|
||||
<< std::partial_ordering::unordered
|
||||
<< std::weak_ordering::greater
|
||||
<< std::strong_ordering::equal;
|
||||
const auto stdStr = "std::partial_ordering::lessstd::partial_ordering::unorderedstd::weak_ordering::greaterstd::strong_ordering::equal"_L1;
|
||||
QCOMPARE(s_msg, stdStr);
|
||||
#endif
|
||||
QCOMPARE(QLatin1StringView(s_file), file);
|
||||
QCOMPARE(QLatin1StringView(s_function), function);
|
||||
}
|
||||
|
||||
void tst_QDebug::textStreamModifiers() const
|
||||
{
|
||||
QString file, function;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <QTest>
|
||||
|
||||
#include <QtCore/qtypes.h>
|
||||
#include <QtCore/qcompare.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -21,6 +22,9 @@ private slots:
|
||||
|
||||
void chrono_duration_data();
|
||||
void chrono_duration() { testRows(); }
|
||||
|
||||
void orderingTypeValue_data();
|
||||
void orderingTypeValue() { testRows(); }
|
||||
};
|
||||
|
||||
void tst_toString::addColumns()
|
||||
@ -211,5 +215,38 @@ void tst_toString::chrono_duration_data()
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_toString::orderingTypeValue_data()
|
||||
{
|
||||
addColumns();
|
||||
#define CHECK(x) ADD_ROW(#x, x, #x)
|
||||
CHECK(Qt::strong_ordering::equal);
|
||||
CHECK(Qt::strong_ordering::less);
|
||||
CHECK(Qt::strong_ordering::greater);
|
||||
|
||||
CHECK(Qt::partial_ordering::equivalent);
|
||||
CHECK(Qt::partial_ordering::less);
|
||||
CHECK(Qt::partial_ordering::greater);
|
||||
CHECK(Qt::partial_ordering::unordered);
|
||||
|
||||
CHECK(Qt::weak_ordering::equivalent);
|
||||
CHECK(Qt::weak_ordering::less);
|
||||
CHECK(Qt::weak_ordering::greater);
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
CHECK(std::strong_ordering::equal);
|
||||
CHECK(std::strong_ordering::less);
|
||||
CHECK(std::strong_ordering::greater);
|
||||
|
||||
CHECK(std::partial_ordering::equivalent);
|
||||
CHECK(std::partial_ordering::less);
|
||||
CHECK(std::partial_ordering::greater);
|
||||
CHECK(std::partial_ordering::unordered);
|
||||
|
||||
CHECK(std::weak_ordering::equivalent);
|
||||
CHECK(std::weak_ordering::less);
|
||||
CHECK(std::weak_ordering::greater);
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
#undef CHECK
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_toString)
|
||||
#include "tst_tostring.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user