summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <[email protected]>2024-10-31 13:45:42 +0100
committerMarc Mutz <[email protected]>2025-06-30 17:45:40 +0000
commite9f91f049cb710b97d50a12306eca577be09b6ab (patch)
tree661923389a419b20b72ac06116ce87aeb7d45537
parent6b968b3f1393fa510d93a5e7e63a20648ad8baae (diff)
QAnyStringView: support single wchar_t arguments also on UnixHEADdev
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.cpp1
-rw-r--r--src/corelib/text/qanystringview.h12
-rw-r--r--src/corelib/text/qstring.h3
-rw-r--r--tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp7
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring.cpp3
-rw-r--r--tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp15
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; }