From 8d43ef666d74a5e715ca5a8b490838aafe1af8a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:25:49 +0000 Subject: [PATCH 1/5] refactor: replace std::regex_replace with cheaper string alternatives Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/e2a9ad06-b710-45c2-9ef9-b2ee3873b11c Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com> --- cpp2rust/converter/converter.cpp | 8 ++-- cpp2rust/converter/converter_lib.h | 13 +++++- cpp2rust/converter/mapper.cpp | 48 +++++++++++++++------ cpp2rust/converter/plugins/emplace_back.cpp | 5 +-- cpp2rust/converter/translation_rule.cpp | 1 - 5 files changed, 51 insertions(+), 24 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 5cad686c..6db513fb 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -9,7 +9,6 @@ #include #include -#include #include "compiler.h" #include "converter/converter_lib.h" @@ -381,7 +380,7 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) { } if (decl->isFileVarDecl()) { - name = std::regex_replace(Mapper::ToString(decl), std::regex("::"), "_"); + name = ReplaceAll(Mapper::ToString(decl), "::", "_"); if ((decl->isExternallyDeclarable() && !decl->hasInit()) || !globals_.insert(name).second) { return false; @@ -2135,8 +2134,7 @@ std::string Converter::ConvertDeclRefExpr(clang::DeclRefExpr *expr) { enum_constant->getDeclContext())), enum_constant->getName().str()); } else if (IsGlobalVar(expr)) { - return std::regex_replace(Mapper::ToString(expr->getDecl()), - std::regex("::"), "_"); + return ReplaceAll(Mapper::ToString(expr->getDecl()), "::", "_"); } return GetNamedDeclAsString(decl); @@ -2884,7 +2882,7 @@ std::string Converter::GetRecordName(const clang::NamedDecl *decl) const { if (auto it = inner_structs_.find(ID); it != inner_structs_.end()) { return it->second; } - return std::regex_replace(Mapper::ToString(decl), std::regex("::"), "_"); + return ReplaceAll(Mapper::ToString(decl), "::", "_"); } std::vector diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index c82dbb3c..4e4203e6 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -167,4 +166,16 @@ std::vector GetSwitchCaseBody(clang::CompoundStmt *body, void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix); +inline std::string ReplaceAll(std::string str, std::string_view from, + std::string_view to) { + if (from.empty()) + return str; + size_t pos = 0; + while ((pos = str.find(from, pos)) != std::string::npos) { + str.replace(pos, from.size(), to); + pos += to.size(); + } + return str; +} + } // namespace cpp2rust diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 9193b32f..638959fb 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -8,9 +8,9 @@ #include #include +#include #include #include -#include #include #include @@ -546,19 +546,41 @@ std::string mapTypeStringRecursive(const std::string &cpp_type) { return instantiateTgt(subs, rule->second.type_info.type); } -std::string normalizeTranslationRule(std::string rule) { - const std::array, 2> normalization_rules{{ - // Dettach pointer from double reference. Useful for matching translation - // rules. - {std::regex(R"(\*\&\&)"), "* &&"}, - // Ignore constant template parameters, i.e. replace them with _. - {std::regex(R"(\b\d+\b)"), "_"}, - }}; - - for (const auto &r : normalization_rules) { - rule = std::regex_replace(rule, r.first, r.second); +// Replace digit sequences that are not adjacent to other word characters with +// '_'. Equivalent to the regex \b\d+\b. +static std::string replaceWordBoundaryDigits(std::string_view str) { + std::string result; + result.reserve(str.size()); + auto is_word_char = [](char c) { + return std::isalnum((unsigned char)c) || c == '_'; + }; + size_t i = 0; + while (i < str.size()) { + if (std::isdigit((unsigned char)str[i])) { + bool start_ok = (i == 0 || !is_word_char(str[i - 1])); + size_t start = i; + while (i < str.size() && std::isdigit((unsigned char)str[i])) { + ++i; + } + bool end_ok = (i == str.size() || !is_word_char(str[i])); + if (start_ok && end_ok) { + result += '_'; + } else { + result.append(str.data() + start, i - start); + } + } else { + result += str[i++]; + } } + return result; +} +std::string normalizeTranslationRule(std::string rule) { + // Dettach pointer from double reference. Useful for matching translation + // rules. + rule = ReplaceAll(std::move(rule), "*&&", "* &&"); + // Ignore constant template parameters, i.e. replace them with _. + rule = replaceWordBoundaryDigits(rule); return rule; } @@ -674,7 +696,7 @@ bool ParamIsPointer(const clang::Expr *expr, unsigned index) { void AddRuleForUserDefinedType(clang::NamedDecl *decl) { auto cpp_name = ToString(decl); - auto rs_name = std::regex_replace(cpp_name, std::regex("::"), "_"); + auto rs_name = ReplaceAll(cpp_name, "::", "_"); if (types_.contains(cpp_name)) { return; diff --git a/cpp2rust/converter/plugins/emplace_back.cpp b/cpp2rust/converter/plugins/emplace_back.cpp index 26cf371f..9c156af5 100644 --- a/cpp2rust/converter/plugins/emplace_back.cpp +++ b/cpp2rust/converter/plugins/emplace_back.cpp @@ -3,8 +3,6 @@ #include -#include - #include "converter/converter_lib.h" #include "converter/mapper.h" #include "converter/models/converter_refcount.h" @@ -139,8 +137,7 @@ clang::CXXConstructExpr *buildConstructExpr(clang::CXXMemberCallExpr *call, void Converter::emplace_back_emit_push_open(clang::CXXMemberCallExpr *call) { { PushExprKind push(*this, ExprKind::LValue); - StrCat(std::regex_replace(ToString(call->getCallee()), - std::regex("emplace_back"), "push")); + StrCat(ReplaceAll(ToString(call->getCallee()), "emplace_back", "push")); } StrCat("("); } diff --git a/cpp2rust/converter/translation_rule.cpp b/cpp2rust/converter/translation_rule.cpp index f3433bbd..b39bb178 100644 --- a/cpp2rust/converter/translation_rule.cpp +++ b/cpp2rust/converter/translation_rule.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include From 6cf16b50128679730665b5ab6a48423a9262c6d6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:27:43 +0000 Subject: [PATCH 2/5] fix: correct typo 'Dettach' -> 'Detach' in comment Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/e2a9ad06-b710-45c2-9ef9-b2ee3873b11c Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com> --- cpp2rust/converter/mapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 638959fb..ceb34d16 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -576,7 +576,7 @@ static std::string replaceWordBoundaryDigits(std::string_view str) { } std::string normalizeTranslationRule(std::string rule) { - // Dettach pointer from double reference. Useful for matching translation + // Detach pointer from double reference. Useful for matching translation // rules. rule = ReplaceAll(std::move(rule), "*&&", "* &&"); // Ignore constant template parameters, i.e. replace them with _. From 29aa19a3f54d789dc56ce72286efe7663a3afd7a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:34:45 +0000 Subject: [PATCH 3/5] revert: restore normalizeTranslationRule to use std::regex_replace Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/0703124b-eddd-4240-bcdd-b114812b1b87 Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com> --- cpp2rust/converter/mapper.cpp | 46 +++++++++-------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index ceb34d16..434d18c4 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include #include #include @@ -546,41 +546,19 @@ std::string mapTypeStringRecursive(const std::string &cpp_type) { return instantiateTgt(subs, rule->second.type_info.type); } -// Replace digit sequences that are not adjacent to other word characters with -// '_'. Equivalent to the regex \b\d+\b. -static std::string replaceWordBoundaryDigits(std::string_view str) { - std::string result; - result.reserve(str.size()); - auto is_word_char = [](char c) { - return std::isalnum((unsigned char)c) || c == '_'; - }; - size_t i = 0; - while (i < str.size()) { - if (std::isdigit((unsigned char)str[i])) { - bool start_ok = (i == 0 || !is_word_char(str[i - 1])); - size_t start = i; - while (i < str.size() && std::isdigit((unsigned char)str[i])) { - ++i; - } - bool end_ok = (i == str.size() || !is_word_char(str[i])); - if (start_ok && end_ok) { - result += '_'; - } else { - result.append(str.data() + start, i - start); - } - } else { - result += str[i++]; - } +std::string normalizeTranslationRule(std::string rule) { + const std::array, 2> normalization_rules{{ + // Detach pointer from double reference. Useful for matching translation + // rules. + {std::regex(R"(\*\&\&)"), "* &&"}, + // Ignore constant template parameters, i.e. replace them with _. + {std::regex(R"(\b\d+\b)"), "_"}, + }}; + + for (const auto &r : normalization_rules) { + rule = std::regex_replace(rule, r.first, r.second); } - return result; -} -std::string normalizeTranslationRule(std::string rule) { - // Detach pointer from double reference. Useful for matching translation - // rules. - rule = ReplaceAll(std::move(rule), "*&&", "* &&"); - // Ignore constant template parameters, i.e. replace them with _. - rule = replaceWordBoundaryDigits(rule); return rule; } From fbcf7a182e6b04f71a0c9a1a201612c713955d96 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:40:57 +0000 Subject: [PATCH 4/5] refactor: move ReplaceAll definition from header to converter_lib.cpp Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/5adfcfd4-fbee-476c-afc9-cb60f688cec2 Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com> --- cpp2rust/converter/converter_lib.cpp | 12 ++++++++++++ cpp2rust/converter/converter_lib.h | 13 ++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 88a4c9b1..126271cd 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -762,4 +762,16 @@ void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix) { } } +std::string ReplaceAll(std::string str, std::string_view from, + std::string_view to) { + if (from.empty()) + return str; + size_t pos = 0; + while ((pos = str.find(from, pos)) != std::string::npos) { + str.replace(pos, from.size(), to); + pos += to.size(); + } + return str; +} + } // namespace cpp2rust diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index 4e4203e6..71219c8e 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -166,16 +166,7 @@ std::vector GetSwitchCaseBody(clang::CompoundStmt *body, void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix); -inline std::string ReplaceAll(std::string str, std::string_view from, - std::string_view to) { - if (from.empty()) - return str; - size_t pos = 0; - while ((pos = str.find(from, pos)) != std::string::npos) { - str.replace(pos, from.size(), to); - pos += to.size(); - } - return str; -} +std::string ReplaceAll(std::string str, std::string_view from, + std::string_view to); } // namespace cpp2rust From ef1cd792f3706d045beab8f8bb6e804b6f3fdc7e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:46:41 +0000 Subject: [PATCH 5/5] refactor: remove unnecessary empty check in ReplaceAll Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/73fb334b-46a8-4ab4-96ed-332380c8dcdf Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com> --- cpp2rust/converter/converter_lib.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 126271cd..a16fd19d 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -764,8 +764,6 @@ void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix) { std::string ReplaceAll(std::string str, std::string_view from, std::string_view to) { - if (from.empty()) - return str; size_t pos = 0; while ((pos = str.find(from, pos)) != std::string::npos) { str.replace(pos, from.size(), to);