Skip to content

Commit 1886ed2

Browse files
committed
Add struct meta function, another from P0707 section 3
It's simpler than in P0707 though because of Cpp2's `operator=` unification
1 parent 70e30c1 commit 1886ed2

File tree

5 files changed

+92
-10
lines changed

5 files changed

+92
-10
lines changed

regression-tests/pure2-types-ordering-via-meta-functions.cpp2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ person_in_family_tree: @partially_ordered type = {
1414
operator=: (out this, parents: int) = { dummy_data = parents; }
1515
}
1616

17+
mystruct: @struct type = {
18+
val: int = 0;
19+
}
20+
1721
main: () = {
1822
a: my_integer = 1;
1923
b: my_integer = 2;
@@ -41,4 +45,6 @@ main: () = {
4145
else {
4246
std::cout << "more\n";
4347
}
48+
49+
s: mystruct = ();
4450
}

regression-tests/test-results/pure2-types-ordering-via-meta-functions.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class case_insensitive_string;
1919
class person_in_family_tree;
2020

2121

22+
#line 17 "pure2-types-ordering-via-meta-functions.cpp2"
23+
class mystruct;
24+
25+
2226
//=== Cpp2 type definitions and function declarations ===========================
2327

2428

@@ -62,6 +66,18 @@ public: [[nodiscard]] auto operator<=>(person_in_family_tree const& that) const
6266
#line 15 "pure2-types-ordering-via-meta-functions.cpp2"
6367
};
6468

69+
class mystruct {
70+
public: int val {0};
71+
public: mystruct(mystruct const& that);
72+
73+
public: auto operator=(mystruct const& that) -> mystruct& ;
74+
public: mystruct(mystruct&& that);
75+
public: auto operator=(mystruct&& that) -> mystruct& ;
76+
public: mystruct();
77+
78+
#line 19 "pure2-types-ordering-via-meta-functions.cpp2"
79+
};
80+
6581
auto main() -> int;
6682

6783

@@ -103,8 +119,21 @@ auto main() -> int;
103119
return *this;
104120
#line 14 "pure2-types-ordering-via-meta-functions.cpp2"
105121
}
106-
107-
#line 17 "pure2-types-ordering-via-meta-functions.cpp2"
122+
123+
mystruct::mystruct(mystruct const& that)
124+
: val{ that.val }{}
125+
126+
auto mystruct::operator=(mystruct const& that) -> mystruct& {
127+
val = that.val;
128+
return *this;}
129+
mystruct::mystruct(mystruct&& that)
130+
: val{ std::move(that).val }{}
131+
auto mystruct::operator=(mystruct&& that) -> mystruct& {
132+
val = std::move(that).val;
133+
return *this;}
134+
135+
mystruct::mystruct(){}
136+
#line 21 "pure2-types-ordering-via-meta-functions.cpp2"
108137
auto main() -> int{
109138
my_integer a {1};
110139
my_integer b {2};
@@ -132,5 +161,7 @@ auto main() -> int{
132161
else {
133162
std::cout << "more\n";
134163
}
164+
165+
mystruct s {};
135166
}
136167

source/cppfront.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,15 +1531,11 @@ class cppfront
15311531
printer.print_cpp2("cpp2::", pos);
15321532
}
15331533

1534-
// 'new' is a named allocator object
1535-
if (n == "new") {
1536-
printer.print_cpp2("cpp2_new", pos);
1537-
}
15381534
// 'this' is not a pointer
1539-
else if (n == "this") {
1535+
if (n == "this") {
15401536
printer.print_cpp2("(*this)", pos);
15411537
}
1542-
// Reclaim the alternative names for users
1538+
// Reclaim the alternative names and some keywords for users
15431539
else if (
15441540
n == "and"
15451541
|| n == "and_eq"
@@ -1552,6 +1548,8 @@ class cppfront
15521548
|| n == "or_eq"
15531549
|| n == "xor"
15541550
|| n == "xor_eq"
1551+
|| n == "new"
1552+
|| n == "struct"
15551553
)
15561554
{
15571555
printer.print_cpp2("cpp2_"+n.to_string(true), pos);

source/lex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ auto lex_line(
942942
"^operator|"
943943
"^private|^protected|^public|"
944944
"^register|^reinterpret_cast|^requires|^return|"
945-
"^short|^signed|^sizeof|^static_assert|^static_cast|^static|^struct|^switch|"
945+
"^short|^signed|^sizeof|^static_assert|^static_cast|^static|^switch|"
946946
"^template|^this|^thread_local|^throws|^throw|^try|^typedef|^typeid|^typename|"
947947
"^unsigned|^using|"
948948
"^virtual|^void|^volatile|"

source/reflect.h

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,50 @@ auto partially_ordered_value(meta::type_declaration& t)
682682
}
683683

684684

685+
//-----------------------------------------------------------------------
686+
//
687+
// "By definition, a `struct` is a `class` in which members
688+
// are by default `public`; that is,
689+
//
690+
// struct s { ...
691+
//
692+
// is simply shorthand for
693+
//
694+
// class s { public: ...
695+
//
696+
// ... Which style you use depends on circumstances and taste.
697+
// I usually prefer to use `struct` for classes that have all
698+
// data `public`."
699+
//
700+
// -- Stroustrup (The C++ Programming Language, 3rd ed., p. 234)
701+
//
702+
//-----------------------------------------------------------------------
703+
//
704+
// struct
705+
//
706+
// a basic_value with only public bases, objects, and functions,
707+
// no virtual functions, and no user-defined constructors
708+
// (i.e., no invariants) or assignment or destructors.
709+
//
710+
auto struct_(meta::type_declaration& t)
711+
-> void
712+
{
713+
for (auto m : t.get_members())
714+
{
715+
m.require( m.make_public(),
716+
"all struct members must be public");
717+
if (m.is_function()) {
718+
auto mf = m.as_function();
719+
t.require( !mf.is_virtual(),
720+
"a struct may not have a virtual function");
721+
t.require( !mf.has_name("operator="),
722+
"a struct may not have a user-defined operator=");
723+
}
724+
}
725+
basic_value(t); // a plain_struct is-a basic_value
726+
}
727+
728+
685729
//-----------------------------------------------------------------------
686730
//
687731
// Now finish the rest of the parser definition
@@ -727,8 +771,11 @@ auto parser::apply_type_meta_functions( declaration_node& n )
727771
else if (meta->to_string() == "partially_ordered_value") {
728772
partially_ordered_value( rtype );
729773
}
774+
else if (meta->to_string() == "struct") {
775+
struct_( rtype );
776+
}
730777
else {
731-
error( "(temporary alpha limitation) unrecognized meta function name '" + meta->to_string() + "' - currently the supported names are: interface, polymorphic_base, ordered, weakly_ordered, partially_ordered, value, weakly_ordered_value, partially_ordered_value" );
778+
error( "(temporary alpha limitation) unrecognized meta function name '" + meta->to_string() + "' - currently the supported names are: interface, polymorphic_base, ordered, weakly_ordered, partially_ordered, value, weakly_ordered_value, partially_ordered_value, struct" );
732779
return false;
733780
}
734781
}

0 commit comments

Comments
 (0)