QString: don't detach in replace(QChar, QChar, case)
If the string is shared, instead of detaching, create a new string and copy the characters from this string, replacing the ones matching "before" with "after", to the new string. Change-Id: I2c33690230d40f3121e60e242666460559258b7b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
482a75fef9
commit
26f8ea1224
@ -3793,27 +3793,39 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
|
||||
*/
|
||||
QString& QString::replace(QChar before, QChar after, Qt::CaseSensitivity cs)
|
||||
{
|
||||
if (d.size) {
|
||||
const qsizetype idx = indexOf(before, 0, cs);
|
||||
if (idx != -1) {
|
||||
detach();
|
||||
const char16_t a = after.unicode();
|
||||
char16_t *i = d.data();
|
||||
char16_t *const e = i + d.size;
|
||||
i += idx;
|
||||
*i = a;
|
||||
++i;
|
||||
if (cs == Qt::CaseSensitive) {
|
||||
const char16_t toReplace = before.unicode();
|
||||
std::replace(i, e, toReplace, a);
|
||||
} else {
|
||||
const char16_t toReplace = foldCase(before.unicode());
|
||||
auto match = [toReplace](const char16_t c) {
|
||||
return foldAndCompare(c, toReplace);
|
||||
};
|
||||
std::replace_if(i, e, match, a);
|
||||
}
|
||||
const qsizetype idx = indexOf(before, 0, cs);
|
||||
if (idx == -1)
|
||||
return *this;
|
||||
|
||||
const char16_t achar = after.unicode();
|
||||
char16_t bchar = before.unicode();
|
||||
|
||||
auto matchesCIS = [](char16_t beforeChar) {
|
||||
return [beforeChar](char16_t ch) { return foldAndCompare(ch, beforeChar); };
|
||||
};
|
||||
|
||||
auto hit = d.begin() + idx;
|
||||
if (!d.needsDetach()) {
|
||||
*hit++ = achar;
|
||||
if (cs == Qt::CaseSensitive) {
|
||||
std::replace(hit, d.end(), bchar, achar);
|
||||
} else {
|
||||
bchar = foldCase(bchar);
|
||||
std::replace_if(hit, d.end(), matchesCIS(bchar), achar);
|
||||
}
|
||||
} else {
|
||||
QString other{ d.size, Qt::Uninitialized };
|
||||
auto dest = std::copy(d.begin(), hit, other.d.begin());
|
||||
*dest++ = achar;
|
||||
++hit;
|
||||
if (cs == Qt::CaseSensitive) {
|
||||
std::replace_copy(hit, d.end(), dest, bchar, achar);
|
||||
} else {
|
||||
bchar = foldCase(bchar);
|
||||
std::replace_copy_if(hit, d.end(), dest, matchesCIS(bchar), achar);
|
||||
}
|
||||
|
||||
swap(other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -764,7 +764,14 @@ void tst_QString::replace_qchar_qchar()
|
||||
QFETCH(Qt::CaseSensitivity, cs);
|
||||
QFETCH(QString, expected);
|
||||
|
||||
QCOMPARE(src.replace(before, after, cs), expected);
|
||||
QString str = src;
|
||||
// Test when string is shared
|
||||
QCOMPARE(str.replace(before, after, cs), expected);
|
||||
|
||||
str = src;
|
||||
// Test when it's not shared
|
||||
str.detach();
|
||||
QCOMPARE(str.replace(before, after, cs), expected);
|
||||
}
|
||||
|
||||
void tst_QString::replace_qchar_qstring_data()
|
||||
|
Loading…
x
Reference in New Issue
Block a user