Skip to content

Commit 083c8a0

Browse files
committed
Add default ctor and copying/moving to union, closes #770
1 parent f41e325 commit 083c8a0

File tree

3 files changed

+124
-14
lines changed

3 files changed

+124
-14
lines changed

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

+80-7
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ public: auto set_num(cpp2::in<cpp2::i32> _value) & -> void;
3232
public: auto set_num(auto&& ..._args) & -> void;
3333
private: auto _destroy() & -> void;
3434
public: ~name_or_number() noexcept;
35+
public: explicit name_or_number();
36+
public: name_or_number(name_or_number const& that);
3537

36-
public: name_or_number() = default;
37-
public: name_or_number(name_or_number const&) = delete; /* No 'that' constructor, suppress copy */
38-
public: auto operator=(name_or_number const&) -> void = delete;
39-
38+
public: auto operator=(name_or_number const& that) -> name_or_number& ;
39+
public: name_or_number(name_or_number&& that) noexcept;
40+
public: auto operator=(name_or_number&& that) noexcept -> name_or_number& ;
4041

4142
#line 5 "pure2-union.cpp2"
4243
};
@@ -59,10 +60,12 @@ public: auto set_other(cpp2::in<T> _value) & -> void;
5960
public: auto set_other(auto&& ..._args) & -> void;
6061
private: auto _destroy() & -> void;
6162
public: ~name_or_other() noexcept;
63+
public: explicit name_or_other();
64+
public: name_or_other(name_or_other const& that);
65+
public: auto operator=(name_or_other const& that) -> name_or_other& ;
66+
public: name_or_other(name_or_other&& that) noexcept;
67+
public: auto operator=(name_or_other&& that) noexcept -> name_or_other& ;
6268

63-
public: name_or_other() = default;
64-
public: name_or_other(name_or_other const&) = delete; /* No 'that' constructor, suppress copy */
65-
public: auto operator=(name_or_other const&) -> void = delete;
6669
#line 17 "pure2-union.cpp2"
6770
};
6871

@@ -98,6 +101,41 @@ auto name_or_number::_destroy() & -> void{
98101
}
99102

100103
name_or_number::~name_or_number() noexcept{_destroy();}
104+
name_or_number::name_or_number()
105+
: _discriminator{ -1 }{}
106+
name_or_number::name_or_number(name_or_number const& that)
107+
: _storage{ that._storage }
108+
, _discriminator{ that._discriminator }{
109+
if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));}
110+
if (CPP2_UFCS_0(is_num, that)) {set_num(CPP2_UFCS_0(num, that));}
111+
_discriminator = that._discriminator;
112+
}
113+
114+
auto name_or_number::operator=(name_or_number const& that) -> name_or_number& {
115+
_storage = that._storage;
116+
_discriminator = that._discriminator;
117+
if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));}
118+
if (CPP2_UFCS_0(is_num, that)) {set_num(CPP2_UFCS_0(num, that));}
119+
_discriminator = that._discriminator;
120+
return *this;
121+
}
122+
123+
name_or_number::name_or_number(name_or_number&& that) noexcept
124+
: _storage{ std::move(that)._storage }
125+
, _discriminator{ std::move(that)._discriminator }{
126+
if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));}
127+
if (CPP2_UFCS_0(is_num, std::move(that))) {set_num(CPP2_UFCS_0(num, std::move(that)));}
128+
_discriminator = std::move(that)._discriminator;
129+
}
130+
131+
auto name_or_number::operator=(name_or_number&& that) noexcept -> name_or_number& {
132+
_storage = std::move(that)._storage;
133+
_discriminator = std::move(that)._discriminator;
134+
if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));}
135+
if (CPP2_UFCS_0(is_num, std::move(that))) {set_num(CPP2_UFCS_0(num, std::move(that)));}
136+
_discriminator = std::move(that)._discriminator;
137+
return *this;
138+
}
101139
#line 12 "pure2-union.cpp2"
102140
template <typename T> [[nodiscard]] auto name_or_other<T>::to_string() const& -> std::string{
103141
if (is_name()) { return name(); }
@@ -128,7 +166,42 @@ template <typename T> auto name_or_other<T>::_destroy() & -> void{
128166
}
129167

130168
template <typename T> name_or_other<T>::~name_or_other() noexcept{_destroy();}
169+
template <typename T> name_or_other<T>::name_or_other()
170+
: _discriminator{ -1 }{}
171+
template <typename T> name_or_other<T>::name_or_other(name_or_other const& that)
172+
: _storage{ that._storage }
173+
, _discriminator{ that._discriminator }{
174+
if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));}
175+
if (CPP2_UFCS_0(is_other, that)) {set_other(CPP2_UFCS_0(other, that));}
176+
_discriminator = that._discriminator;
177+
}
178+
179+
180+
template <typename T> auto name_or_other<T>::operator=(name_or_other const& that) -> name_or_other& {
181+
_storage = that._storage;
182+
_discriminator = that._discriminator;
183+
if (CPP2_UFCS_0(is_name, that)) {set_name(CPP2_UFCS_0(name, that));}
184+
if (CPP2_UFCS_0(is_other, that)) {set_other(CPP2_UFCS_0(other, that));}
185+
_discriminator = that._discriminator;
186+
return *this;
187+
}
131188

189+
template <typename T> name_or_other<T>::name_or_other(name_or_other&& that) noexcept
190+
: _storage{ std::move(that)._storage }
191+
, _discriminator{ std::move(that)._discriminator }{
192+
if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));}
193+
if (CPP2_UFCS_0(is_other, std::move(that))) {set_other(CPP2_UFCS_0(other, std::move(that)));}
194+
_discriminator = std::move(that)._discriminator;
195+
}
196+
197+
template <typename T> auto name_or_other<T>::operator=(name_or_other&& that) noexcept -> name_or_other& {
198+
_storage = std::move(that)._storage;
199+
_discriminator = std::move(that)._discriminator;
200+
if (CPP2_UFCS_0(is_name, std::move(that))) {set_name(CPP2_UFCS_0(name, std::move(that)));}
201+
if (CPP2_UFCS_0(is_other, std::move(that))) {set_other(CPP2_UFCS_0(other, std::move(that)));}
202+
_discriminator = std::move(that)._discriminator;
203+
return *this;
204+
}
132205
#line 19 "pure2-union.cpp2"
133206
auto print_name(cpp2::in<name_or_number> non) -> void{
134207
if (CPP2_UFCS_0(is_name, non)) {

source/reflect.h

+28-7
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class alias_declaration;
3838
#line 841 "reflect.h2"
3939
class value_member_info;
4040

41-
#line 1311 "reflect.h2"
41+
#line 1327 "reflect.h2"
4242
}
4343

4444
}
@@ -699,14 +699,14 @@ auto flag_enum(meta::type_declaration& t) -> void;
699699

700700
auto cpp2_union(meta::type_declaration& t) -> void;
701701

702-
#line 1197 "reflect.h2"
702+
#line 1213 "reflect.h2"
703703
//-----------------------------------------------------------------------
704704
//
705705
// print - output a pretty-printed visualization of t
706706
//
707707
auto print(cpp2::in<meta::type_declaration> t) -> void;
708708

709-
#line 1207 "reflect.h2"
709+
#line 1223 "reflect.h2"
710710
//-----------------------------------------------------------------------
711711
//
712712
// apply_metafunctions
@@ -717,7 +717,7 @@ auto print(cpp2::in<meta::type_declaration> t) -> void;
717717
auto const& error
718718
) -> bool;
719719

720-
#line 1311 "reflect.h2"
720+
#line 1327 "reflect.h2"
721721
}
722722

723723
}
@@ -1681,15 +1681,36 @@ std::string destroy = " private _destroy: (inout this) = {\n";
16811681
// Add the destructor
16821682
#line 1193 "reflect.h2"
16831683
CPP2_UFCS(add_member, t, " operator=: (move this) = { _destroy(); } ");
1684+
1685+
// Add default constructor
1686+
CPP2_UFCS(add_member, t, " operator=: (out this) = { _discriminator = -1; } ");
1687+
{
1688+
std::string value_set = " operator=: (out this, that) = {\n";
1689+
1690+
// Add value-set
1691+
1692+
#line 1200 "reflect.h2"
1693+
{
1694+
for (
1695+
auto const& a : alternatives ) {
1696+
value_set += " if that.is_" + cpp2::to_string(a.name) + "() { set_" + cpp2::to_string(a.name) + "( that." + cpp2::to_string(a.name) + "() ); }\n";
1697+
}
1698+
1699+
value_set += " _discriminator = that._discriminator;\n";
1700+
value_set += " }\n";
1701+
CPP2_UFCS(add_member, t, std::move(value_set));
1702+
}
1703+
}
1704+
#line 1210 "reflect.h2"
16841705
}
16851706

1686-
#line 1201 "reflect.h2"
1707+
#line 1217 "reflect.h2"
16871708
auto print(cpp2::in<meta::type_declaration> t) -> void
16881709
{
16891710
std::cout << CPP2_UFCS_0(print, t) << "\n";
16901711
}
16911712

1692-
#line 1211 "reflect.h2"
1713+
#line 1227 "reflect.h2"
16931714
[[nodiscard]] auto apply_metafunctions(
16941715
declaration_node& n,
16951716
type_declaration& rtype,
@@ -1789,7 +1810,7 @@ auto print(cpp2::in<meta::type_declaration> t) -> void
17891810
return true;
17901811
}
17911812

1792-
#line 1311 "reflect.h2"
1813+
#line 1327 "reflect.h2"
17931814
}
17941815

17951816
}

source/reflect.h2

+16
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,22 @@ union: (inout t : meta::type_declaration)
11911191

11921192
// Add the destructor
11931193
t.add_member( " operator=: (move this) = { _destroy(); } " );
1194+
1195+
// Add default constructor
1196+
t.add_member( " operator=: (out this) = { _discriminator = -1; } " );
1197+
1198+
// Add value-set
1199+
(copy value_set: std::string = " operator=: (out this, that) = {\n")
1200+
{
1201+
for alternatives
1202+
do (a) {
1203+
value_set += " if that.is_(a.name)$() { set_(a.name)$( that.(a.name)$() ); }\n";
1204+
}
1205+
1206+
value_set += " _discriminator = that._discriminator;\n";
1207+
value_set += " }\n";
1208+
t.add_member( value_set );
1209+
}
11941210
}
11951211

11961212

0 commit comments

Comments
 (0)