diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 270bc770e2d..6cff436fae5 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -9113,8 +9113,8 @@ static qsizetype resolveStringRefsAndReturnTotalSize(ParseResult &parts, const A case ArgBase::L1: part.reset(static_cast(arg).string); break; - case ArgBase::U8: - Q_UNREACHABLE(); // waiting for QUtf8String... + case ArgBase::Any: + part.reset(static_cast(arg).string); break; case ArgBase::U16: part.reset(static_cast(arg).string); diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 0af63ca253b..a1d130c2b17 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -337,12 +337,6 @@ private: QString arg_impl(double a, int fieldWidth, char format, int precision, QChar fillChar) const; QString arg_impl(QAnyStringView a, int fieldWidth, QChar fillChar) const; - template - using is_convertible_to_view_or_qstring = std::disjunction< - std::is_convertible, - std::is_convertible, - std::is_convertible - >; public: template [[nodiscard]] @@ -350,10 +344,7 @@ public: QString #else typename std::enable_if< - sizeof...(Args) >= 2 && std::is_same< - QtPrivate::BoolList::value..., true>, - QtPrivate::BoolList::value...> - >::value, + sizeof...(Args) >= 2 && std::conjunction_v...>, QString >::type #endif @@ -1644,7 +1635,7 @@ inline QString &&asString(QString &&s) { return std::move(s); } namespace QtPrivate { struct ArgBase { - enum Tag : uchar { L1, U8, U16 } tag; + enum Tag : uchar { L1, Any, U16 } tag; }; struct QStringViewArg : ArgBase { @@ -1659,6 +1650,12 @@ struct QLatin1StringArg : ArgBase { constexpr explicit QLatin1StringArg(QLatin1StringView v) noexcept : ArgBase{L1}, string{v} {} }; +struct QAnyStringArg : ArgBase { + QAnyStringView string; + QAnyStringArg() = default; + constexpr explicit QAnyStringArg(QAnyStringView v) noexcept : ArgBase{Any}, string{v} {} +}; + #if QT_CORE_REMOVED_SINCE(6, 9) [[nodiscard]] Q_CORE_EXPORT QString argToQString(QStringView pattern, size_t n, const ArgBase **args); [[nodiscard]] Q_CORE_EXPORT QString argToQString(QLatin1StringView pattern, size_t n, const ArgBase **args); @@ -1672,10 +1669,7 @@ template return QtPrivate::argToQString(pattern, sizeof...(Args), argBases); } - inline QStringViewArg qStringLikeToArg(const QString &s) noexcept { return QStringViewArg{qToStringViewIgnoringNull(s)}; } -constexpr inline QStringViewArg qStringLikeToArg(QStringView s) noexcept { return QStringViewArg{s}; } - inline QStringViewArg qStringLikeToArg(const QChar &c) noexcept { return QStringViewArg{QStringView{&c, 1}}; } -constexpr inline QLatin1StringArg qStringLikeToArg(QLatin1StringView s) noexcept { return QLatin1StringArg{s}; } +constexpr inline QAnyStringArg qStringLikeToArg(QAnyStringView s) noexcept { return QAnyStringArg{s}; } } // namespace QtPrivate diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index 1510c31bca5..64d4ffc1f1d 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -517,12 +517,13 @@ QT_BEGIN_NAMESPACE the \a args replaces the \c{%N} with the lowest \c{N} (all of them), the second of the \a args the \c{%N} with the next-lowest \c{N} etc. - \c Args can consist of anything that implicitly converts to QString, - QStringView or QLatin1StringView. - - In addition, the following types are also supported: QChar, QLatin1Char. + \c Args can consist of anything that implicitly converts to QAnyStringView. //![qstring-multi-arg] + \note In Qt versions prior to 6.9, QAnyStringView and UTF-8 strings + (QUtf8StringView, QByteArray, QByteArrayView, \c{const char8_t*}, etc) were + not supported as \a args. + \sa QString::arg() */ diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index ce2a11bc72f..f6f57081906 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -1014,10 +1014,12 @@ void tst_QAnyStringView::arg() const #undef CHECK2 #undef CHECK1 - QCOMPARE_EQ(QAnyStringView(u8"ä %2 %2—%1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), - u"ä \r \r—c C "_s); - QCOMPARE_EQ(QUtf8StringView(u8"ä %2 %2—%1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), - u"ä \r \r—c C "_s); + QCOMPARE_EQ(QAnyStringView(u8"ä %2 %2—%1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u8"Ç"), + u"ä \r \r—c Ç "_s); + QCOMPARE_EQ(QUtf8StringView(u8"ä %2 %2—%1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, "Ç"), + u"ä \r \r—c Ç "_s); + QCOMPARE_EQ(QUtf8StringView(u8"ä %2 %2—%1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, "Ç"_ba), + u"ä \r \r—c Ç "_s); } QTEST_APPLESS_MAIN(tst_QAnyStringView) diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index f2a3c48ce9e..47ad8393e2d 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -550,7 +550,7 @@ private: private Q_SLOTS: // let Formats = {QString, QStringView, QLatin1String, QUtf8StringView, QAnyStringView} - // let Arguments = Formats ∪ {QByteArray, const char*, const char8_t*. const char16_t*, std::u16string, char, QChar, QLatin1Char, char16_t} + // let Arguments = Formats ∪ {QByteArray/View, const char*, const char8_t*, const char16_t*, std::u16string, char, QChar, QLatin1Char, char16_t} // test Formats × Arguments: void arg1_QString_QString_data() { arg1_data(); } void arg1_QString_QString() { arg1_impl(); } @@ -595,8 +595,18 @@ private Q_SLOTS: void arg1_QStringView_QStringView() { arg1_impl(); } void arg1_QStringView_QLatin1StringView_data() { arg1_data(); } void arg1_QStringView_QLatin1StringView() { arg1_impl(); } + void arg1_QStringView_QUtf8StringView_data() { arg1_data(); } + void arg1_QStringView_QUtf8StringView() { arg1_impl(); } + void arg1_QStringView_QAnyStringViewUsingL1_data() { arg1_data(); } + void arg1_QStringView_QAnyStringViewUsingL1() { arg1_impl(); } + void arg1_QStringView_QAnyStringViewUsingU8_data() { arg1_data(); } + void arg1_QStringView_QAnyStringViewUsingU8() { arg1_impl(); } + void arg1_QStringView_QAnyStringViewUsingU16_data() { arg1_data(); } + void arg1_QStringView_QAnyStringViewUsingU16() { arg1_impl(); } void arg1_QStringView_QByteArray_data() { arg1_data(); } void arg1_QStringView_QByteArray() { arg1_impl(); } + void arg1_QStringView_QByteArrayView_data() { arg1_data(); } + void arg1_QStringView_QByteArrayView() { arg1_impl(); } void arg1_QStringView_const_char_star_data() { arg1_data(); } void arg1_QStringView_const_char_star() { arg1_impl(); } void arg1_QStringView_const_char8_t_star_data() { arg1_data(); } @@ -620,8 +630,18 @@ private Q_SLOTS: void arg1_QLatin1StringView_QStringView() { arg1_impl(); } void arg1_QLatin1StringView_QLatin1StringView_data() { arg1_data(); } void arg1_QLatin1StringView_QLatin1StringView() { arg1_impl(); } + void arg1_QLatin1StringView_QUtf8StringView_data() { arg1_data(); } + void arg1_QLatin1StringView_QUtf8StringView() { arg1_impl(); } + void arg1_QLatin1StringView_QAnyStringViewUsingL1_data() { arg1_data(); } + void arg1_QLatin1StringView_QAnyStringViewUsingL1() { arg1_impl(); } + void arg1_QLatin1StringView_QAnyStringViewUsingU8_data() { arg1_data(); } + void arg1_QLatin1StringView_QAnyStringViewUsingU8() { arg1_impl(); } + void arg1_QLatin1StringView_QAnyStringViewUsingU16_data() { arg1_data(); } + void arg1_QLatin1StringView_QAnyStringViewUsingU16() { arg1_impl(); } void arg1_QLatin1StringView_QByteArray_data() { arg1_data(); } void arg1_QLatin1StringView_QByteArray() { arg1_impl(); } + void arg1_QLatin1StringView_QByteArrayView_data() { arg1_data(); } + void arg1_QLatin1StringView_QByteArrayView() { arg1_impl(); } void arg1_QLatin1StringView_const_char_star_data() { arg1_data(); } void arg1_QLatin1StringView_const_char_star() { arg1_impl(); } void arg1_QLatin1StringView_const_char8_t_star_data() { arg1_data(); } @@ -645,8 +665,18 @@ private Q_SLOTS: void arg1_QUtf8StringView_QStringView() { arg1_impl(); } void arg1_QUtf8StringView_QLatin1StringView_data() { arg1_data(); } void arg1_QUtf8StringView_QLatin1StringView() { arg1_impl(); } + void arg1_QUtf8StringView_QUtf8StringView_data() { arg1_data(); } + void arg1_QUtf8StringView_QUtf8StringView() { arg1_impl(); } + void arg1_QUtf8StringView_QAnyStringViewUsingL1_data() { arg1_data(); } + void arg1_QUtf8StringView_QAnyStringViewUsingL1() { arg1_impl(); } + void arg1_QUtf8StringView_QAnyStringViewUsingU8_data() { arg1_data(); } + void arg1_QUtf8StringView_QAnyStringViewUsingU8() { arg1_impl(); } + void arg1_QUtf8StringView_QAnyStringViewUsingU16_data() { arg1_data(); } + void arg1_QUtf8StringView_QAnyStringViewUsingU16() { arg1_impl(); } void arg1_QUtf8StringView_QByteArray_data() { arg1_data(); } void arg1_QUtf8StringView_QByteArray() { arg1_impl(); } + void arg1_QUtf8StringView_QByteArrayView_data() { arg1_data(); } + void arg1_QUtf8StringView_QByteArrayView() { arg1_impl(); } void arg1_QUtf8StringView_const_char_star_data() { arg1_data(); } void arg1_QUtf8StringView_const_char_star() { arg1_impl(); } void arg1_QUtf8StringView_const_char8_t_star_data() { arg1_data(); } @@ -670,8 +700,18 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingL1_QStringView() { arg1_impl(); } void arg1_QAnyStringViewUsingL1_QLatin1StringView_data() { arg1_data(); } void arg1_QAnyStringViewUsingL1_QLatin1StringView() { arg1_impl(); } + void arg1_QAnyStringViewUsingL1_QUtf8StringView_data() { arg1_data(); } + void arg1_QAnyStringViewUsingL1_QUtf8StringView() { arg1_impl(); } + void arg1_QAnyStringViewUsingL1_QAnyStringViewUsingL1_data() { arg1_data(); } + void arg1_QAnyStringViewUsingL1_QAnyStringViewUsingL1() { arg1_impl(); } + void arg1_QAnyStringViewUsingL1_QAnyStringViewUsingU8_data() { arg1_data(); } + void arg1_QAnyStringViewUsingL1_QAnyStringViewUsingU8() { arg1_impl(); } + void arg1_QAnyStringViewUsingL1_QAnyStringViewUsingU16_data() { arg1_data(); } + void arg1_QAnyStringViewUsingL1_QAnyStringViewUsingU16() { arg1_impl(); } void arg1_QAnyStringViewUsingL1_QByteArray_data() { arg1_data(); } void arg1_QAnyStringViewUsingL1_QByteArray() { arg1_impl(); } + void arg1_QAnyStringViewUsingL1_QByteArrayView_data() { arg1_data(); } + void arg1_QAnyStringViewUsingL1_QByteArrayView() { arg1_impl(); } void arg1_QAnyStringViewUsingL1_const_char_star_data() { arg1_data(); } void arg1_QAnyStringViewUsingL1_const_char_star() { arg1_impl(); } void arg1_QAnyStringViewUsingL1_const_char8_t_star_data() { arg1_data(); } @@ -695,8 +735,18 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingU8_QStringView() { arg1_impl(); } void arg1_QAnyStringViewUsingU8_QLatin1StringView_data() { arg1_data(); } void arg1_QAnyStringViewUsingU8_QLatin1StringView() { arg1_impl(); } + void arg1_QAnyStringViewUsingU8_QUtf8StringView_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU8_QUtf8StringView() { arg1_impl(); } + void arg1_QAnyStringViewUsingU8_QAnyStringViewUsingL1_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU8_QAnyStringViewUsingL1() { arg1_impl(); } + void arg1_QAnyStringViewUsingU8_QAnyStringViewUsingU8_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU8_QAnyStringViewUsingU8() { arg1_impl(); } + void arg1_QAnyStringViewUsingU8_QAnyStringViewUsingU16_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU8_QAnyStringViewUsingU16() { arg1_impl(); } void arg1_QAnyStringViewUsingU8_QByteArray_data() { arg1_data(); } void arg1_QAnyStringViewUsingU8_QByteArray() { arg1_impl(); } + void arg1_QAnyStringViewUsingU8_QByteArrayView_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU8_QByteArrayView() { arg1_impl(); } void arg1_QAnyStringViewUsingU8_const_char_star_data() { arg1_data(); } void arg1_QAnyStringViewUsingU8_const_char_star() { arg1_impl(); } void arg1_QAnyStringViewUsingU8_const_char8_t_star_data() { arg1_data(); } @@ -720,8 +770,18 @@ private Q_SLOTS: void arg1_QAnyStringViewUsingU16_QStringView() { arg1_impl(); } void arg1_QAnyStringViewUsingU16_QLatin1StringView_data() { arg1_data(); } void arg1_QAnyStringViewUsingU16_QLatin1StringView() { arg1_impl(); } + void arg1_QAnyStringViewUsingU16_QUtf8StringView_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU16_QUtf8StringView() { arg1_impl(); } + void arg1_QAnyStringViewUsingU16_QAnyStringViewUsingL1_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU16_QAnyStringViewUsingL1() { arg1_impl(); } + void arg1_QAnyStringViewUsingU16_QAnyStringViewUsingU8_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU16_QAnyStringViewUsingU8() { arg1_impl(); } + void arg1_QAnyStringViewUsingU16_QAnyStringViewUsingU16_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU16_QAnyStringViewUsingU16() { arg1_impl(); } void arg1_QAnyStringViewUsingU16_QByteArray_data() { arg1_data(); } void arg1_QAnyStringViewUsingU16_QByteArray() { arg1_impl(); } + void arg1_QAnyStringViewUsingU16_QByteArrayView_data() { arg1_data(); } + void arg1_QAnyStringViewUsingU16_QByteArrayView() { arg1_impl(); } void arg1_QAnyStringViewUsingU16_const_char_star_data() { arg1_data(); } void arg1_QAnyStringViewUsingU16_const_char_star() { arg1_impl(); } void arg1_QAnyStringViewUsingU16_const_char8_t_star_data() { arg1_data(); } diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index 3f87ffc9fc3..fff089042ca 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -495,7 +495,7 @@ void tst_QStringView::arg() const { // nullness checks QCOMPARE(QStringView().arg(QStringView()), ""); - QCOMPARE(QStringView(u"%1").arg(QStringView()), ""); + QCOMPARE(QStringView(u"%1").arg(nullptr), ""); #define CHECK1(pattern, arg1, expected) \ do { \