In StdRegexStrategy::Match (cucumber_cpp/library/cucumber_expression/StdRegexStrategy.cpp), the input std::string_view text is currently copied into a local std::string textStr solely because std::regex_search with std::smatch requires lvalue string iterators. This allocation is unnecessary if we switch to std::regex_search overloads that work on arbitrary iterator ranges paired with std::match_results<std::string_view::const_iterator> (aka std::svmatch in C++20, or std::match_results<const char*>/std::cmatch).
Current code:
std::optional<std::vector<std::optional<MatchGroup>>> StdRegexStrategy::Match(std::string_view text) const
{
std::string textStr{ text }; // unnecessary copy
std::smatch match;
if (!std::regex_search(textStr, match, regex))
return std::nullopt;
// ... extract groups from match ...
}
Proposed approach:
std::optional<std::vector<std::optional<MatchGroup>>> StdRegexStrategy::Match(std::string_view text) const
{
std::cmatch match; // match_results<const char*>
if (!std::regex_search(text.data(), text.data() + text.size(), match, regex))
return std::nullopt;
// positions now refer directly into the original text buffer
// match[i].str() still returns std::string copies for value
// match.position(i) and match.length(i) work as before
}
Using std::cmatch (i.e. std::match_results<const char*>) avoids the temporary string entirely. The regex_search(const char*, const char*, cmatch&, regex) overload is well-defined and the resulting cmatch references the original text data directly — no lifetime concerns as long as the match is consumed before text goes out of scope (which it already is).
File: cucumber_cpp/library/cucumber_expression/StdRegexStrategy.cpp
In
StdRegexStrategy::Match(cucumber_cpp/library/cucumber_expression/StdRegexStrategy.cpp), the inputstd::string_view textis currently copied into a localstd::string textStrsolely becausestd::regex_searchwithstd::smatchrequires lvalue string iterators. This allocation is unnecessary if we switch tostd::regex_searchoverloads that work on arbitrary iterator ranges paired withstd::match_results<std::string_view::const_iterator>(akastd::svmatchin C++20, orstd::match_results<const char*>/std::cmatch).Current code:
Proposed approach:
Using
std::cmatch(i.e.std::match_results<const char*>) avoids the temporary string entirely. Theregex_search(const char*, const char*, cmatch&, regex)overload is well-defined and the resultingcmatchreferences the originaltextdata directly — no lifetime concerns as long as the match is consumed beforetextgoes out of scope (which it already is).File:
cucumber_cpp/library/cucumber_expression/StdRegexStrategy.cpp