Skip to content

Commit e606505

Browse files
authored
Fix support for function multiple forward arguments - close #279 (#293)
* Add support for function multiple forward arguments The current implementation correctly handle one forward argument - it produces correct requires clause. When there are more forward arguments like in following code: ```cpp fun: (forward s1 : std::string, forward s2 : std::string, forward s3 : std::string) = { // ... } ``` generates: ```cpp requires std::is_same_v<CPP2_TYPEOF(s1), std::string>requires std::is_same_v<CPP2_TYPEOF(s2), std::string>requires std::is_same_v<CPP2_TYPEOF(s3), std::string> ``` This change correct this behaviour and creates requires clause that joins multiple clauses with `&&`: ```cpp requires (std::is_same_v<CPP2_TYPEOF(s1), std::string> && std::is_same_v<CPP2_TYPEOF(s2), std::string> && std::is_same_v<CPP2_TYPEOF(s3), std::string>) ``` * Add regression test for multiple forward arguments
1 parent 2639de7 commit e606505

9 files changed

+62
-2
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fun: (forward s1 : std::string, forward s2 : std::string, forward s3 : std::string) = {
2+
std::cout << s1 << s2 << s3 << std::endl;
3+
}
4+
5+
main: () = {
6+
b : std::string = "b";
7+
c : std::string = "c";
8+
fun(std::string("a"), b, c);
9+
b = "";
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
abc

regression-tests/test-results/apple-clang-14/pure2-function-multiple-forward-arguments.cpp.output

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
abc

regression-tests/test-results/clang-12/pure2-function-multiple-forward-arguments.cpp.output

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
#define CPP2_USE_MODULES Yes
3+
4+
#include "cpp2util.h"
5+
6+
7+
#line 1 "pure2-function-multiple-forward-arguments.cpp2"
8+
auto fun(auto&& s1, auto&& s2, auto&& s3) -> void;
9+
#line 5 "pure2-function-multiple-forward-arguments.cpp2"
10+
auto main() -> int;
11+
12+
//=== Cpp2 definitions ==========================================================
13+
14+
#line 1 "pure2-function-multiple-forward-arguments.cpp2"
15+
auto fun(auto&& s1, auto&& s2, auto&& s3) -> void
16+
requires (std::is_same_v<CPP2_TYPEOF(s1), std::string> && std::is_same_v<CPP2_TYPEOF(s2), std::string> && std::is_same_v<CPP2_TYPEOF(s3), std::string>)
17+
#line 2 "pure2-function-multiple-forward-arguments.cpp2"
18+
{ std::cout << CPP2_FORWARD(s1) << CPP2_FORWARD(s2) << CPP2_FORWARD(s3) << std::endl;
19+
}
20+
21+
auto main() -> int{
22+
std::string b {"b"};
23+
std::string c {"c"};
24+
fun(std::string("a"), b, std::move(c));
25+
b = "";
26+
}
27+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fun: (forward s1 : std::string, forward s2 : std::string, forward s3 : std::string) = {
2+
std::cout << s1 << s2 << s3 << std::endl;
3+
}
4+
5+
main: () = {
6+
b : std::string = "b";
7+
c : std::string = "c";
8+
fun(std::string("a"), b, c);
9+
b = "";
10+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-function-multiple-forward-arguments.cpp2... ok (all Cpp2, passes safety checks)
2+

source/cppfront.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4734,8 +4734,17 @@ class cppfront
47344734
if (!function_requires_conditions.empty()) {
47354735
printer.ignore_alignment( true, n.position().colno + 4 );
47364736
printer.print_extra("\n");
4737-
for (auto const& req : function_requires_conditions) {
4738-
printer.print_extra("requires " + req);
4737+
auto is_multi_fwd = function_requires_conditions.size() > 1;
4738+
printer.print_extra("requires ");
4739+
if (is_multi_fwd) {
4740+
printer.print_extra("(");
4741+
}
4742+
printer.print_extra(function_requires_conditions.front());
4743+
for (auto it = std::cbegin(function_requires_conditions)+1; it != std::cend(function_requires_conditions); ++it) {
4744+
printer.print_extra(" && " + *it);
4745+
}
4746+
if (is_multi_fwd) {
4747+
printer.print_extra(")");
47394748
}
47404749
function_requires_conditions = {};
47414750
printer.ignore_alignment( false );

0 commit comments

Comments
 (0)