mirror of https://github.com/qt/qtbase.git
QString::arg(): don't ignore signedness in (unscoped) enums
std::is_signed doesn't work on enums. Instead of SFINAE'ing out for
non-arithmetic types, it returns false. This changes the output of
(unscoped) enums with signed underlying_type from signed to unsigned,
compared to Qt 6.8.
To fix, use an enum's underlying_type to determine signedness. This is
complicated by the fact that std::underlying_type SFINAE's out (since
C++20) or even constitutes UB (until C++17) when called on non-enums,
so we have to be careful to limit the use of it to just enums, which
we reach by passing the meta-function (underlying_type), not its
result (underlying_type_t) to std::conditional and then calling he
result. This requires the non-enum branch to be a meta-function, too
(and not just a type), which is easily achieved using
q20::type_identity.
Use ::type::type instead of mixing _t and ::type to not confuse users
(the leading `typename` is required, anyway, because at least one
trailing ::type is required, and typename std::conditional_t looks
wrong).
Amends 563ed822f8
.
Fixes: QTBUG-131906
Change-Id: I6d122d5a48bffb1e09eb0d7841bb8f1f79cd882f
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
d7c9619a81
commit
2021d3978d
|
@ -316,7 +316,12 @@ public:
|
|||
[[nodiscard]] QString arg(T a, int fieldWidth = 0, int base = 10,
|
||||
QChar fillChar = u' ') const
|
||||
{
|
||||
if constexpr (std::is_signed_v<T>)
|
||||
using U = typename std::conditional<
|
||||
// underlying_type_t<non-enum> is UB in C++17/SFINAE in C++20, so wrap:
|
||||
std::is_enum_v<T>, std::underlying_type<T>,
|
||||
q20::type_identity<T>
|
||||
>::type::type;
|
||||
if constexpr (std::is_signed_v<U>)
|
||||
return arg_impl(qlonglong(a), fieldWidth, base, fillChar);
|
||||
else
|
||||
return arg_impl(qulonglong(a), fieldWidth, base, fillChar);
|
||||
|
|
|
@ -6697,7 +6697,6 @@ void tst_QString::arg()
|
|||
// (unscoped) enums
|
||||
enum : int { FooS = -1 };
|
||||
enum : uint { FooU = 1 };
|
||||
QEXPECT_FAIL("", "QTBUG-131906", Continue); // Qt 6.9 only
|
||||
QCOMPARE(s4.arg(FooS), QLatin1String("[-1]"));
|
||||
QCOMPARE(s4.arg(FooU), QLatin1String("[1]"));
|
||||
|
||||
|
|
Loading…
Reference in New Issue