Skip to content

Commit 35e5628

Browse files
committed
WIP
1 parent 756ae05 commit 35e5628

1 file changed

Lines changed: 71 additions & 2 deletions

File tree

tests/SelfTest/IntrospectiveTests/ToString.tests.cpp

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
// SPDX-License-Identifier: BSL-1.0
88

9+
#include <catch2/benchmark/catch_benchmark.hpp>
10+
#include <catch2/catch_template_test_macros.hpp>
11+
#include <catch2/catch_test_macros.hpp>
12+
#include <catch2/generators/catch_generators.hpp>
913
#include <catch2/internal/catch_enum_values_registry.hpp>
1014
#include <catch2/matchers/catch_matchers_string.hpp>
1115
#include <catch2/matchers/catch_matchers_vector.hpp>
12-
#include <catch2/catch_test_macros.hpp>
13-
#include <catch2/catch_template_test_macros.hpp>
1416

1517
#include <chrono>
1618

@@ -139,3 +141,70 @@ TEST_CASE( "Exception thrown inside stringify does not fail the test", "[toStrin
139141
ThrowsOnStringification tos;
140142
CHECK( tos == tos );
141143
}
144+
145+
namespace {
146+
[[maybe_unused]]
147+
std::string convertIntoString( Catch::StringRef string,
148+
bool escapeInvisibles ) {
149+
std::string ret;
150+
// This is enough for the "don't escape invisibles" case, and a good
151+
// lower bound on the "escape invisibles" case.
152+
ret.reserve( string.size() + 2 );
153+
154+
if ( !escapeInvisibles ) {
155+
ret += '"';
156+
ret += string;
157+
ret += '"';
158+
return ret;
159+
}
160+
161+
size_t last_start = 0;
162+
auto write_to = [&]( size_t idx ) {
163+
if ( last_start < idx ) {
164+
//ret.append( string.data() + last_start, idx - last_start );
165+
ret += string.substr( last_start, idx - last_start );
166+
}
167+
last_start = idx + 1;
168+
};
169+
170+
ret += '"';
171+
for ( size_t i = 0; i < string.size(); ++i ) {
172+
const char c = string[i];
173+
if (c == '\r' || c == '\n' || c == '\t' || c == '\f') {
174+
write_to( i );
175+
if ( c == '\r' ) { ret.append( "\\r" ); }
176+
if ( c == '\n' ) { ret.append( "\\n" ); }
177+
if ( c == '\t' ) { ret.append( "\\t" ); }
178+
if ( c == '\f' ) { ret.append( "\\f" ); }
179+
}
180+
}
181+
write_to( string.size() );
182+
ret += '"';
183+
184+
return ret;
185+
}
186+
}
187+
188+
189+
TEST_CASE( "string escaping benchmark", "[toString][!benchmark]" ) {
190+
const auto input_length = GENERATE( as<size_t>{}, 10, 100, 10'000, 100'000 );
191+
std::string test_input( input_length, 'a' );
192+
BENCHMARK( "no-escape string, no-escaping, len=" +
193+
std::to_string( input_length ) ) {
194+
return Catch::Detail::convertIntoString( test_input, false );
195+
};
196+
BENCHMARK( "no-escape string, escaping, len=" +
197+
std::to_string( input_length ) ) {
198+
return Catch::Detail::convertIntoString( test_input, true );
199+
};
200+
201+
std::string escape_input( input_length, '\r' );
202+
BENCHMARK( "full escape string, no-escaping, len=" +
203+
std::to_string( input_length ) ) {
204+
return Catch::Detail::convertIntoString( escape_input, false );
205+
};
206+
BENCHMARK( "full escape string, escaping, len=" +
207+
std::to_string( input_length ) ) {
208+
return Catch::Detail::convertIntoString( escape_input, true );
209+
};
210+
}

0 commit comments

Comments
 (0)