Skip to content

Commit fe13207

Browse files
committed
Add the member's name as a String literal parameter to store_as_base, closes #334
Disambiguates two such members having the same type Move the existing `String` wrapper into `cpp2util.h` where it can be used outside the compiler too, in this case by `store_as_base`
1 parent 0982b8e commit fe13207

File tree

8 files changed

+80
-48
lines changed

8 files changed

+80
-48
lines changed

include/cpp2util.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,27 @@ using __schar = signed char; // normally use i8 instead
269269
using __uchar = unsigned char; // normally use u8 instead
270270

271271

272+
//-----------------------------------------------------------------------
273+
//
274+
// String: A helper workaround for passing a string literal as a
275+
// template argument
276+
//
277+
//-----------------------------------------------------------------------
278+
//
279+
template<size_t N>
280+
struct String
281+
{
282+
constexpr String(const char (&str)[N])
283+
{
284+
std::copy_n(str, N, value);
285+
}
286+
287+
auto operator<=>(String const&) const = default;
288+
289+
char value[N] = {};
290+
};
291+
292+
272293
//-----------------------------------------------------------------------
273294
//
274295
// contract_group
@@ -619,7 +640,7 @@ class out {
619640
};
620641

621642

622-
template<typename T>
643+
template<String Name, typename T>
623644
struct store_as_base : private T
624645
{
625646
store_as_base( T const& t ) : T{t} { }

regression-tests/pure2-types-inheritance.cpp2

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ N: namespace = {
1212
}
1313

1414
Cyborg: type = {
15-
name: std::string;
16-
this: Human = ();
17-
this: N::Machine;
15+
name: std::string;
16+
this: Human = ();
17+
address: std::string = "123 Main St.";
18+
this: N::Machine;
1819

1920
operator=: (out this, n: std::string) = {
2021
name = n;
@@ -28,6 +29,9 @@ Cyborg: type = {
2829
work: (override this) =
2930
std::cout << "(name)$ carries some half-tonne crates of Fe2O3 to cold storage\n";
3031

32+
print: (this) =
33+
std::cout << "printing: (name)$ lives at (address)$\n";
34+
3135
operator=: (move this) =
3236
std::cout << "Tired but satisfied after another successful day, (name)$ checks out and goes home to their family\n";
3337
}
@@ -44,6 +48,7 @@ do_work: ( m: N::Machine ) = {
4448

4549
main: () = {
4650
c: Cyborg = "Parsnip";
51+
c.print();
4752
c.make_speak();
4853
c.do_work();
4954
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Parsnip checks in for the day's shift
2+
printing: Parsnip lives at 123 Main St.
23
-> [vcall: make_speak] Parsnip cracks a few jokes with a coworker
34
-> [vcall: do_work] Parsnip carries some half-tonne crates of Fe2O3 to cold storage
45
Tired but satisfied after another successful day, Parsnip checks out and goes home to their family
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Parsnip checks in for the day's shift
2+
printing: Parsnip lives at 123 Main St.
23
-> [vcall: make_speak] Parsnip cracks a few jokes with a coworker
34
-> [vcall: do_work] Parsnip carries some half-tonne crates of Fe2O3 to cold storage
45
Tired but satisfied after another successful day, Parsnip checks out and goes home to their family
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Parsnip checks in for the day's shift
2+
printing: Parsnip lives at 123 Main St.
23
-> [vcall: make_speak] Parsnip cracks a few jokes with a coworker
34
-> [vcall: do_work] Parsnip carries some half-tonne crates of Fe2O3 to cold storage
45
Tired but satisfied after another successful day, Parsnip checks out and goes home to their family

regression-tests/test-results/pure2-types-inheritance.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,31 @@ namespace N {
3535
};
3636
}
3737

38-
class Cyborg: private cpp2::store_as_base<std::string>, public Human, public N::Machine {
38+
class Cyborg: private cpp2::store_as_base<"name",std::string>, public Human, private cpp2::store_as_base<"address",std::string>, public N::Machine {
3939

40-
#line 19 "pure2-types-inheritance.cpp2"
40+
#line 20 "pure2-types-inheritance.cpp2"
4141
public: explicit Cyborg(cpp2::in<std::string> n);
4242

43-
#line 25 "pure2-types-inheritance.cpp2"
43+
#line 26 "pure2-types-inheritance.cpp2"
4444
public: auto speak() const -> void override;
4545

46-
#line 28 "pure2-types-inheritance.cpp2"
46+
#line 29 "pure2-types-inheritance.cpp2"
4747
public: auto work() const -> void override;
4848

49-
#line 31 "pure2-types-inheritance.cpp2"
49+
#line 32 "pure2-types-inheritance.cpp2"
50+
public: auto print() const -> void;
51+
52+
#line 35 "pure2-types-inheritance.cpp2"
5053
public: ~Cyborg();
5154

5255
};
5356

5457
auto make_speak(cpp2::in<Human> h) -> void;
5558

56-
#line 40 "pure2-types-inheritance.cpp2"
59+
#line 44 "pure2-types-inheritance.cpp2"
5760
auto do_work(cpp2::in<N::Machine> m) -> void;
5861

59-
#line 45 "pure2-types-inheritance.cpp2"
62+
#line 49 "pure2-types-inheritance.cpp2"
6063
auto main() -> int;
6164

6265
//=== Cpp2 function definitions =================================================
@@ -74,28 +77,32 @@ namespace N {
7477

7578
}
7679

77-
#line 19 "pure2-types-inheritance.cpp2"
80+
#line 20 "pure2-types-inheritance.cpp2"
7881
Cyborg::Cyborg(cpp2::in<std::string> n)
79-
: cpp2::store_as_base<std::string>{ n }
82+
: cpp2::store_as_base<"name",std::string>{ n }
8083
, Human{ }
84+
, cpp2::store_as_base<"address",std::string>{ "123 Main St." }
8185
, N::Machine{ "Acme Corp. engineer tech" }
82-
#line 19 "pure2-types-inheritance.cpp2"
86+
#line 20 "pure2-types-inheritance.cpp2"
8387
{
8488

85-
#line 22 "pure2-types-inheritance.cpp2"
86-
std::cout << cpp2::to_string(cpp2::store_as_base<std::string>::value__()) + " checks in for the day's shift\n";
89+
#line 23 "pure2-types-inheritance.cpp2"
90+
std::cout << cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " checks in for the day's shift\n";
8791
}
8892

8993
auto Cyborg::speak() const -> void {
90-
std::cout << cpp2::to_string(cpp2::store_as_base<std::string>::value__()) + " cracks a few jokes with a coworker\n"; }
94+
std::cout << cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " cracks a few jokes with a coworker\n"; }
9195

9296
auto Cyborg::work() const -> void {
93-
std::cout << cpp2::to_string(cpp2::store_as_base<std::string>::value__()) + " carries some half-tonne crates of Fe2O3 to cold storage\n"; }
97+
std::cout << cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " carries some half-tonne crates of Fe2O3 to cold storage\n"; }
98+
99+
auto Cyborg::print() const -> void {
100+
std::cout << "printing: " + cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " lives at " + cpp2::to_string(cpp2::store_as_base<"address",std::string>::value__()) + "\n"; }
94101

95102
Cyborg::~Cyborg() {
96-
std::cout << "Tired but satisfied after another successful day, " + cpp2::to_string(cpp2::store_as_base<std::string>::value__()) + " checks out and goes home to their family\n"; }
103+
std::cout << "Tired but satisfied after another successful day, " + cpp2::to_string(cpp2::store_as_base<"name",std::string>::value__()) + " checks out and goes home to their family\n"; }
97104

98-
#line 35 "pure2-types-inheritance.cpp2"
105+
#line 39 "pure2-types-inheritance.cpp2"
99106
auto make_speak(cpp2::in<Human> h) -> void{
100107
std::cout << "-> [vcall: make_speak] ";
101108
CPP2_UFCS_0(speak, h);
@@ -108,6 +115,7 @@ auto do_work(cpp2::in<N::Machine> m) -> void{
108115

109116
auto main() -> int{
110117
Cyborg c {"Parsnip"};
118+
CPP2_UFCS_0(print, c);
111119
CPP2_UFCS_0(make_speak, c);
112120
CPP2_UFCS_0(do_work, std::move(c));
113121
}

source/common.h

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ auto starts_with_identifier(std::string_view s)
380380
return 0;
381381
};
382382

383+
383384
// Helper to allow one of the above or a digit separator
384385
// Example: is_separator_or( is_binary_digit (c) )
385386
//
@@ -393,27 +394,6 @@ auto is_separator_or(auto pred, char c)
393394
}
394395

395396

396-
//-----------------------------------------------------------------------
397-
//
398-
// String: A helper workaround for passing a string literal as a
399-
// template argument
400-
//
401-
//-----------------------------------------------------------------------
402-
//
403-
template<size_t N>
404-
struct String
405-
{
406-
constexpr String(const char (&str)[N])
407-
{
408-
std::copy_n(str, N, value);
409-
}
410-
411-
auto operator<=>(String const&) const = default;
412-
413-
char value[N] = {};
414-
};
415-
416-
417397
// Bool to string
418398
//
419399
template<typename T>
@@ -426,6 +406,7 @@ auto __as(bool b)
426406

427407

428408
// Explicit cast
409+
//
429410
template<typename T>
430411
auto __as(auto x)
431412
-> T

source/cppfront.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,8 @@ class cppfront
14611461
assert(decl && decl->is_object());
14621462
auto type = decl->get_object_type();
14631463
assert(type);
1464-
printer.print_cpp2("cpp2::store_as_base<", pos);
1464+
assert(decl->name());
1465+
printer.print_cpp2("cpp2::store_as_base<\"" + decl->name()->to_string(true) + "\",", pos);
14651466
emit(*type);
14661467
printer.print_cpp2(">::value__()", pos);
14671468
}
@@ -4355,9 +4356,12 @@ class cppfront
43554356
// (a) ... if this is assignment, emit it in all cases
43564357
if (is_assignment)
43574358
{
4359+
assert ((*object)->name());
43584360
if (is_object_before_base) {
43594361
object_name =
4360-
"cpp2::store_as_base<"
4362+
"cpp2::store_as_base<\""
4363+
+ (*object)->name()->to_string(true)
4364+
+ "\","
43614365
+ print_to_string(*(*object)->get_object_type())
43624366
+ ">::value__()";
43634367
}
@@ -4403,7 +4407,9 @@ class cppfront
44034407
{
44044408
if (is_object_before_base) {
44054409
object_name =
4406-
"cpp2::store_as_base<"
4410+
"cpp2::store_as_base<\""
4411+
+ (*object)->name()->to_string(true)
4412+
+ "\","
44074413
+ print_to_string(*(*object)->get_object_type())
44084414
+ ">";
44094415
}
@@ -4469,7 +4475,9 @@ class cppfront
44694475

44704476
if (is_object_before_base) {
44714477
object_name =
4472-
"cpp2::store_as_base<"
4478+
"cpp2::store_as_base<\""
4479+
+ (*object)->name()->to_string(true)
4480+
+ "\","
44734481
+ print_to_string(*(*object)->get_object_type())
44744482
+ ">::value__()";
44754483
}
@@ -4485,7 +4493,9 @@ class cppfront
44854493
if (is_object_before_base)
44864494
{
44874495
object_name =
4488-
"cpp2::store_as_base<"
4496+
"cpp2::store_as_base<\""
4497+
+ (*object)->name()->to_string(true)
4498+
+ "\","
44894499
+ print_to_string(*(*object)->get_object_type())
44904500
+ ">::value__()";
44914501
}
@@ -4501,7 +4511,9 @@ class cppfront
45014511
else if (is_object_before_base)
45024512
{
45034513
object_name =
4504-
"cpp2::store_as_base<"
4514+
"cpp2::store_as_base<\""
4515+
+ (*object)->name()->to_string(true)
4516+
+ "\","
45054517
+ print_to_string(*(*object)->get_object_type())
45064518
+ ">";
45074519

@@ -4858,7 +4870,9 @@ class cppfront
48584870
else {
48594871
if (printer.get_phase() == printer.phase1_type_defs_func_decls) {
48604872
printer.print_cpp2(
4861-
separator + " private cpp2::store_as_base<"
4873+
separator + " private cpp2::store_as_base<\""
4874+
+ decl->name()->to_string(true)
4875+
+ "\","
48624876
+ print_to_string(*decl->get_object_type()) + ">",
48634877
compound_stmt->position()
48644878
);

0 commit comments

Comments
 (0)