From ae39a45a40a7d5d8d9ad08a128080c62cdee9063 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 13:48:26 +0300 Subject: [PATCH 1/4] Initial commit with task details for issue #58 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/RegularExpressions.Transformer.CSharpToCpp/issues/58 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..abb8b11 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/RegularExpressions.Transformer.CSharpToCpp/issues/58 +Your prepared branch: issue-58-7e06cbcc +Your prepared working directory: /tmp/gh-issue-solver-1757760503044 + +Proceed. \ No newline at end of file From 0e2e5ba04122a39bccdbfcd260d2f77bd391cd0d Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 14:06:24 +0300 Subject: [PATCH 2/4] Implement modern C++ style improvements for issue #58 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive regex patterns to improve generated C++ code quality: **Type Style Improvements:** - Fix reference positioning: `Type &val` → `Type& val` - Fix pointer positioning: `Type *val` → `Type* val` **Performance Optimizations:** - Add std::move for constructor parameters: `field(string)` → `field(std::move(string))` - Convert function parameters to const references: `func(std::string param)` → `func(const std::string& param)` - Add std::move to container insertions: `vector.push_back(value)` → `vector.push_back(std::move(value))` **Template Enhancements:** - Use universal references: `template func(T arg)` → `template func(T&& arg)` - Add perfect forwarding: `push_back(param)` → `push_back(std::forward(param))` Updated both C# and Python implementations to maintain consistency. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../CSharpToCppTransformer.cs | 27 +++++++ python/cs2cpp/cs2cpp.py | 27 +++++++ test_improvements.cs | 42 +++++++++++ verification_examples.md | 72 +++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 test_improvements.cs create mode 100644 verification_examples.md diff --git a/csharp/Platform.RegularExpressions.Transformer.CSharpToCpp/CSharpToCppTransformer.cs b/csharp/Platform.RegularExpressions.Transformer.CSharpToCpp/CSharpToCppTransformer.cs index 2f5dceb..7dd6930 100644 --- a/csharp/Platform.RegularExpressions.Transformer.CSharpToCpp/CSharpToCppTransformer.cs +++ b/csharp/Platform.RegularExpressions.Transformer.CSharpToCpp/CSharpToCppTransformer.cs @@ -634,6 +634,25 @@ public class CSharpToCppTransformer : TextTransformer // AppDomain.CurrentDomain.ProcessExit -= OnProcessExit; // /* No translation. It is not possible to unsubscribe from std::atexit. */ (new Regex(@"AppDomain\.CurrentDomain\.ProcessExit -= ([a-zA-Z_][a-zA-Z0-9_]*);"), "/* No translation. It is not possible to unsubscribe from std::atexit. */", 0), + // C++ Modern Style Improvements + // std::string &val + // std::string& val + (new Regex(@"(?std::[a-zA-Z0-9_]+|[a-zA-Z][a-zA-Z0-9_]*) &(?[a-zA-Z_][a-zA-Z0-9_]*)"), "${type}& ${var}", 0), + // Type *val + // Type* val + (new Regex(@"(?std::[a-zA-Z0-9_]+|[a-zA-Z][a-zA-Z0-9_]*) \*(?[a-zA-Z_][a-zA-Z0-9_]*)"), "${type}* ${var}", 0), + // constructor(std::string string) : field(string) + // constructor(std::string string) : field(std::move(string)) + (new Regex(@"(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[^)]*std::string [a-zA-Z_][a-zA-Z0-9_]*[^)]*)\)(?\s*:\s*[^{]*?)(?(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[a-zA-Z_][a-zA-Z0-9_]*)\))"), "${constructor}(${params})${init}${field}(std::move(${param}))", 0), + // function(std::string param) + // function(const std::string& param) + (new Regex(@"(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[^)]*?)(?(^|\(|, ))std::string (?[a-zA-Z_][a-zA-Z0-9_]*)(?[^)]*)\)"), "${func}(${before}${sep}const std::string& ${param}${after})", 0), + // function(std::vector param) + // function(const std::vector& param) + (new Regex(@"(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[^)]*?)(?(^|\(|, ))std::(vector|string|unordered_set|unordered_map|set|map)<[^>]+> (?[a-zA-Z_][a-zA-Z0-9_]*)(?[^)]*)\)"), "${func}(${before}${sep}const std::${2}<${3}>& ${param}${after})", 0), + // vector.push_back(value) + // vector.push_back(std::move(value)) for non-const value parameters + (new Regex(@"(?[a-zA-Z_][a-zA-Z0-9_]*)\.push_back\((?[a-zA-Z_][a-zA-Z0-9_]*)\)(?!\s*//.*const)"), "${container}.push_back(std::move(${value}))", 0), }.Cast().ToList(); /// @@ -752,6 +771,14 @@ public class CSharpToCppTransformer : TextTransformer // \n\n} // \n} (new Regex(@"\r?\n[ \t]*\r?\n(?[ \t]*})"), Environment.NewLine + "${end}", 10), + // C++ Universal Reference and std::forward for templates + // template void func(T arg) + // template void func(T&& arg) + (new Regex(@"(?template\s*<\s*typename\s+(?[a-zA-Z_][a-zA-Z0-9_]*)\s*>\s*[^(]*\([^)]*?)(?\k) (?[a-zA-Z_][a-zA-Z0-9_]*)(?[^)]*\))"), "${before}${type}&& ${param}${after}", 0), + // Inside template functions, use std::forward for perfect forwarding + // container.push_back(templateParam) + // container.push_back(std::forward(templateParam)) + (new Regex(@"(?[a-zA-Z_][a-zA-Z0-9_]*)\.push_back\((?[a-zA-Z_][a-zA-Z0-9_]*)\)(?=.*template.*\k)"), "${container}.push_back(std::forward(${param}))", 0), }.Cast().ToList(); /// diff --git a/python/cs2cpp/cs2cpp.py b/python/cs2cpp/cs2cpp.py index 44ab7bb..0fabfaf 100644 --- a/python/cs2cpp/cs2cpp.py +++ b/python/cs2cpp/cs2cpp.py @@ -633,6 +633,25 @@ def __init__( # AppDomain.CurrentDomain.ProcessExit -= OnProcessExit; # /* No translation. It is not possible to unsubscribe from std::atexit. */ SubRule(r"AppDomain\.CurrentDomain\.ProcessExit -= ([a-zA-Z_][a-zA-Z0-9_]*);", r"/* No translation. It is not possible to unsubscribe from std::atexit. */", max_repeat=0), + # C++ Modern Style Improvements + # std::string &val + # std::string& val + SubRule(r"(?Pstd::[a-zA-Z0-9_]+|[a-zA-Z][a-zA-Z0-9_]*) &(?P[a-zA-Z_][a-zA-Z0-9_]*)", r"\g& \g", max_repeat=0), + # Type *val + # Type* val + SubRule(r"(?Pstd::[a-zA-Z0-9_]+|[a-zA-Z][a-zA-Z0-9_]*) \*(?P[a-zA-Z_][a-zA-Z0-9_]*)", r"\g* \g", max_repeat=0), + # constructor(std::string string) : field(string) + # constructor(std::string string) : field(std::move(string)) + SubRule(r"(?P[a-zA-Z_][a-zA-Z0-9_]*)\((?P[^)]*std::string [a-zA-Z_][a-zA-Z0-9_]*[^)]*)\)(?P\s*:\s*[^{]*?)(?P(?P[a-zA-Z_][a-zA-Z0-9_]*)\((?P[a-zA-Z_][a-zA-Z0-9_]*)\))", r"\g(\g)\g\g(std::move(\g))", max_repeat=0), + # function(std::string param) + # function(const std::string& param) + SubRule(r"(?P[a-zA-Z_][a-zA-Z0-9_]*)\((?P[^)]*?)(?P(^|\(|, ))std::string (?P[a-zA-Z_][a-zA-Z0-9_]*)(?P[^)]*)\)", r"\g(\g\gconst std::string& \g\g)", max_repeat=0), + # function(std::vector param) + # function(const std::vector& param) + SubRule(r"(?P[a-zA-Z_][a-zA-Z0-9_]*)\((?P[^)]*?)(?P(^|\(|, ))std::(?Pvector|string|unordered_set|unordered_map|set|map)<(?P[^>]+)> (?P[a-zA-Z_][a-zA-Z0-9_]*)(?P[^)]*)\)", r"\g(\g\gconst std::\g<\g>& \g\g)", max_repeat=0), + # vector.push_back(value) + # vector.push_back(std::move(value)) for non-const value parameters + SubRule(r"(?P[a-zA-Z_][a-zA-Z0-9_]*)\.push_back\((?P[a-zA-Z_][a-zA-Z0-9_]*)\)(?!\s*//.*const)", r"\g.push_back(std::move(\g))", max_repeat=0), ] @@ -745,4 +764,12 @@ def __init__( # \n\n} # \n} SubRule(r"\r?\n[ \t]*\r?\n(?P[ \t]*})", "\n\g", max_repeat=10), + # C++ Universal Reference and std::forward for templates + # template void func(T arg) + # template void func(T&& arg) + SubRule(r"(?Ptemplate\s*<\s*typename\s+(?P[a-zA-Z_][a-zA-Z0-9_]*)\s*>\s*[^(]*\([^)]*?)(?P\k) (?P[a-zA-Z_][a-zA-Z0-9_]*)(?P[^)]*\))", r"\g\g&& \g\g", max_repeat=0), + # Inside template functions, use std::forward for perfect forwarding + # container.push_back(templateParam) + # container.push_back(std::forward(templateParam)) + SubRule(r"(?P[a-zA-Z_][a-zA-Z0-9_]*)\.push_back\((?P[a-zA-Z_][a-zA-Z0-9_]*)\)(?=.*template.*\k)", r"\g.push_back(std::forward)>(\g))", max_repeat=0), ] diff --git a/test_improvements.cs b/test_improvements.cs new file mode 100644 index 0000000..17792c0 --- /dev/null +++ b/test_improvements.cs @@ -0,0 +1,42 @@ +using System; +using Platform.RegularExpressions.Transformer.CSharpToCpp; + +class TestProgram +{ + static void Main() + { + var transformer = new CSharpToCppTransformer(); + + // Test 1: Type& val style + string input1 = "void function(std::string &value) { }"; + string result1 = transformer.Transform(input1); + Console.WriteLine("Test 1 - Type& val style:"); + Console.WriteLine($"Input: {input1}"); + Console.WriteLine($"Output: {result1}"); + Console.WriteLine(); + + // Test 2: Type* val style + string input2 = "void function(int *pointer) { }"; + string result2 = transformer.Transform(input2); + Console.WriteLine("Test 2 - Type* val style:"); + Console.WriteLine($"Input: {input2}"); + Console.WriteLine($"Output: {result2}"); + Console.WriteLine(); + + // Test 3: const& for string parameters + string input3 = "void function(std::string value) { }"; + string result3 = transformer.Transform(input3); + Console.WriteLine("Test 3 - const& for string parameters:"); + Console.WriteLine($"Input: {input3}"); + Console.WriteLine($"Output: {result3}"); + Console.WriteLine(); + + // Test 4: std::move for push_back + string input4 = "vector.push_back(value);"; + string result4 = transformer.Transform(input4); + Console.WriteLine("Test 4 - std::move for push_back:"); + Console.WriteLine($"Input: {input4}"); + Console.WriteLine($"Output: {result4}"); + Console.WriteLine(); + } +} \ No newline at end of file diff --git a/verification_examples.md b/verification_examples.md new file mode 100644 index 0000000..30d7ad3 --- /dev/null +++ b/verification_examples.md @@ -0,0 +1,72 @@ +# C++ Style Improvements Verification + +This document shows the transformations our regex patterns should perform: + +## 1. Type Reference Style (Type& val instead of Type &val) + +**Pattern:** `(?std::[a-zA-Z0-9_]+|[a-zA-Z][a-zA-Z0-9_]*) &(?[a-zA-Z_][a-zA-Z0-9_]*)` +**Replacement:** `${type}& ${var}` + +Examples: +- `std::string &value` → `std::string& value` +- `MyType &ref` → `MyType& ref` + +## 2. Type Pointer Style (Type* val instead of Type *val) + +**Pattern:** `(?std::[a-zA-Z0-9_]+|[a-zA-Z][a-zA-Z0-9_]*) \*(?[a-zA-Z_][a-zA-Z0-9_]*)` +**Replacement:** `${type}* ${var}` + +Examples: +- `int *pointer` → `int* pointer` +- `std::string *ptr` → `std::string* ptr` + +## 3. Constructor std::move Pattern + +**Pattern:** `(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[^)]*std::string [a-zA-Z_][a-zA-Z0-9_]*[^)]*)\)(?\s*:\s*[^{]*?)(?(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[a-zA-Z_][a-zA-Z0-9_]*)\))` +**Replacement:** `${constructor}(${params})${init}${field}(std::move(${param}))` + +Examples: +- `MyClass(std::string str) : field(str)` → `MyClass(std::string str) : field(std::move(str))` + +## 4. Const Reference for std::string Parameters + +**Pattern:** `(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[^)]*?)(?(^|\(|, ))std::string (?[a-zA-Z_][a-zA-Z0-9_]*)(?[^)]*)\)` +**Replacement:** `${func}(${before}${sep}const std::string& ${param}${after})` + +Examples: +- `function(std::string param)` → `function(const std::string& param)` +- `method(int x, std::string str)` → `method(int x, const std::string& str)` + +## 5. Const Reference for Container Parameters + +**Pattern:** `(?[a-zA-Z_][a-zA-Z0-9_]*)\((?[^)]*?)(?(^|\(|, ))std::(vector|string|unordered_set|unordered_map|set|map)<[^>]+> (?[a-zA-Z_][a-zA-Z0-9_]*)(?[^)]*)\)` +**Replacement:** `${func}(${before}${sep}const std::${2}<${3}>& ${param}${after})` + +Examples: +- `function(std::vector vec)` → `function(const std::vector& vec)` + +## 6. std::move for push_back + +**Pattern:** `(?[a-zA-Z_][a-zA-Z0-9_]*)\.push_back\((?[a-zA-Z_][a-zA-Z0-9_]*)\)(?!\s*//.*const)` +**Replacement:** `${container}.push_back(std::move(${value}))` + +Examples: +- `vector.push_back(value)` → `vector.push_back(std::move(value))` + +## 7. Universal Reference for Templates + +**Pattern:** `(?template\s*<\s*typename\s+(?[a-zA-Z_][a-zA-Z0-9_]*)\s*>\s*[^(]*\([^)]*?)(?\k) (?[a-zA-Z_][a-zA-Z0-9_]*)(?[^)]*\))` +**Replacement:** `${before}${type}&& ${param}${after}` + +Examples: +- `template void func(T arg)` → `template void func(T&& arg)` + +## 8. std::forward for Perfect Forwarding + +**Pattern:** `(?[a-zA-Z_][a-zA-Z0-9_]*)\.push_back\((?[a-zA-Z_][a-zA-Z0-9_]*)\)(?=.*template.*\k)` +**Replacement:** `${container}.push_back(std::forward(${param}))` + +Examples: +- In template context: `container.push_back(param)` → `container.push_back(std::forward(param))` + +All these patterns follow modern C++ best practices as requested in the issue. \ No newline at end of file From b7df3248bd6a6ccc0fb55fb68bc5dfb2ece49ef7 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 14:07:06 +0300 Subject: [PATCH 3/4] Remove temporary test file --- test_improvements.cs | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 test_improvements.cs diff --git a/test_improvements.cs b/test_improvements.cs deleted file mode 100644 index 17792c0..0000000 --- a/test_improvements.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using Platform.RegularExpressions.Transformer.CSharpToCpp; - -class TestProgram -{ - static void Main() - { - var transformer = new CSharpToCppTransformer(); - - // Test 1: Type& val style - string input1 = "void function(std::string &value) { }"; - string result1 = transformer.Transform(input1); - Console.WriteLine("Test 1 - Type& val style:"); - Console.WriteLine($"Input: {input1}"); - Console.WriteLine($"Output: {result1}"); - Console.WriteLine(); - - // Test 2: Type* val style - string input2 = "void function(int *pointer) { }"; - string result2 = transformer.Transform(input2); - Console.WriteLine("Test 2 - Type* val style:"); - Console.WriteLine($"Input: {input2}"); - Console.WriteLine($"Output: {result2}"); - Console.WriteLine(); - - // Test 3: const& for string parameters - string input3 = "void function(std::string value) { }"; - string result3 = transformer.Transform(input3); - Console.WriteLine("Test 3 - const& for string parameters:"); - Console.WriteLine($"Input: {input3}"); - Console.WriteLine($"Output: {result3}"); - Console.WriteLine(); - - // Test 4: std::move for push_back - string input4 = "vector.push_back(value);"; - string result4 = transformer.Transform(input4); - Console.WriteLine("Test 4 - std::move for push_back:"); - Console.WriteLine($"Input: {input4}"); - Console.WriteLine($"Output: {result4}"); - Console.WriteLine(); - } -} \ No newline at end of file From 327baa9337f1dcfb2c1d62c5e82b8e1c162d0f18 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 14:07:22 +0300 Subject: [PATCH 4/4] Remove CLAUDE.md - Claude command completed --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index abb8b11..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/RegularExpressions.Transformer.CSharpToCpp/issues/58 -Your prepared branch: issue-58-7e06cbcc -Your prepared working directory: /tmp/gh-issue-solver-1757760503044 - -Proceed. \ No newline at end of file