QString: add STL-style assign() [1/4]: non-(it,it) overloads
Implemented assign() methods for QString to align with the criteria of std::basic_string, addressing the previously missing functionality. This is a subset of the overloads provided by the standard. Reference: https://en.cppreference.com/w/cpp/string/basic_string/assign The assign(it, it) overload is a bit more complicated and will be added in follow-up patches. [ChangeLog][QtCore][QString] Added assign(). Task-number: QTBUG-106198 Change-Id: Ia1481d184865f46db872cf94c266fef83b962351 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
ef1be84551
commit
54d8d8055e
@ -3309,6 +3309,52 @@ QString &QString::append(QChar ch)
|
||||
Prepends the character \a ch to this string.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString &QString::assign(QAnyStringView v)
|
||||
\since 6.6
|
||||
|
||||
Replaces the contents of this string with a copy of \a v and returns a
|
||||
reference to this string.
|
||||
|
||||
The size of this string will be equal to the size of \a v, converted to
|
||||
UTF-16 as if by \c{v.toString()}. Unlike QAnyStringView::toString(), however,
|
||||
this function only allocates memory if the estimated size exceeds the capacity
|
||||
of this string or this string is shared.
|
||||
|
||||
\sa QAnyStringView::toString()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString &QString::assign(qsizetype n, QChar c)
|
||||
\since 6.6
|
||||
|
||||
Replaces the contents of this string with \a n copies of \a c and
|
||||
returns a reference to this string.
|
||||
|
||||
The size of this string will be equal to \a n, which has to be non-negative.
|
||||
|
||||
This function will only allocate memory if \a n exceeds the capacity of this
|
||||
string or this string is shared.
|
||||
|
||||
\sa fill()
|
||||
*/
|
||||
|
||||
QString &QString::assign(QAnyStringView s)
|
||||
{
|
||||
if (s.size() <= capacity() && isDetached()) {
|
||||
const auto offset = d.freeSpaceAtBegin();
|
||||
if (offset)
|
||||
d.setBegin(d.begin() - offset);
|
||||
resize(0);
|
||||
s.visit([this](auto input) {
|
||||
this->append(input);
|
||||
});
|
||||
} else {
|
||||
*this = s.toString();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString &QString::remove(qsizetype position, qsizetype n)
|
||||
|
||||
|
@ -36,6 +36,8 @@ Q_FORWARD_DECLARE_CF_TYPE(CFString);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
|
||||
#endif
|
||||
|
||||
class tst_QString;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QRegularExpression;
|
||||
@ -116,6 +118,8 @@ constexpr QChar QAnyStringView::back() const
|
||||
class Q_CORE_EXPORT QString
|
||||
{
|
||||
typedef QTypedArrayData<char16_t> Data;
|
||||
|
||||
friend class ::tst_QString;
|
||||
public:
|
||||
typedef QStringPrivate DataPointer;
|
||||
|
||||
@ -375,6 +379,12 @@ public:
|
||||
inline QString &prepend(QLatin1StringView s) { return insert(0, s); }
|
||||
QString &prepend(QUtf8StringView s) { return insert(0, s); }
|
||||
|
||||
QString &assign(QAnyStringView s);
|
||||
inline QString &assign(qsizetype n, QChar c)
|
||||
{
|
||||
Q_ASSERT(n >= 0);
|
||||
return fill(c, n);
|
||||
}
|
||||
inline QString &operator+=(QChar c) { return append(c); }
|
||||
|
||||
inline QString &operator+=(const QString &s) { return append(s); }
|
||||
|
@ -526,6 +526,10 @@ private slots:
|
||||
|
||||
void insert_special_cases();
|
||||
|
||||
void assign();
|
||||
void assign_shared();
|
||||
void assign_uses_prepend_buffer();
|
||||
|
||||
void simplified_data();
|
||||
void simplified();
|
||||
void trimmed();
|
||||
@ -3386,6 +3390,100 @@ void tst_QString::append_bytearray_special_cases()
|
||||
}
|
||||
#endif // !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
|
||||
|
||||
void tst_QString::assign()
|
||||
{
|
||||
// QString &assign(QAnyStringView)
|
||||
{
|
||||
QString str;
|
||||
QCOMPARE(str.assign("data"), u"data");
|
||||
QCOMPARE(str.size(), 4);
|
||||
QCOMPARE(str.assign(u8"data\0data"), u"data\0data");
|
||||
QCOMPARE(str.size(), 4);
|
||||
QCOMPARE(str.assign(u"\0data\0data"), u"\0data\0data");
|
||||
QCOMPARE(str.size(), 0);
|
||||
QCOMPARE(str.assign(QAnyStringView("data\0")), u"data\0");
|
||||
QCOMPARE(str.size(), 4);
|
||||
QCOMPARE(str.assign(QStringView(u"(ノಠ益ಠ)ノ彡┻━┻\0")), u"(ノಠ益ಠ)ノ彡┻━┻\0");
|
||||
QCOMPARE(str.size(), 11);
|
||||
QCOMPARE(str.assign(QUtf8StringView(u8"٩(⁎❛ᴗ❛⁎)۶")), u"٩(⁎❛ᴗ❛⁎)۶");
|
||||
QCOMPARE(str.size(), 9);
|
||||
QCOMPARE(str.assign(QLatin1String("datadata")), u"datadata");
|
||||
QCOMPARE(str.size(), 8);
|
||||
}
|
||||
// QString &assign(qsizetype, char);
|
||||
{
|
||||
QString str;
|
||||
QCOMPARE(str.assign(3, u'è'), u"èèè");
|
||||
QCOMPARE(str.size(), 3);
|
||||
QCOMPARE(str.assign(20, u'd').assign(2, u'ᴗ'), u"ᴗᴗ");
|
||||
QCOMPARE(str.size(), 2);
|
||||
QCOMPARE(str.assign(0, u'x').assign(5, QLatin1Char('d')), u"ddddd");
|
||||
QCOMPARE(str.size(), 5);
|
||||
QCOMPARE(str.assign(3, u'x'), u"xxx");
|
||||
QCOMPARE(str.size(), 3);
|
||||
}
|
||||
// Test chaining
|
||||
{
|
||||
QString str;
|
||||
QCOMPARE(str.assign(300, u'T').assign({"[̲̅$̲̅(̲̅5̲̅)̲̅$̲̅]"}), u"[̲̅$̲̅(̲̅5̲̅)̲̅$̲̅]");
|
||||
QCOMPARE(str.size(), 19);
|
||||
QCOMPARE(str.assign("data").assign(QByteArrayView::fromArray(
|
||||
{std::byte('T'), std::byte('T'), std::byte('T')})), u"TTT");
|
||||
QCOMPARE(str.size(), 3);
|
||||
QCOMPARE(str.assign("data").assign("\0data"), u"\0data");
|
||||
QCOMPARE(str.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::assign_shared()
|
||||
{
|
||||
{
|
||||
QString str = "DATA"_L1;
|
||||
QVERIFY(str.isDetached());
|
||||
auto strCopy = str;
|
||||
QVERIFY(!str.isDetached());
|
||||
QVERIFY(!strCopy.isDetached());
|
||||
QVERIFY(str.isSharedWith(strCopy));
|
||||
QVERIFY(strCopy.isSharedWith(str));
|
||||
|
||||
str.assign(4, u'D');
|
||||
QVERIFY(str.isDetached());
|
||||
QVERIFY(strCopy.isDetached());
|
||||
QVERIFY(!str.isSharedWith(strCopy));
|
||||
QVERIFY(!strCopy.isSharedWith(str));
|
||||
QCOMPARE(str, u"DDDD");
|
||||
QCOMPARE(strCopy, u"DATA");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::assign_uses_prepend_buffer()
|
||||
{
|
||||
const auto capBegin = [](const QString &s) {
|
||||
return s.begin() - s.d.freeSpaceAtBegin();
|
||||
};
|
||||
const auto capEnd = [](const QString &s) {
|
||||
return s.end() + s.d.freeSpaceAtEnd();
|
||||
};
|
||||
// QString &assign(QAnyStringView)
|
||||
{
|
||||
QString withFreeSpaceAtBegin;
|
||||
for (int i = 0; i < 100 && withFreeSpaceAtBegin.d.freeSpaceAtBegin() < 2; ++i)
|
||||
withFreeSpaceAtBegin.prepend(u'd');
|
||||
QCOMPARE_GT(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 1);
|
||||
|
||||
const auto oldCapBegin = capBegin(withFreeSpaceAtBegin);
|
||||
const auto oldCapEnd = capEnd(withFreeSpaceAtBegin);
|
||||
|
||||
QString test(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), u'ȍ');
|
||||
withFreeSpaceAtBegin.assign(test);
|
||||
|
||||
QCOMPARE_EQ(withFreeSpaceAtBegin.d.freeSpaceAtBegin(), 0); // we used the prepend buffer
|
||||
QCOMPARE_EQ(capBegin(withFreeSpaceAtBegin), oldCapBegin);
|
||||
QCOMPARE_EQ(capEnd(withFreeSpaceAtBegin), oldCapEnd);
|
||||
QCOMPARE(withFreeSpaceAtBegin, test);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::operator_pluseq_special_cases()
|
||||
{
|
||||
QString a;
|
||||
|
Loading…
Reference in New Issue
Block a user