Skip to content

Commit d4c81a4

Browse files
Copilotnunoplopes
andauthored
Specialize StrCat for constant string literals
- For single-char literals (N==2): use char append to avoid strlen scan - For longer literals (N>2): combine string+space into single append via _MakeStringWithSpace helper using index_sequence - Add #include <array> and #include <utility> required by new templates Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/3ee80ab3-b415-4172-90d7-3a80ee9aa747 Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>
1 parent 9c4c6da commit d4c81a4

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

cpp2rust/converter/converter.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
#include <clang/AST/RecursiveASTVisitor.h>
88
#include <clang/Sema/Sema.h>
99

10+
#include <array>
1011
#include <functional>
1112
#include <optional>
1213
#include <stack>
1314
#include <string>
1415
#include <unordered_map>
1516
#include <unordered_set>
17+
#include <utility>
1618
#include <vector>
1719

1820
#include "converter/lex.h"
@@ -315,7 +317,40 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
315317
template <typename... Ts>
316318
inline void _StrCat(const char *func, int line, const Ts &...vals) {
317319
llvm::errs() << '[' << func << ':' << line << "] ";
318-
((llvm::errs() << vals << '\n', *rs_code_ += vals, *rs_code_ += ' '), ...);
320+
((llvm::errs() << vals << '\n', AppendToCode(*rs_code_, vals)), ...);
321+
}
322+
323+
// Builds a std::array of N chars from the first N-1 chars of s followed by a
324+
// space. Used by AppendToCode to combine a string literal and its trailing
325+
// space into a single contiguous buffer for one append call.
326+
template <std::size_t N, std::size_t... I>
327+
static constexpr std::array<char, N>
328+
_MakeStringWithSpace(const char (&s)[N], std::index_sequence<I...>) {
329+
return {s[I]..., ' '};
330+
}
331+
332+
// General fallback: append val then a space (two operations).
333+
template <typename T>
334+
static void AppendToCode(std::string &rs_code, const T &val) {
335+
rs_code += val;
336+
rs_code += ' ';
337+
}
338+
339+
// Specialization for string literals (const char[N]):
340+
// - N == 2 (single char, e.g. "("): use character append rather than string
341+
// append to avoid a strlen scan.
342+
// - N > 2 (longer string): combine the string and trailing space into one
343+
// contiguous buffer and append it in a single call.
344+
template <std::size_t N>
345+
static void AppendToCode(std::string &rs_code, const char (&val)[N]) {
346+
if constexpr (N == 2) {
347+
rs_code += val[0];
348+
rs_code += ' ';
349+
} else {
350+
const auto combined =
351+
_MakeStringWithSpace(val, std::make_index_sequence<N - 1>{});
352+
rs_code.append(combined.data(), N);
353+
}
319354
}
320355

321356
class Buffer {

0 commit comments

Comments
 (0)