summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2024-05-22 14:29:30 +0200
committerMarc Mutz <marc.mutz@qt.io>2024-12-03 22:44:54 +0100
commitf7e8e54d7e6803c91cc453afdfc46f3d0b4da9c2 (patch)
treeb7bbd5f28ee2d630b3326e996aefd9d7a6ac9300 /src
parent563ed822f867c6c3040956017d4ca7f3795f172c (diff)
QString: toward UTF-8 arg() support [4/4]: accept QAnyStringViews (incl. UTF-8 ones)
This is the public API for the functionality already implemented in pt.1 of this patch series (except the replacement of the remaining Q_UNREACHABLE). I opted to do the minimal change to enable this important functionality: the ArgBase hierarchy stays and gets extended a bit differently than originally envisioned. ArgBase, of course, is just yet another QAnyStringView re-implementation, so eventually, this will go. But the churn to do this in a binary-compatible way would just be too big. Instead of the U8 tag representing UTF-8 arguments, repurpose this up-to-now unused tag to mean QAnyStringView. This allows to get rid of the qStringLikeToArg() overloads, leaving only one accepting QAnyStringView. This is the only one that new code will ever call. But we still need to support L1 and U16 ArgBases for old code. [ChangeLog][QtCore][QString/QStringView/QAnyStringView] Added (multi-)arg() support for UTF-8 (QUtf8StringView) and QAnyStringView arguments. Passing C string literals or QByteArrays to arg() now no longer implicitly converts to QString first. Fixes: QTBUG-124365 Change-Id: I0d710365a45d2c62af26184e8a857c3f4cdeeae2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/text/qstring.cpp4
-rw-r--r--src/corelib/text/qstring.h24
-rw-r--r--src/corelib/text/qstringview.cpp9
3 files changed, 16 insertions, 21 deletions
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<const QLatin1StringArg&>(arg).string);
break;
- case ArgBase::U8:
- Q_UNREACHABLE(); // waiting for QUtf8String...
+ case ArgBase::Any:
+ part.reset(static_cast<const QAnyStringArg&>(arg).string);
break;
case ArgBase::U16:
part.reset(static_cast<const QStringViewArg&>(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 <typename T>
- using is_convertible_to_view_or_qstring = std::disjunction<
- std::is_convertible<T, QString>,
- std::is_convertible<T, QStringView>,
- std::is_convertible<T, QLatin1StringView>
- >;
public:
template <typename...Args>
[[nodiscard]]
@@ -350,10 +344,7 @@ public:
QString
#else
typename std::enable_if<
- sizeof...(Args) >= 2 && std::is_same<
- QtPrivate::BoolList<is_convertible_to_view_or_qstring<Args>::value..., true>,
- QtPrivate::BoolList<true, is_convertible_to_view_or_qstring<Args>::value...>
- >::value,
+ sizeof...(Args) >= 2 && std::conjunction_v<is_string_like<Args>...>,
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 <typename...Args>
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()
*/