Skip to content

Commit d3c464d

Browse files
Copilotnunoplopes
andauthored
Merge consecutive string literals in StrCat into a single append
Replace _MakeStringWithSpace (single-literal helper) with _MergeStrings, a constexpr function that handles k string literals at once. Add an all-literal overload of _StrCat (selected by partial ordering whenever every StrCat argument is a string literal) that merges all literals into one buffer and performs a single rs_code append call. StrCat("foo", "bar", "xyz") is now equivalent to StrCat("foo bar xyz"): both produce exactly one append of "foo bar xyz ". Drop #include <utility> which was only needed by the removed _MakeStringWithSpace/std::make_index_sequence code. Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/6b9ad28e-62b4-44a3-bf1e-538e5dc148ef Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>
1 parent 22a3007 commit d3c464d

1 file changed

Lines changed: 33 additions & 14 deletions

File tree

cpp2rust/converter/converter.h

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <string>
1515
#include <unordered_map>
1616
#include <unordered_set>
17-
#include <utility>
1817
#include <vector>
1918

2019
#include "converter/lex.h"
@@ -314,19 +313,42 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
314313

315314
#define StrCat(...) _StrCat(__FUNCTION__, __LINE__, __VA_ARGS__)
316315

316+
// All-literal overload: selected (by partial ordering) when every argument
317+
// is a string literal. Merges all literals (each followed by a space) into
318+
// a single buffer and performs one rs_code append instead of one per literal.
319+
// e.g. StrCat("foo", "bar") is equivalent to StrCat("foo bar").
320+
template <std::size_t... Ns>
321+
inline void _StrCat(const char *func, int line, const char (&...vals)[Ns]) {
322+
llvm::errs() << '[' << func << ':' << line << "] ";
323+
((llvm::errs() << vals << '\n'), ...);
324+
constexpr std::size_t total = (Ns + ...);
325+
const auto merged = _MergeStrings<total>(vals...);
326+
rs_code_->append(merged.data(), total);
327+
}
328+
329+
// General fallback: used when at least one argument is not a string literal.
330+
// Each argument is appended individually (value then space).
317331
template <typename... Ts>
318332
inline void _StrCat(const char *func, int line, const Ts &...vals) {
319333
llvm::errs() << '[' << func << ':' << line << "] ";
320334
((llvm::errs() << vals << '\n', AppendToCode(*rs_code_, vals)), ...);
321335
}
322336

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]..., ' '};
337+
// Merges k string literals (each followed by a space) into a single
338+
// std::array<char, Total> where Total = sum(Ns). The null terminator of
339+
// each literal is dropped and replaced by a space character.
340+
template <std::size_t Total, std::size_t... Ns>
341+
static constexpr std::array<char, Total>
342+
_MergeStrings(const char (&...strs)[Ns]) {
343+
std::array<char, Total> result{};
344+
std::size_t pos = 0;
345+
auto fill = [&](const char *s, std::size_t n) {
346+
for (std::size_t i = 0; i < n - 1; ++i)
347+
result[pos++] = s[i];
348+
result[pos++] = ' ';
349+
};
350+
(fill(strs, Ns), ...);
351+
return result;
330352
}
331353

332354
// General fallback: append val then a space (two operations).
@@ -336,14 +358,11 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
336358
rs_code += ' ';
337359
}
338360

339-
// Specialization for string literals (const char[N]): combines the string
340-
// content and a trailing space into a single contiguous buffer (using the
341-
// compile-time size N to skip any strlen scan) and appends it in one call.
342-
// This covers all lengths, including single-char literals such as "(".
361+
// Specialization for a single string literal in the general (mixed) path:
362+
// reuses _MergeStrings to perform one append call.
343363
template <std::size_t N>
344364
static void AppendToCode(std::string &rs_code, const char (&val)[N]) {
345-
const auto combined =
346-
_MakeStringWithSpace(val, std::make_index_sequence<N - 1>{});
365+
const auto combined = _MergeStrings<N>(val);
347366
rs_code.append(combined.data(), N);
348367
}
349368

0 commit comments

Comments
 (0)