diff options
author | Marc Mutz <[email protected]> | 2024-10-31 13:45:42 +0100 |
---|---|---|
committer | Marc Mutz <[email protected]> | 2025-06-30 17:45:40 +0000 |
commit | e9f91f049cb710b97d50a12306eca577be09b6ab (patch) | |
tree | 661923389a419b20b72ac06116ce87aeb7d45537 | |
parent | 6b968b3f1393fa510d93a5e7e63a20648ad8baae (diff) |
We support char32_t, so there's no reason to not support a
4-byte-wchar_t.
This also fixes a nasty asymmery between QString::arg(L'ä') (integral
output) and QL1SV::arg(L'ä') or QString::arg(L'ä', L'ä') (characters)
[ChangeLog][Important Behavior Changes][QtCore][QString] The unary
arg() function now treats wchar_t as a character (string-like; was:
integer), so u"%1".arg(L'ø') will now return "ø" and not '248". This
makes the function consistent with both QString multi-arg() and
QLatin1StringView::arg().
[ChangeLog][QtCore][QAnyStringView] Supports construction from a
single wchar_t on all platforms now (was: only on Windows).
Fixes: QTBUG-126054
Pick-to: 6.10
Change-Id: I21b7a9782f03d04686207db30d1b1c9d50bc8169
Reviewed-by: Thiago Macieira <[email protected]>
-rw-r--r-- | src/corelib/text/qanystringview.cpp | 1 | ||||
-rw-r--r-- | src/corelib/text/qanystringview.h | 12 | ||||
-rw-r--r-- | src/corelib/text/qstring.h | 3 | ||||
-rw-r--r-- | tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp | 7 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstring/tst_qstring.cpp | 3 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp | 15 |
6 files changed, 32 insertions, 9 deletions
diff --git a/src/corelib/text/qanystringview.cpp b/src/corelib/text/qanystringview.cpp index 717b53f06c2..7bf8a3fa1fd 100644 --- a/src/corelib/text/qanystringview.cpp +++ b/src/corelib/text/qanystringview.cpp @@ -138,6 +138,7 @@ QT_BEGIN_NAMESPACE \list \li \c QLatin1Char \li \c QChar::SpecialCharacter + \li \c wchar_t (where it's a 32-bit type, i.e. Unix) (since 6.10) \li \c char32_t \endlist diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h index 4b89fa6edbf..079cf751af1 100644 --- a/src/corelib/text/qanystringview.h +++ b/src/corelib/text/qanystringview.h @@ -25,6 +25,11 @@ struct wrapped { using type = Result; }; template <typename Tag, typename Result> using wrapped_t = typename wrapped<Tag, Result>::type; +template <typename Char> +struct is_compatible_utf32_char : std::false_type {}; +template <> struct is_compatible_utf32_char<char32_t> : std::true_type {}; +template <> struct is_compatible_utf32_char<wchar_t> : std::bool_constant<sizeof(wchar_t) == 4> {}; + } // namespace QtPrivate class QAnyStringView @@ -60,6 +65,11 @@ private: }; template <typename Char> + using if_compatible_utf32_char = std::enable_if_t< + QtPrivate::is_compatible_utf32_char<Char>::value + , bool>; + + template <typename Char> using is_compatible_char = std::disjunction< QtPrivate::IsCompatibleCharType<Char>, QtPrivate::IsCompatibleChar8Type<Char> @@ -220,7 +230,7 @@ public: constexpr QAnyStringView(Char ch, QCharContainer &&capacity = QCharContainer()) noexcept : QAnyStringView{&(capacity.ch = ch), 1} {} template <typename Char, typename Container = decltype(QChar::fromUcs4(U'x')), - std::enable_if_t<std::is_same_v<Char, char32_t>, bool> = true> + if_compatible_utf32_char<Char> = true> constexpr QAnyStringView(Char c, Container &&capacity = {}) noexcept : QAnyStringView(capacity = QChar::fromUcs4(c)) {} diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 09cfbdfe94d..e4f06835bd1 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -66,9 +66,6 @@ template <> struct treat_as_integral_arg<unsigned short> : std::true_type {}; template <> struct treat_as_integral_arg< signed short> : std::true_type {}; template <> struct treat_as_integral_arg<unsigned char> : std::true_type {}; template <> struct treat_as_integral_arg< signed char> : std::true_type {}; -// QTBUG-126054, keep until we can fix it for all platforms, not just Windows -// (where wchar_t does convert to QAnyStringView): -template <> struct treat_as_integral_arg<wchar_t> : std::true_type {}; } // Qt 4.x compatibility diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index 8c129a93c71..d976191406d 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -242,7 +242,7 @@ constexpr bool CanConvertFromWCharT = #endif ; -static_assert(CanConvert<wchar_t> == CanConvertFromWCharT); // ### FIXME: should work everywhere +static_assert(CanConvert<wchar_t>); static_assert(CanConvert< wchar_t[123]> == CanConvertFromWCharT); static_assert(CanConvert<const wchar_t[123]> == CanConvertFromWCharT); @@ -414,7 +414,10 @@ private Q_SLOTS: fromCharacter(U'\x1F0A0', 2, true); // U+1F0A0: PLAYING CARD BACK } void fromWCharT() const { - ONLY_WIN(fromCharacter(L'ä', 1)); // should work on Unix, too (char32_t does) + fromCharacter(L'ä', 1, sizeof(L'ä') == sizeof(char32_t)); +#ifndef Q_OS_WIN // sizedof(wchar_t) == 2 on Windows, so L'\x1F0A0' would be out-of-range + fromCharacter(L'\x1F0A0', 2, true); // U+1F0A0: PLAYING CARD BACK +#endif } void fromQChar() const { fromCharacter(QChar(u'ä'), 1); } void fromQLatin1Char() const { fromCharacter(QLatin1Char('\xE4'), 1, true); } diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index cfc0ec1cc07..2cd1398e7f9 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -6859,10 +6859,7 @@ void tst_QString::arg() // char-ish overloads QCOMPARE(s4.arg('\xE4'), QStringView(u"[ä]")); QCOMPARE(s4.arg(u'ø'), QStringView(u"[ø]")); -#ifdef Q_OS_WIN QCOMPARE(QLatin1String("[%1]").arg(L'ø'), QStringView(u"[ø]")); -#endif - QEXPECT_FAIL("", "QTBUG-126054", Continue); QCOMPARE(s4.arg(L'ø'), QStringView(u"[ø]")); #ifndef __cpp_char8_t #ifndef QT_NO_CAST_FROM_ASCII diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 0b2aaa8281e..7b5b468df0d 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -603,6 +603,8 @@ private Q_SLOTS: void arg1_QString_char16_t() { arg1_impl<QString, char16_t>(); } + void arg1_QString_wchar_t_data() { arg1_data(false); } + void arg1_QString_wchar_t() { arg1_impl<QString, wchar_t>(); } void arg1_QStringView_QString_data() { arg1_data(); } void arg1_QStringView_QString() { arg1_impl<QStringView, QString>(); } @@ -638,6 +640,8 @@ private Q_SLOTS: void arg1_QStringView_QLatin1Char() { arg1_impl<QStringView, QLatin1Char>(); } void arg1_QStringView_char16_t_data() { arg1_data(false); } void arg1_QStringView_char16_t() { arg1_impl<QStringView, char16_t>(); } + void arg1_QStringView_wchar_t_data() { arg1_data(false); } + void arg1_QStringView_wchar_t() { arg1_impl<QStringView, wchar_t>(); } void arg1_QLatin1StringView_QString_data() { arg1_data(); } void arg1_QLatin1StringView_QString() { arg1_impl<QLatin1StringView, QString>(); } @@ -673,6 +677,8 @@ private Q_SLOTS: void arg1_QLatin1StringView_QLatin1Char() { arg1_impl<QLatin1StringView, QLatin1Char>(); } void arg1_QLatin1StringView_char16_t_data() { arg1_data(false); } void arg1_QLatin1StringView_char16_t() { arg1_impl<QLatin1StringView, char16_t>(); } + void arg1_QLatin1StringView_wchar_t_data() { arg1_data(false); } + void arg1_QLatin1StringView_wchar_t() { arg1_impl<QLatin1StringView, wchar_t>(); } void arg1_QUtf8StringView_QString_data() { arg1_data(); } void arg1_QUtf8StringView_QString() { arg1_impl<QUtf8StringView, QString>(); } @@ -708,6 +714,8 @@ private Q_SLOTS: void arg1_QUtf8StringView_QLatin1Char() { arg1_impl<QUtf8StringView, QLatin1Char>(); } void arg1_QUtf8StringView_char16_t_data() { arg1_data(false); } void arg1_QUtf8StringView_char16_t() { arg1_impl<QUtf8StringView, char16_t>(); } + void arg1_QUtf8StringView_wchar_t_data() { arg1_data(false); } + void arg1_QUtf8StringView_wchar_t() { arg1_impl<QUtf8StringView, wchar_t>(); } void arg1_QAnyStringViewUsingL1_QString_data() { arg1_data(); } void arg1_QAnyStringViewUsingL1_QString() { arg1_impl<QAnyStringViewUsingL1, QString>(); } @@ -743,6 +751,8 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingL1_QLatin1Char() { arg1_impl<QAnyStringViewUsingL1, QLatin1Char>(); } void arg1_QAnyStringViewUsingL1_char16_t_data() { arg1_data(false); } void arg1_QAnyStringViewUsingL1_char16_t() { arg1_impl<QAnyStringViewUsingL1, char16_t>(); } + void arg1_QAnyStringViewUsingL1_wchar_t_data() { arg1_data(false); } + void arg1_QAnyStringViewUsingL1_wchar_t() { arg1_impl<QAnyStringViewUsingL1, wchar_t>(); } void arg1_QAnyStringViewUsingU8_QString_data() { arg1_data(); } void arg1_QAnyStringViewUsingU8_QString() { arg1_impl<QAnyStringViewUsingU8, QString>(); } @@ -778,6 +788,8 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingU8_QLatin1Char() { arg1_impl<QAnyStringViewUsingU8, QLatin1Char>(); } void arg1_QAnyStringViewUsingU8_char16_t_data() { arg1_data(false); } void arg1_QAnyStringViewUsingU8_char16_t() { arg1_impl<QAnyStringViewUsingU8, char16_t>(); } + void arg1_QAnyStringViewUsingU8_wchar_t_data() { arg1_data(false); } + void arg1_QAnyStringViewUsingU8_wchar_t() { arg1_impl<QAnyStringViewUsingU8, wchar_t>(); } void arg1_QAnyStringViewUsingU16_QString_data() { arg1_data(); } void arg1_QAnyStringViewUsingU16_QString() { arg1_impl<QAnyStringViewUsingU16, QString>(); } @@ -813,6 +825,8 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingU16_QLatin1Char() { arg1_impl<QAnyStringViewUsingU16, QLatin1Char>(); } void arg1_QAnyStringViewUsingU16_char16_t_data() { arg1_data(false); } void arg1_QAnyStringViewUsingU16_char16_t() { arg1_impl<QAnyStringViewUsingU16, char16_t>(); } + void arg1_QAnyStringViewUsingU16_wchar_t_data() { arg1_data(false); } + void arg1_QAnyStringViewUsingU16_wchar_t() { arg1_impl<QAnyStringViewUsingU16, wchar_t>(); } private: void split_data(bool rhsHasVariableLength = true); @@ -1627,6 +1641,7 @@ template <class Str> Str make(QStringView sf, QLatin1String l1, const QByteArra MAKE(QChar) { return sv.isEmpty() ? QChar() : sv.at(0); } MAKE(char) { return sv.isEmpty() ? char() : char(sv.at(0).unicode()); } MAKE(char16_t) { return sv.isEmpty() ? char16_t() : char16_t{sv.at(0).unicode()}; } +MAKE(wchar_t) { return make<char16_t>(sv, l1, u8); } MAKE(QLatin1Char) { return l1.isEmpty() ? QLatin1Char('\0') : l1.at(0); } MAKE(QString) { return sv.toString(); } MAKE(QStringView) { return sv; } |