QString: overload append to accept QUtf8StringView

Add the missing overload, among other things it is needed to
implement QTBUG-103302.

[ChangeLog][QtCore][QString] Added append(QUtf8StringView)
overload.

Task-number: QTBUG-103302
Change-Id: I576f73c1919e3a1f1a315d0f82c708e835686eb1
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
bb10
Mate Barany 2022-11-03 13:25:27 +01:00
parent 4ca8a68408
commit d2e1d73bf1
3 changed files with 64 additions and 13 deletions

View File

@ -290,6 +290,26 @@ bool qt_ends_with_impl(Haystack haystack, Needle needle, Qt::CaseSensitivity cs)
return QtPrivate::compareStrings(haystack.right(needleLen), needle, cs) == 0;
}
template <typename T, typename F>
static void append_helper(QString &self, T view, F appendToUtf16)
{
const auto strData = view.data();
const qsizetype strSize = view.size();
auto &d = self.data_ptr();
if (strData && strSize > 0) {
// the number of UTF-8 code units is always at a minimum equal to the number
// of equivalent UTF-16 code units
d.detachAndGrow(QArrayData::GrowsAtEnd, strSize, nullptr, nullptr);
Q_CHECK_PTR(d.data());
Q_ASSERT(strSize <= d.freeSpaceAtEnd());
const auto newEnd = appendToUtf16(self.data() + self.size(), view);
self.resize(newEnd - std::as_const(self).data());
} else if (d.isNull() && !view.isNull()) { // special case
self = QLatin1StringView("");
}
}
} // unnamed namespace
/*
@ -3125,23 +3145,35 @@ QString &QString::append(const QChar *str, qsizetype len)
/*!
\overload append()
Appends the Latin-1 string \a str to this string.
Appends the Latin-1 string view \a str to this string.
*/
QString &QString::append(QLatin1StringView str)
{
const char *s = str.latin1();
const qsizetype len = str.size();
if (s && len > 0) {
d.detachAndGrow(Data::GrowsAtEnd, len, nullptr, nullptr);
Q_CHECK_PTR(d.data());
Q_ASSERT(len <= d->freeSpaceAtEnd());
char16_t *i = d.data() + d.size;
auto appendUtf16 = [](QChar *dst, QLatin1StringView str) {
const qsizetype len = str.size();
const char *s = str.latin1();
char16_t *i = reinterpret_cast<char16_t *>(dst);
qt_from_latin1(i, s, size_t(len));
d.size += len;
d.data()[d.size] = '\0';
} else if (d.isNull() && !str.isNull()) { // special case
d = DataPointer::fromRawData(&_empty, 0);
}
return dst + len;
};
append_helper(*this, str, appendUtf16);
return *this;
}
/*!
\overload append()
\since 6.5
Appends the UTF-8 string view \a str to this string.
*/
QString &QString::append(QUtf8StringView str)
{
auto appendUtf16 = [](QChar *dst, QUtf8StringView str) {
return QUtf8::convertToUnicode(dst, str);
};
append_helper(*this, str, appendUtf16);
return *this;
}

View File

@ -693,6 +693,7 @@ public:
QString &append(const QString &s);
inline QString &append(QStringView v) { return append(v.data(), v.size()); }
QString &append(QLatin1StringView s);
QString &append(QUtf8StringView s);
inline QString &prepend(QChar c) { return insert(0, c); }
inline QString &prepend(const QChar *uc, qsizetype len) { return insert(0, uc, len); }

View File

@ -150,6 +150,22 @@ public:
{ (s.*mf)(a1, l1); }
};
template <bool b>
class Arg<QBasicUtf8StringView<b>>
{
QUtf8StringView u8;
public:
explicit Arg(const char *str) : u8(str) {}
template <typename MemFunc>
void apply0(QString &s, MemFunc mf) const
{ (s.*mf)(u8); }
template <typename MemFunc, typename A1>
void apply1(QString &s, MemFunc mf, A1 a1) const
{ (s.*mf)(a1, u8); }
};
template <>
class Arg<char>
{
@ -402,6 +418,8 @@ private slots:
void append_qstringview_data() { append_data(EmptyIsNoop); }
void append_qlatin1string() { append_impl<QLatin1String, QString &(QString::*)(QLatin1String)>(); }
void append_qlatin1string_data() { append_data(Latin1Encoded); }
void append_qutf8stringview() { append_impl<QUtf8StringView, QString &(QString::*)(QUtf8StringView)>(); }
void append_qutf8stringview_data() { append_data(); }
void append_qcharstar_int() { append_impl<QPair<const QChar *, int>, QString&(QString::*)(const QChar *, qsizetype)>(); }
void append_qcharstar_int_data() { append_data(EmptyIsNoop); }
void append_qchar() { append_impl<QChar, QString &(QString::*)(QChar)>(); }