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,
|
[[nodiscard]] QString arg(T a, int fieldWidth = 0, int base = 10,
|
||||||
QChar fillChar = u' ') const
|
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);
|
return arg_impl(qlonglong(a), fieldWidth, base, fillChar);
|
||||||
else
|
else
|
||||||
return arg_impl(qulonglong(a), fieldWidth, base, fillChar);
|
return arg_impl(qulonglong(a), fieldWidth, base, fillChar);
|
||||||
|
@ -6697,7 +6697,6 @@ void tst_QString::arg()
|
|||||||
// (unscoped) enums
|
// (unscoped) enums
|
||||||
enum : int { FooS = -1 };
|
enum : int { FooS = -1 };
|
||||||
enum : uint { FooU = 1 };
|
enum : uint { FooU = 1 };
|
||||||
QEXPECT_FAIL("", "QTBUG-131906", Continue); // Qt 6.9 only
|
|
||||||
QCOMPARE(s4.arg(FooS), QLatin1String("[-1]"));
|
QCOMPARE(s4.arg(FooS), QLatin1String("[-1]"));
|
||||||
QCOMPARE(s4.arg(FooU), QLatin1String("[1]"));
|
QCOMPARE(s4.arg(FooU), QLatin1String("[1]"));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user