Skip to content

Commit bfefeb1

Browse files
committed
Try out explicit forward expressions, see hsutter#77 comment thread
1 parent 7f4abb1 commit bfefeb1

17 files changed

+127
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <iostream>
2+
#include <utility>
3+
4+
struct X {
5+
int i;
6+
X(int i) : i{ i} { std::cout << "+X " << i << "\n"; }
7+
X(X const& that) : i{that.i} { std::cout << "copy X " << i << "\n"; }
8+
X(X && that) : i{that.i} { std::cout << "move X " << i << "\n"; }
9+
};
10+
11+
discard: (copy x:_) = { }
12+
13+
apply_implicit_forward: (forward t: std::pair<X, X>) = {
14+
discard(t.first);
15+
discard(t.second);
16+
}
17+
18+
apply_explicit_forward: (forward t: std::pair<X, X>) = {
19+
discard(forward t.first);
20+
discard(forward t.second);
21+
}
22+
23+
main: ()->int = {
24+
t1: std::pair<X,X> = (1,2);
25+
apply_implicit_forward(t1);
26+
27+
t2: std::pair<X,X> = (3,4);
28+
apply_explicit_forward(t2);
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
+X 1
2+
+X 2
3+
copy X 1
4+
move X 2
5+
+X 3
6+
+X 4
7+
move X 3
8+
move X 4

regression-tests/test-results/clang-12/mixed-forwarding.cpp.output

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

regression-tests/test-results/clang-12/mixed-ufcs-multiple-template-arguments.cpp.output

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
+X 1
2+
+X 2
3+
copy X 1
4+
move X 2
5+
+X 3
6+
+X 4
7+
move X 3
8+
move X 4

regression-tests/test-results/gcc-10/mixed-forwarding.cpp.output

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

regression-tests/test-results/gcc-10/mixed-ufcs-multiple-template-arguments.cpp.output

Whitespace-only changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// ----- Cpp2 support -----
2+
#include "cpp2util.h"
3+
4+
#line 1 "mixed-forwarding.cpp2"
5+
#include <iostream>
6+
#include <utility>
7+
8+
struct X {
9+
int i;
10+
X(int i) : i{ i} { std::cout << "+X " << i << "\n"; }
11+
X(X const& that) : i{that.i} { std::cout << "copy X " << i << "\n"; }
12+
X(X && that) : i{that.i} { std::cout << "move X " << i << "\n"; }
13+
};
14+
15+
auto discard(auto x) -> void;
16+
#line 13 "mixed-forwarding.cpp2"
17+
auto apply_implicit_forward(auto&& t) -> void;
18+
#line 18 "mixed-forwarding.cpp2"
19+
auto apply_explicit_forward(auto&& t) -> void;
20+
#line 23 "mixed-forwarding.cpp2"
21+
[[nodiscard]] auto main() -> int;
22+
23+
//=== Cpp2 definitions ==========================================================
24+
25+
#line 10 "mixed-forwarding.cpp2"
26+
27+
auto discard(auto x) -> void{}
28+
29+
auto apply_implicit_forward(auto&& t) -> void
30+
requires std::is_same_v<CPP2_TYPEOF(t), std::pair<X,X>>
31+
#line 14 "mixed-forwarding.cpp2"
32+
{ discard(t.first);
33+
discard(CPP2_FORWARD(t).second);
34+
}
35+
36+
auto apply_explicit_forward(auto&& t) -> void
37+
requires std::is_same_v<CPP2_TYPEOF(t), std::pair<X,X>>
38+
#line 19 "mixed-forwarding.cpp2"
39+
{ discard(CPP2_FORWARD(t.first));
40+
discard(CPP2_FORWARD(CPP2_FORWARD(t).second));
41+
}
42+
43+
[[nodiscard]] auto main() -> int{
44+
std::pair<X,X> t1 { 1, 2 };
45+
apply_implicit_forward(std::move(t1));
46+
47+
std::pair<X,X> t2 { 3, 4 };
48+
apply_explicit_forward(std::move(t2));
49+
}
50+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mixed-forwarding.cpp2... ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks)
2+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
+X 1
2+
+X 2
3+
copy X 1
4+
move X 2
5+
+X 3
6+
+X 4
7+
move X 3
8+
move X 4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mixed-forwarding.cpp
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rain
2+
rain
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mixed-ufcs-multiple-template-arguments.cpp

source/cppfront.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,7 +2065,11 @@ class cppfront
20652065
auto is_out = false;
20662066

20672067
if (x.pass != passing_style::in) {
2068-
assert(to_string_view(x.pass) == "out" || to_string_view(x.pass) == "move");
2068+
assert(
2069+
to_string_view(x.pass) == "out" ||
2070+
to_string_view(x.pass) == "move" ||
2071+
to_string_view(x.pass) == "forward"
2072+
);
20692073
if (to_string_view(x.pass) == "out") {
20702074
is_out = true;
20712075
printer.print_cpp2("&", n.position());
@@ -2075,6 +2079,10 @@ class cppfront
20752079
printer.print_cpp2("std::move(", n.position());
20762080
offset = 6; // because we're replacing "move " (followed by at least one space) with "std::move("
20772081
}
2082+
else if (to_string_view(x.pass) == "forward") {
2083+
printer.print_cpp2("CPP2_FORWARD(", n.position());
2084+
offset = 10; // because we're replacing "forward " (followed by at least one space) with "CPP2_FORWARD("
2085+
}
20782086
}
20792087

20802088
if (is_out) {
@@ -2090,7 +2098,7 @@ class cppfront
20902098
in_non_rvalue_context.pop_back();
20912099
}
20922100

2093-
if (to_string_view(x.pass) == "move") {
2101+
if (to_string_view(x.pass) == "move" || to_string_view(x.pass) == "forward") {
20942102
printer.print_cpp2(")", n.position());
20952103
}
20962104
}

source/parse.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,10 @@ class parser
18021802
pass = passing_style::move;
18031803
next();
18041804
}
1805+
else if (curr().type() == lexeme::Identifier && curr() == "forward") {
1806+
pass = passing_style::forward;
1807+
next();
1808+
}
18051809
auto x = expression();
18061810

18071811
// If this is an empty expression_list, we're done

0 commit comments

Comments
 (0)