Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal
diff options
context:
space:
mode:
authorMartin Jeřábek2024-02-25 18:01:28 +0100
committerMartin Hořeňovský2024-03-01 21:24:45 +0100
commit4d8affc989cc13f60796f66781b8729d175c18e9 (patch)
treec5ead1e093ba86da285f9fbe77c11236545a32b8 /src/catch2/internal
parentcde35096641d55b4aa0f743bb03e04703fbb5e9c (diff)
downloadcatch3-4d8affc989cc13f60796f66781b8729d175c18e9.tar.gz
less copies and allocations in replaceInPlace
Diffstat (limited to 'src/catch2/internal')
-rw-r--r--src/catch2/internal/catch_string_manip.cpp27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/catch2/internal/catch_string_manip.cpp b/src/catch2/internal/catch_string_manip.cpp
index 0c889ca1..ce1abaa0 100644
--- a/src/catch2/internal/catch_string_manip.cpp
+++ b/src/catch2/internal/catch_string_manip.cpp
@@ -5,6 +5,7 @@
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
+#include <catch2/internal/catch_move_and_forward.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_stringref.hpp>
@@ -65,17 +66,29 @@ namespace Catch {
}
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
- bool replaced = false;
std::size_t i = str.find( replaceThis );
- while( i != std::string::npos ) {
- replaced = true;
- str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
- if( i < str.size()-withThis.size() )
- i = str.find( replaceThis, i+withThis.size() );
+ if (i == std::string::npos) {
+ return false;
+ }
+ std::size_t copyBegin = 0;
+ std::string origStr = CATCH_MOVE(str);
+ str.clear();
+ // There is at least one replacement, so reserve with the best guess
+ // we can make without actually counting the number of occurences.
+ str.reserve(origStr.size() - replaceThis.size() + withThis.size());
+ do {
+ str.append(origStr, copyBegin, i-copyBegin );
+ str += withThis;
+ copyBegin = i + replaceThis.size();
+ if( copyBegin < origStr.size() )
+ i = origStr.find( replaceThis, copyBegin );
else
i = std::string::npos;
+ } while( i != std::string::npos );
+ if ( copyBegin < origStr.size() ) {
+ str.append(origStr, copyBegin, origStr.size() );
}
- return replaced;
+ return true;
}
std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {