diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index aeeeeb98506..7b83269275f 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -761,6 +761,27 @@ unittest_public: return cacheLineBlocks * cacheLineSize; } + size_type countOccurrence(SmallStringView text) + { + auto found = begin(); + + size_type count = 0; + + while (true) { + found = std::search(found, + end(), + text.begin(), + text.end()); + if (found == end()) + break; + + ++count; + found += text.size(); + } + + return count; + } + private: BasicSmallString(Internal::StringDataLayout data) noexcept : m_data(data) @@ -883,7 +904,6 @@ private: std::memcpy(replacementTextStartPosition.data(), toText.data(), toText.size()); } else { size_type newSize = size() + sizeDifference; - reserve(optimalCapacity(newSize)); setSize(newSize); at(newSize) = 0; } @@ -896,7 +916,15 @@ private: size_type sizeDifference = 0; size_type startIndex = 0; - replaceLargerSizedRecursive(startIndex, fromText, toText, sizeDifference); + size_type replacementTextSizeDifference = toText.size() - fromText.size(); + size_type occurrences = countOccurrence(fromText); + size_type newSize = size() + (replacementTextSizeDifference * occurrences); + + if (occurrences > 0) { + reserve(optimalCapacity(newSize)); + + replaceLargerSizedRecursive(startIndex, fromText, toText, sizeDifference); + } } void setSize(size_type size) diff --git a/tests/unit/unittest/smallstring-test.cpp b/tests/unit/unittest/smallstring-test.cpp index 5dadfbad669..31033e44d4c 100644 --- a/tests/unit/unittest/smallstring-test.cpp +++ b/tests/unit/unittest/smallstring-test.cpp @@ -753,6 +753,42 @@ TEST(SmallString, Clear) ASSERT_TRUE(text.isEmpty()); } +TEST(SmallString, NoOccurrencesForEmptyText) +{ + SmallString text; + + auto occurrences = text.countOccurrence("text"); + + ASSERT_THAT(occurrences, 0); +} + +TEST(SmallString, NoOccurrencesInText) +{ + SmallString text("here is some text, here is some text, here is some text"); + + auto occurrences = text.countOccurrence("texts"); + + ASSERT_THAT(occurrences, 0); +} + +TEST(SmallString, SomeOccurrences) +{ + SmallString text("here is some text, here is some text, here is some text"); + + auto occurrences = text.countOccurrence("text"); + + ASSERT_THAT(occurrences, 3); +} + +TEST(SmallString, SomeMoreOccurrences) +{ + SmallString text("texttexttext"); + + auto occurrences = text.countOccurrence("text"); + + ASSERT_THAT(occurrences, 3); +} + TEST(SmallString, ReplaceWithCharacter) { SmallString text("here is some text, here is some text, here is some text");