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 563ed822f867c6c3040956017d4ca7f3795f172c. 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…
x
Reference in New Issue
Block a user