Skip to content

Commit f632e83

Browse files
committed
Add variadic member set for @union
And fix the `is_fold_expression` implementation
1 parent 4868673 commit f632e83

13 files changed

+111
-23
lines changed

regression-tests/pure2-union.cpp2

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ main: () = {
1919

2020
x.print_name();
2121

22-
s: std::string = "xyzzy";
23-
x.set_name( s );
22+
x.set_name( "xyzzy", 3 as u8 );
2423

2524
x.print_name();
2625
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
pure2-print.cpp2:50:80: warning: unused parameter 't' [-Wunused-parameter]
1+
pure2-print.cpp2:52:80: warning: unused parameter 't' [-Wunused-parameter]
22
template<typename T> [[nodiscard]] auto outer::mytype::values(T const& t) const& -> values__ret{
33
^
4-
pure2-print.cpp2:61:53: warning: unused parameter 'x' [-Wunused-parameter]
4+
pure2-print.cpp2:63:53: warning: unused parameter 'x' [-Wunused-parameter]
55
auto outer::mytype::variadic(auto const& ...x) -> void{}
66
^
77
2 warnings generated.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
sizeof(x) is 33
22
(not a name)
3-
xyzzy
3+
xyz
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
In file included from pure2-print.cpp:7:
2+
../../../include/cpp2util.h:10005:33: error: expected unqualified-id before ‘static_assert’
3+
pure2-print.cpp2:7:1: note: in expansion of macro ‘CPP2_REQUIRES_’
24
../../../include/cpp2util.h:10005:33: error: expected initializer before ‘static_assert’
3-
pure2-print.cpp2:80:1: note: in expansion of macro ‘CPP2_REQUIRES_’
4-
pure2-print.cpp2:79:37: error: no declaration matches ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
5-
pure2-print.cpp2:79:37: note: no functions named ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
5+
pure2-print.cpp2:89:1: note: in expansion of macro ‘CPP2_REQUIRES_’
6+
pure2-print.cpp2:88:37: error: no declaration matches ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
7+
pure2-print.cpp2:88:37: note: no functions named ‘void outer::print(std::ostream&, const Args& ...) requires cpp2::cmp_greater_eq(sizeof (Args)..., 0)’
68
pure2-print.cpp2:4:7: note: ‘class outer’ defined here
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
sizeof(x) is 33
22
(not a name)
3-
xyzzy
3+
xyz
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
sizeof(x) is 33
22
(not a name)
3-
xyzzy
3+
xyz
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
sizeof(x) is 25
22
(not a name)
3-
xyzzy
3+
xyz

regression-tests/test-results/pure2-union.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ private: std::array<std::byte,cpp2::max(sizeof(std::string), sizeof(cpp2::i32))>
2020
public: [[nodiscard]] auto get_name() const& -> auto&&;
2121
public: [[nodiscard]] auto get_name() & -> auto&&;
2222
public: auto set_name(cpp2::in<std::string> value) & -> void;
23+
public: auto set_name(auto&& ...args) & -> void;
2324
public: [[nodiscard]] auto is_num() const& -> bool;
2425
public: [[nodiscard]] auto get_num() const& -> auto&&;
2526
public: [[nodiscard]] auto get_num() & -> auto&&;
2627
public: auto set_num(cpp2::in<cpp2::i32> value) & -> void;
28+
public: auto set_num(auto&& ...args) & -> void;
2729
private: auto destroy() & -> void;
2830
public: ~name_or_number() noexcept;
2931

@@ -52,12 +54,14 @@ auto main() -> int;
5254
[[nodiscard]] auto name_or_number::get_name() & -> auto&& {
5355
cpp2::Default.expects(is_name(), "");return *cpp2::assert_not_null(reinterpret_cast<std::string*>(&storage__)); }
5456
auto name_or_number::set_name(cpp2::in<std::string> value) & -> void{if (!(is_name())) {destroy();std::construct_at(reinterpret_cast<std::string*>(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast<std::string*>(&storage__)) = value;}discriminator__ = 0;}
57+
auto name_or_number::set_name(auto&& ...args) & -> void{if (!(is_name())) {destroy();std::construct_at(reinterpret_cast<std::string*>(&storage__), args...);}else {*cpp2::assert_not_null(reinterpret_cast<std::string*>(&storage__)) = std::string{args...};}discriminator__ = 0;}
5558
[[nodiscard]] auto name_or_number::is_num() const& -> bool { return discriminator__ == 1; }
5659
[[nodiscard]] auto name_or_number::get_num() const& -> auto&& {
5760
cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast<cpp2::i32 const*>(&storage__)); }
5861
[[nodiscard]] auto name_or_number::get_num() & -> auto&& {
5962
cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast<cpp2::i32*>(&storage__)); }
6063
auto name_or_number::set_num(cpp2::in<cpp2::i32> value) & -> void{if (!(is_num())) {destroy();std::construct_at(reinterpret_cast<cpp2::i32*>(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast<cpp2::i32*>(&storage__)) = value;}discriminator__ = 1;}
64+
auto name_or_number::set_num(auto&& ...args) & -> void{if (!(is_num())) {destroy();std::construct_at(reinterpret_cast<cpp2::i32*>(&storage__), args...);}else {*cpp2::assert_not_null(reinterpret_cast<cpp2::i32*>(&storage__)) = cpp2::i32{args...};}discriminator__ = 1;}
6165
auto name_or_number::destroy() & -> void{
6266
if (discriminator__ == 0) {std::destroy_at(reinterpret_cast<std::string*>(&storage__));}
6367
if (discriminator__ == 1) {std::destroy_at(reinterpret_cast<cpp2::i32*>(&storage__));}
@@ -80,8 +84,7 @@ auto main() -> int{
8084

8185
CPP2_UFCS_0(print_name, x);
8286

83-
std::string s {"xyzzy"};
84-
CPP2_UFCS(set_name, x, std::move(s));
87+
CPP2_UFCS(set_name, x, "xyzzy", cpp2::as_<cpp2::u8, 3>());
8588

8689
CPP2_UFCS_0(print_name, std::move(x));
8790
}

regression-tests/test-results/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.2.1 Build 8917:1248
2+
cppfront compiler v0.2.1 Build 8918:1648
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/build.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8917:1248"
1+
"8918:1648"

source/parse.h

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,12 @@ struct primary_expression_node
145145
std::unique_ptr<literal_node>
146146
> expr;
147147

148+
148149
// API
149150
//
151+
auto is_fold_expression() const
152+
-> bool;
153+
150154
auto is_identifier() const
151155
-> bool;
152156

@@ -230,6 +234,9 @@ struct prefix_expression_node
230234

231235
// API
232236
//
237+
auto is_fold_expression() const
238+
-> bool;
239+
233240
auto is_identifier() const
234241
-> bool;
235242

@@ -285,8 +292,21 @@ struct binary_expression_node
285292
};
286293
std::vector<term> terms;
287294

295+
288296
// API
289297
//
298+
auto is_fold_expression() const
299+
-> bool
300+
{
301+
// This is a fold-expression if any subexpression
302+
// has an identifier named "..."
303+
auto ret = expr->is_fold_expression();
304+
for (auto& x : terms) {
305+
ret |= x.expr->is_fold_expression();
306+
}
307+
return ret;
308+
}
309+
290310
auto lhs_is_id_expression() const
291311
-> bool
292312
{
@@ -405,6 +425,7 @@ struct binary_expression_node
405425
return ret;
406426
}
407427

428+
408429
// Internals
409430
//
410431
auto position() const
@@ -467,6 +488,14 @@ struct expression_node
467488

468489
// API
469490
//
491+
auto is_fold_expression() const
492+
-> bool
493+
{
494+
// This is a fold-expression if any subexpression
495+
// has an identifier named "..."
496+
return expr->is_fold_expression();
497+
}
498+
470499
auto is_standalone_expression() const
471500
-> bool;
472501

@@ -613,12 +642,13 @@ struct expression_list_node
613642
auto is_fold_expression() const
614643
-> bool
615644
{
616-
auto found_ellipsis = false;
645+
// This is a fold-expression if any subexpression
646+
// has an identifier named "..."
647+
auto ret = false;
617648
for (auto& x : expressions) {
618-
auto s = x.expr->to_string();
619-
found_ellipsis |= s.find("...") != s.npos;
649+
ret |= x.expr->is_fold_expression();
620650
}
621-
return found_ellipsis;
651+
return ret;
622652
}
623653

624654

@@ -789,6 +819,14 @@ struct postfix_expression_node
789819

790820
// API
791821
//
822+
auto is_fold_expression() const
823+
-> bool
824+
{
825+
// This is a fold-expression if any subexpression
826+
// has an identifier named "..."
827+
return expr->is_fold_expression();
828+
}
829+
792830
auto is_identifier() const
793831
-> bool
794832
{
@@ -848,6 +886,14 @@ struct postfix_expression_node
848886
auto visit(auto& v, int depth) -> void;
849887
};
850888

889+
auto prefix_expression_node::is_fold_expression() const
890+
-> bool
891+
{
892+
// This is a fold-expression if any subexpression
893+
// has an identifier named "..."
894+
return expr->is_fold_expression();
895+
}
896+
851897
auto prefix_expression_node::is_identifier() const
852898
-> bool
853899
{
@@ -1269,8 +1315,17 @@ struct is_as_expression_node
12691315
};
12701316
std::vector<term> ops;
12711317

1318+
12721319
// API
12731320
//
1321+
auto is_fold_expression() const
1322+
-> bool
1323+
{
1324+
// This is a fold-expression if any subexpression
1325+
// has an identifier named "..."
1326+
return expr->is_fold_expression();
1327+
}
1328+
12741329
auto is_identifier() const
12751330
-> bool
12761331
{
@@ -1389,6 +1444,15 @@ struct id_expression_node
13891444
return 0;
13901445
}
13911446

1447+
auto is_fold_expression() const
1448+
-> bool
1449+
{
1450+
// This is a fold-expression if any subexpression has
1451+
// has an identifier named "..."
1452+
auto tok = get_token();
1453+
return tok && *tok == "...";
1454+
}
1455+
13921456
auto is_empty() const
13931457
-> bool
13941458
{
@@ -1447,6 +1511,24 @@ struct id_expression_node
14471511
};
14481512

14491513

1514+
auto primary_expression_node::is_fold_expression() const
1515+
-> bool
1516+
{
1517+
// This is a fold-expression if any subexpression has
1518+
// has an identifier named "..."
1519+
switch (expr.index()) {
1520+
break;case identifier:
1521+
return *std::get<identifier>(expr) == "...";
1522+
break;case expression_list:
1523+
return std::get<expression_list>(expr)->is_fold_expression();
1524+
break;case id_expression:
1525+
return std::get<id_expression>(expr)->is_fold_expression();
1526+
break;default: ; // the others can't contain folds
1527+
}
1528+
return false;
1529+
}
1530+
1531+
14501532
auto postfix_expression_node::get_first_token_ignoring_this() const
14511533
-> token const*
14521534
{

source/reflect.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,8 @@ namespace cpp2 {
706706
auto parser::apply_type_meta_functions( declaration_node& n )
707707
-> bool
708708
{
709+
assert(n.is_type());
710+
709711
// Get the reflection state ready to pass to the function
710712
auto cs = meta::compiler_services{ &errors, generated_tokens };
711713
auto rtype = meta::type_declaration{ &n, cs };
@@ -1690,8 +1692,8 @@ std::string comma = "";
16901692
CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, " public set_" + cpp2::to_string(a.name) + ": (inout this, value: " + cpp2::to_string(a.type) + ") = { if !is_" + cpp2::to_string(a.name) + "() { destroy(); std::construct_at( reinterpret_cast<*" + cpp2::to_string(a.type) + ">(storage__&), value); } else { reinterpret_cast<*" + cpp2::to_string(a.type) + ">(storage__&)* = value; } discriminator__ = " + cpp2::to_string(a.value) + "; }\n"),
16911693
"could not add set_" + a.name);
16921694

1693-
//t.require( t.add_member( " public set_(a.name)$: (inout this, forward args...: _) = { if !is_(a.name)$() { destroy(); std::construct_at( reinterpret_cast<*(a.type)$>(storage__&), args...); } else { reinterpret_cast<*(a.type)$>(storage__&)* = value; } discriminator__ = :(a.type)$ = (args...); }\n"),
1694-
// "could not add variadic set_" + a.name);
1695+
CPP2_UFCS(require, t, CPP2_UFCS(add_member, t, " public set_" + cpp2::to_string(a.name) + ": (inout this, forward args...: _) = { if !is_" + cpp2::to_string(a.name) + "() { destroy(); std::construct_at( reinterpret_cast<*" + cpp2::to_string(a.type) + ">(storage__&), args...); } else { reinterpret_cast<*" + cpp2::to_string(a.type) + ">(storage__&)* = :" + cpp2::to_string(a.type) + " = (args...); } discriminator__ = " + cpp2::to_string(a.value) + "; }\n"),
1696+
"could not add variadic set_" + a.name);
16951697
}
16961698
{
16971699
std::string destroy = " private destroy: (inout this) = {\n";

source/reflect.h2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,8 +1152,8 @@ union: (inout t : meta::type_declaration)
11521152
t.require( t.add_member( " public set_(a.name)$: (inout this, value: (a.type)$) = { if !is_(a.name)$() { destroy(); std::construct_at( reinterpret_cast<*(a.type)$>(storage__&), value); } else { reinterpret_cast<*(a.type)$>(storage__&)* = value; } discriminator__ = (a.value)$; }\n"),
11531153
"could not add set_" + a.name);
11541154

1155-
//t.require( t.add_member( " public set_(a.name)$: (inout this, forward args...: _) = { if !is_(a.name)$() { destroy(); std::construct_at( reinterpret_cast<*(a.type)$>(storage__&), args...); } else { reinterpret_cast<*(a.type)$>(storage__&)* = value; } discriminator__ = :(a.type)$ = (args...); }\n"),
1156-
// "could not add variadic set_" + a.name);
1155+
t.require( t.add_member( " public set_(a.name)$: (inout this, forward args...: _) = { if !is_(a.name)$() { destroy(); std::construct_at( reinterpret_cast<*(a.type)$>(storage__&), args...); } else { reinterpret_cast<*(a.type)$>(storage__&)* = :(a.type)$ = (args...); } discriminator__ = (a.value)$; }\n"),
1156+
"could not add variadic set_" + a.name);
11571157
}
11581158

11591159
//// Add operator<<

0 commit comments

Comments
 (0)