Avoid copying TokenStreams while parsing

The code is now even worse mess than before, due to the ad-hoc
implementation of Result-ish type based on virtual functions in
Clara, but it has dropped the allocations for empty binary down
to 151.
This commit is contained in:
Martin Hořeňovský committed 2023-12-27 21:14:12 +01:00
1 parent 5d637d4c6b
commit eaafd07674
2 files changed
+66 -42

No files matched your search

+26 -27
View File
@@ -145,8 +145,8 @@ namespace Catch {
}
ParseState::ParseState( ParseResultType type,
TokenStream const& remainingTokens ):
m_type( type ), m_remainingTokens( remainingTokens ) {}
TokenStream remainingTokens ):
m_type( type ), m_remainingTokens( CATCH_MOVE(remainingTokens) ) {}
ParserResult BoundFlagRef::setFlag( bool flag ) {
m_ref = flag;
@@ -164,27 +164,27 @@ namespace Catch {
} // namespace Detail
Detail::InternalParseResult Arg::parse(std::string const&,
Detail::TokenStream const& tokens) const {
Detail::TokenStream tokens) const {
auto validationResult = validate();
if (!validationResult)
return Detail::InternalParseResult(validationResult);
auto remainingTokens = tokens;
auto const& token = *remainingTokens;
auto token = *tokens;
if (token.type != Detail::TokenType::Argument)
return Detail::InternalParseResult::ok(Detail::ParseState(
ParseResultType::NoMatch, remainingTokens));
ParseResultType::NoMatch, CATCH_MOVE(tokens)));
assert(!m_ref->isFlag());
auto valueRef =
static_cast<Detail::BoundValueRefBase*>(m_ref.get());
auto result = valueRef->setValue(static_cast<std::string>(token.token));
if (!result)
return Detail::InternalParseResult(result);
if ( !result )
return Detail::InternalParseResult( result );
else
return Detail::InternalParseResult::ok(Detail::ParseState(
ParseResultType::Matched, ++remainingTokens));
return Detail::InternalParseResult::ok(
Detail::ParseState( ParseResultType::Matched,
CATCH_MOVE( ++tokens ) ) );
}
Opt::Opt(bool& ref) :
@@ -215,15 +215,14 @@ namespace Catch {
}
Detail::InternalParseResult Opt::parse(std::string const&,
Detail::TokenStream const& tokens) const {
Detail::TokenStream tokens) const {
auto validationResult = validate();
if (!validationResult)
return Detail::InternalParseResult(validationResult);
auto remainingTokens = tokens;
if (remainingTokens &&
remainingTokens->type == Detail::TokenType::Option) {
auto const& token = *remainingTokens;
if (tokens &&
tokens->type == Detail::TokenType::Option) {
auto const& token = *tokens;
if (isMatch(token.token)) {
if (m_ref->isFlag()) {
auto flagRef =
@@ -235,17 +234,17 @@ namespace Catch {
if (result.value() ==
ParseResultType::ShortCircuitAll)
return Detail::InternalParseResult::ok(Detail::ParseState(
result.value(), remainingTokens));
result.value(), CATCH_MOVE(tokens)));
} else {
auto valueRef =
static_cast<Detail::BoundValueRefBase*>(
m_ref.get());
++remainingTokens;
if (!remainingTokens)
++tokens;
if (!tokens)
return Detail::InternalParseResult::runtimeError(
"Expected argument following " +
token.token);
auto const& argToken = *remainingTokens;
auto const& argToken = *tokens;
if (argToken.type != Detail::TokenType::Argument)
return Detail::InternalParseResult::runtimeError(
"Expected argument following " +
@@ -256,14 +255,14 @@ namespace Catch {
if (result.value() ==
ParseResultType::ShortCircuitAll)
return Detail::InternalParseResult::ok(Detail::ParseState(
result.value(), remainingTokens));
result.value(), CATCH_MOVE(tokens)));
}
return Detail::InternalParseResult::ok(Detail::ParseState(
ParseResultType::Matched, ++remainingTokens));
ParseResultType::Matched, CATCH_MOVE(++tokens)));
}
}
return Detail::InternalParseResult::ok(
Detail::ParseState(ParseResultType::NoMatch, remainingTokens));
Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
}
Detail::Result Opt::validate() const {
@@ -295,9 +294,9 @@ namespace Catch {
Detail::InternalParseResult
ExeName::parse(std::string const&,
Detail::TokenStream const& tokens) const {
Detail::TokenStream tokens) const {
return Detail::InternalParseResult::ok(
Detail::ParseState(ParseResultType::NoMatch, tokens));
Detail::ParseState(ParseResultType::NoMatch, CATCH_MOVE(tokens)));
}
ParserResult ExeName::set(std::string const& newName) {
@@ -394,7 +393,7 @@ namespace Catch {
Detail::InternalParseResult
Parser::parse( std::string const& exeName,
Detail::TokenStream const& tokens ) const {
Detail::TokenStream tokens ) const {
struct ParserInfo {
ParserBase const* parser = nullptr;
@@ -412,7 +411,7 @@ namespace Catch {
m_exeName.set( exeName );
auto result = Detail::InternalParseResult::ok(
Detail::ParseState( ParseResultType::NoMatch, tokens ) );
Detail::ParseState( ParseResultType::NoMatch, CATCH_MOVE(tokens) ) );
while ( result.value().remainingTokens() ) {
bool tokenParsed = false;
@@ -420,7 +419,7 @@ namespace Catch {
if ( parseInfo.parser->cardinality() == 0 ||
parseInfo.count < parseInfo.parser->cardinality() ) {
result = parseInfo.parser->parse(
exeName, result.value().remainingTokens() );
exeName, CATCH_MOVE(result).value().remainingTokens() );
if ( !result )
return result;
if ( result.value().type() !=