Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,69 @@ public static void Main(string[] args)
var actualResult = transformer.Transform(helloWorldCode);
Assert.Equal(expectedResult, actualResult);
}

[Fact]
public void BigTypeParametersTest()
{
// Test a simple case first - just std::string
const string code = @"void function(std::string name)";
var transformer = new CSharpToCppTransformer();
var actualResult = transformer.Transform(code);

// Check that std::string becomes const std::string&
Assert.Contains("const std::string& name", actualResult);
}

[Fact]
public void UniversalReferenceParametersTest()
{
const string code = @"void function(auto&& param)
{
// body
}";
const string expectedResult = @"void function(auto&& param)
{
// body
};";
var transformer = new CSharpToCppTransformer();
var actualResult = transformer.Transform(code);
Assert.Equal(expectedResult, actualResult);
}

[Fact]
public void StdForwardTest()
{
const string code = @"void function(auto&& param)
{
list.push_back(param);
}";
const string expectedResult = @"void function(auto&& param)
{
list.push_back(std::forward<decltype(param)>(param));
};";
var transformer = new CSharpToCppTransformer();
var actualResult = transformer.Transform(code);
Assert.Equal(expectedResult, actualResult);
}

[Fact]
public void MixedParameterTypesTest()
{
const string code = @"void function(std::vector<big_type> list, big_type case1, const big_type& case2, auto&& case3)
{
list.push_back(case1);
list.push_back(case2);
list.push_back(case3);
}";
const string expectedResult = @"void function(const std::vector<big_type>& list, const big_type& case1, const big_type& case2, auto&& case3)
{
list.push_back(std::forward<decltype(case1)>(case1));
list.push_back(std::forward<decltype(case2)>(case2));
list.push_back(std::forward<decltype(case3)>(case3));
};";
var transformer = new CSharpToCppTransformer();
var actualResult = transformer.Transform(code);
Assert.Equal(expectedResult, actualResult);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,12 @@ public class CSharpToCppTransformer : TextTransformer
// IDisposable disposable)
// IDisposable &disposable)
(new Regex(@"(?<argumentAbstractType>I[A-Z][a-zA-Z0-9]+(<[^>\r\n]+>)?) (?<argument>[_a-zA-Z0-9]+)(?<after>,|\))"), "${argumentAbstractType} &${argument}${after}", 0),
// std::vector<std::int32_t> list) or std::string name) or MyClass obj) -> const std::vector<std::int32_t>& list) or const std::string& name) or const MyClass& obj)
// Convert big types to const references for better performance
(new Regex(@"(?<bigType>std::(vector|string|map|set|list|unordered_map|unordered_set|multimap|multiset|deque|array|queue|stack|priority_queue)<[^>\r\n]*>|std::(string|wstring)|[A-Z][a-zA-Z0-9]*(<[^>\r\n]+>)?) (?<argument>[_a-zA-Z0-9]+)(?<after>,|\))"), "const ${bigType}& ${argument}${after}", 5),
// auto&& param) -> auto&& param) (keep universal references as is)
// This rule preserves universal references for perfect forwarding
(new Regex(@"(?<universalRef>auto&&) (?<argument>[_a-zA-Z0-9]+)(?<after>,|\))"), "${universalRef} ${argument}${after}", 0),
// ICounter<int, int> c1;
// ICounter<int, int>* c1;
(new Regex(@"(?<abstractType>I[A-Z][a-zA-Z0-9]+(<[^>\r\n]+>)?) (?<variable>[_a-zA-Z0-9]+)(?<after> = null)?;"), "${abstractType} *${variable}${after};", 0),
Expand Down Expand Up @@ -741,6 +747,10 @@ public class CSharpToCppTransformer : TextTransformer
// \Anamespace
(new Regex(@"(\A)(\r?\n)+namespace"), "$1namespace", 0),
// \A \n ... class
// Transform universal reference parameters to use std::forward
// For parameters declared as auto&& that are passed to functions, use std::forward
// push_back(param) where param is auto&& -> push_back(std::forward<decltype(param)>(param))
(new Regex(@"(?<method>push_back|emplace_back|insert|emplace)\((?<param>[_a-zA-Z0-9]+)\)(?=\s*(;|,|\)))"), "${method}(std::forward<decltype(${param})>(${param}))", 0),
// \Aclass
(new Regex(@"(\A)(\r?\n)+class"), "$1class", 0),
// \n\n\n
Expand Down
Loading