Skip to content

Commit 8f03ffc

Browse files
committed
Add initial to_string, operator<<, set, and clear for enumerations
1 parent a92fdc8 commit 8f03ffc

13 files changed

+158
-55
lines changed

include/cpp2util.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,8 @@ using in =
553553
//
554554
template<typename T>
555555
class deferred_init {
556-
bool init = false;
557556
alignas(T) std::byte data[sizeof(T)]; // or: std::aligned_storage_t<sizeof(T), alignof(T)> data
557+
bool init = false;
558558

559559
auto t() -> T& { return *std::launder(reinterpret_cast<T*>(&data)); }
560560

@@ -1584,6 +1584,12 @@ class strict_value {
15841584

15851585
auto operator<=>( strict_value const& ) const -> std::strong_ordering = default;
15861586

1587+
auto to_string() const -> std::string { return Tag::to_string(*this); }
1588+
1589+
friend auto operator<<(std::ostream& o, strict_value const& v) -> std::ostream& { return o << v.to_string(); }
1590+
1591+
// Bitwise operations
1592+
15871593
auto operator|=( strict_value const& that ) -> strict_value requires BitwiseOps { t |= that.t; return *this; }
15881594
auto operator&=( strict_value const& that ) -> strict_value requires BitwiseOps { t &= that.t; return *this; }
15891595
auto operator^=( strict_value const& that ) -> strict_value requires BitwiseOps { t ^= that.t; return *this; }
@@ -1592,7 +1598,8 @@ class strict_value {
15921598
auto operator& ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t & that.t); }
15931599
auto operator^ ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t ^ that.t); }
15941600

1595-
auto is_default_value() const -> bool { return t == T{}; }
1601+
auto set ( strict_value const& that ) -> void requires BitwiseOps { t |= that.t; }
1602+
auto clear ( strict_value const& that ) -> void requires BitwiseOps { t &= ~that.t; }
15961603
};
15971604

15981605
template <typename T, typename Tag>

regression-tests/pure2-enum.cpp2

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ main: () = {
2828
// if x == 9 { } // error, can't compare skat_game and integer
2929
// if x == rgb::red { } // error, can't compare skat_game and rgb color
3030

31+
std::cout << "x.to_string() is (x.to_string())$\n";
32+
std::cout << "using << prints " << x << "\n";
33+
3134
std::cout << "with if else: ";
3235
if x == skat_game::diamonds { // ok, can compare two skat_games
3336
std::cout << "diamonds";
@@ -51,7 +54,7 @@ main: () = {
5154
is (skat_game::spades ) = "spades";
5255
is (skat_game::clubs ) = "clubs";
5356
is _ = "not a suit";
54-
} << std::endl;
57+
} << "\n\n";
5558

5659
// x = 9; // error, can't assign skat_game from integer
5760
// x = rgb::red; // error, can't assign skat_game from rgb color
@@ -69,7 +72,8 @@ main: () = {
6972
std::cout << "f is (f2) is (f is (f2))$\n";
7073
std::cout << "f2 is (f ) is (f2 is (f ))$\n\n";
7174

72-
f |= file_attributes::current;
75+
f.clear( f2 );
76+
f.set( file_attributes::current | f2 );
7377
f |= file_attributes::obsolete;
7478
f2 |= file_attributes::current;
7579

@@ -83,6 +87,6 @@ main: () = {
8387
std::cout << "inspecting: " << inspect f -> std::string {
8488
is (file_attributes::current) = "exactly 'current'";
8589
is (cpp2::has_flags(f2)) = "includes all f2's flags ('cached' and 'current')";
86-
is _ = "no match";
90+
is _ = "something else";
8791
} << "\n";
8892
}

regression-tests/test-results/clang-12/pure2-enum.cpp.execution

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
x.to_string() is clubs
2+
using << prints clubs
13
with if else: clubs
24
with inspect: clubs
5+
36
f as int is 1
47
f2 as int is 1
58
f is (f2) is 1

regression-tests/test-results/gcc-10/pure2-bugfix-for-requires-clause-in-forward-declaration.cpp.output

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
pure2-bugfix-for-requires-clause-in-forward-declaration.cpp2:3:36: error: expected ‘;’ at end of member declaration
22
In file included from pure2-bugfix-for-requires-clause-in-forward-declaration.cpp:7:
3-
../../../include/cpp2util.h:1794:47: error: static assertion failed: GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.
4-
1794 | #define CPP2_REQUIRES_(...) static_assert(false, "GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.")
3+
../../../include/cpp2util.h:1801:47: error: static assertion failed: GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.
4+
1801 | #define CPP2_REQUIRES_(...) static_assert(false, "GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.")
55
| ^~~~~
66
pure2-bugfix-for-requires-clause-in-forward-declaration.cpp2:4:1: note: in expansion of macro ‘CPP2_REQUIRES_’
77
pure2-bugfix-for-requires-clause-in-forward-declaration.cpp2:3:46: error: expected ‘;’ at end of member declaration
88
In file included from pure2-bugfix-for-requires-clause-in-forward-declaration.cpp:7:
9-
../../../include/cpp2util.h:1794:47: error: static assertion failed: GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.
10-
1794 | #define CPP2_REQUIRES_(...) static_assert(false, "GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.")
9+
../../../include/cpp2util.h:1801:47: error: static assertion failed: GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.
10+
1801 | #define CPP2_REQUIRES_(...) static_assert(false, "GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.")
1111
| ^~~~~
1212
pure2-bugfix-for-requires-clause-in-forward-declaration.cpp2:4:1: note: in expansion of macro ‘CPP2_REQUIRES_’
1313
pure2-bugfix-for-requires-clause-in-forward-declaration.cpp2:3:3: error: no declaration matches ‘element::element(auto:80&&) requires is_same_v<typename std::remove_cv<typename std::remove_reference<decltype(element::__ct ::n)>::type>::type, std::__cxx11::string>’

regression-tests/test-results/gcc-10/pure2-enum.cpp.execution

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
x.to_string() is clubs
2+
using << prints clubs
13
with if else: clubs
24
with inspect: clubs
5+
36
f as int is 1
47
f2 as int is 1
58
f is (f2) is 1
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-requires-clauses.cpp:7:
2-
../../../include/cpp2util.h:1794:33: error: expected unqualified-id before ‘static_assert’
3-
1794 | #define CPP2_REQUIRES_(...) static_assert(false, "GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.")
2+
../../../include/cpp2util.h:1801:33: error: expected unqualified-id before ‘static_assert’
3+
1801 | #define CPP2_REQUIRES_(...) static_assert(false, "GCC 11 or higher is required to support variables and type-scope functions that have a 'requires' clause. This includes a type-scope 'forward' parameter of non-wildcard type, such as 'func: (this, forward s: std::string)', which relies on being able to add a 'requires' clause - in that case, use 'forward s: _' instead if you need the result to compile with GCC 10.")
44
| ^~~~~~~~~~~~~
55
pure2-requires-clauses.cpp2:19:1: note: in expansion of macro ‘CPP2_REQUIRES_’

regression-tests/test-results/gcc-13/pure2-enum.cpp.execution

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
x.to_string() is clubs
2+
using << prints clubs
13
with if else: clubs
24
with inspect: clubs
5+
36
f as int is 1
47
f2 as int is 1
58
f is (f2) is 1

regression-tests/test-results/msvc-2022/pure2-enum.cpp.execution

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
x.to_string() is clubs
2+
using << prints clubs
13
with if else: clubs
24
with inspect: clubs
5+
36
f as int is 1
47
f2 as int is 1
58
f is (f2) is 1

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

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public: auto static constexpr spades = cpp2::strict_value<cpp2::i8,skat_game,0>(
3030
public: auto static constexpr clubs = cpp2::strict_value<cpp2::i8,skat_game,0>(12);
3131
public: auto static constexpr grand = cpp2::strict_value<cpp2::i8,skat_game,0>(20);
3232
public: auto static constexpr null = cpp2::strict_value<cpp2::i8,skat_game,0>(23);
33+
public: [[nodiscard]] static auto size() -> auto;
34+
public: [[nodiscard]] static auto to_string(cpp2::in<cpp2::strict_value<cpp2::i8,skat_game,0>> value) -> std::string;
3335
public: [[nodiscard]] auto operator<=>([[maybe_unused]] skat_game const& that) const& -> std::strong_ordering = default;
3436
public: skat_game([[maybe_unused]] skat_game const& that);
3537

@@ -50,6 +52,8 @@ class rgb {
5052
public: auto static constexpr red = cpp2::strict_value<cpp2::i8,rgb,0>(0);
5153
public: auto static constexpr green = cpp2::strict_value<cpp2::i8,rgb,0>(1);
5254
public: auto static constexpr blue = cpp2::strict_value<cpp2::i8,rgb,0>(2);
55+
public: [[nodiscard]] static auto size() -> auto;
56+
public: [[nodiscard]] static auto to_string(cpp2::in<cpp2::strict_value<cpp2::i8,rgb,0>> value) -> std::string;
5357
public: [[nodiscard]] auto operator<=>([[maybe_unused]] rgb const& that) const& -> std::strong_ordering = default;
5458
public: rgb([[maybe_unused]] rgb const& that);
5559

@@ -70,6 +74,8 @@ public: auto static constexpr cached = cpp2::strict_value<cpp2::u8,file_attribut
7074
public: auto static constexpr current = cpp2::strict_value<cpp2::u8,file_attributes,1>(2);
7175
public: auto static constexpr obsolete = cpp2::strict_value<cpp2::u8,file_attributes,1>(4);
7276
public: auto static constexpr none = cpp2::strict_value<cpp2::u8,file_attributes,1>(0);
77+
public: [[nodiscard]] static auto size() -> auto;
78+
public: [[nodiscard]] static auto to_string(cpp2::in<cpp2::strict_value<cpp2::u8,file_attributes,1>> value) -> std::string;
7379
public: [[nodiscard]] auto operator<=>([[maybe_unused]] file_attributes const& that) const& -> std::strong_ordering = default;
7480
public: file_attributes([[maybe_unused]] file_attributes const& that);
7581

@@ -92,6 +98,18 @@ auto main() -> int;
9298

9399

94100

101+
#line 1 "pure2-enum.cpp2"
102+
[[nodiscard]] auto skat_game::size() -> auto { return 6; }
103+
[[nodiscard]] auto skat_game::to_string(cpp2::in<cpp2::strict_value<cpp2::i8,skat_game,0>> value) -> std::string{
104+
if (value == diamonds) {return "diamonds"; }
105+
if (value == hearts) {return "hearts"; }
106+
if (value == spades) {return "spades"; }
107+
if (value == clubs) {return "clubs"; }
108+
if (value == grand) {return "grand"; }
109+
if (value == null) {return "null"; }
110+
return "(invalid skat_game enumerator value)";
111+
}
112+
95113
#line 1 "pure2-enum.cpp2"
96114
skat_game::skat_game([[maybe_unused]] skat_game const& that){}
97115
auto skat_game::operator=([[maybe_unused]] skat_game const& that) -> skat_game& {
@@ -100,14 +118,31 @@ skat_game::skat_game([[maybe_unused]] skat_game&& that) noexcept{}
100118
auto skat_game::operator=([[maybe_unused]] skat_game&& that) noexcept -> skat_game& {
101119
return *this;}
102120
skat_game::skat_game(){}
103-
rgb::rgb([[maybe_unused]] rgb const& that){}
121+
[[nodiscard]] auto rgb::size() -> auto { return 3; }
122+
[[nodiscard]] auto rgb::to_string(cpp2::in<cpp2::strict_value<cpp2::i8,rgb,0>> value) -> std::string{
123+
if (value == red) {return "red"; }
124+
if (value == green) {return "green"; }
125+
if (value == blue) {return "blue"; }
126+
return "(invalid rgb enumerator value)";
127+
}
128+
129+
rgb::rgb([[maybe_unused]] rgb const& that){}
104130
auto rgb::operator=([[maybe_unused]] rgb const& that) -> rgb& {
105131
return *this;}
106132
rgb::rgb([[maybe_unused]] rgb&& that) noexcept{}
107133
auto rgb::operator=([[maybe_unused]] rgb&& that) noexcept -> rgb& {
108134
return *this;}
109135
rgb::rgb(){}
110-
file_attributes::file_attributes([[maybe_unused]] file_attributes const& that){}
136+
[[nodiscard]] auto file_attributes::size() -> auto { return 4; }
137+
[[nodiscard]] auto file_attributes::to_string(cpp2::in<cpp2::strict_value<cpp2::u8,file_attributes,1>> value) -> std::string{
138+
if (value == cached) {return "cached"; }
139+
if (value == current) {return "current"; }
140+
if (value == obsolete) {return "obsolete"; }
141+
if (value == none) {return "none"; }
142+
return "(invalid file_attributes enumerator value)";
143+
}
144+
145+
file_attributes::file_attributes([[maybe_unused]] file_attributes const& that){}
111146
auto file_attributes::operator=([[maybe_unused]] file_attributes const& that) -> file_attributes& {
112147
return *this;}
113148
file_attributes::file_attributes([[maybe_unused]] file_attributes&& that) noexcept{}
@@ -123,6 +158,9 @@ auto main() -> int{
123158
// if x == 9 { } // error, can't compare skat_game and integer
124159
// if x == rgb::red { } // error, can't compare skat_game and rgb color
125160

161+
std::cout << "x.to_string() is " + cpp2::to_string(CPP2_UFCS_0(to_string, x)) + "\n";
162+
std::cout << "using << prints " << x << "\n";
163+
126164
std::cout << "with if else: ";
127165
if (x == skat_game::diamonds) { // ok, can compare two skat_games
128166
std::cout << "diamonds";
@@ -146,7 +184,7 @@ auto main() -> int{
146184
else if (cpp2::is(__expr, skat_game::spades)) { if constexpr( requires{"spades";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("spades")),std::string> ) return "spades"; else return std::string{}; else return std::string{}; }
147185
else if (cpp2::is(__expr, skat_game::clubs)) { if constexpr( requires{"clubs";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("clubs")),std::string> ) return "clubs"; else return std::string{}; else return std::string{}; }
148186
else return "not a suit"; }
149-
() << std::endl;
187+
() << "\n\n";
150188

151189
// x = 9; // error, can't assign skat_game from integer
152190
// x = rgb::red; // error, can't assign skat_game from rgb color
@@ -164,7 +202,8 @@ auto main() -> int{
164202
std::cout << "f is (f2) is " + cpp2::to_string(cpp2::is(f, (f2))) + "\n";
165203
std::cout << "f2 is (f ) is " + cpp2::to_string(cpp2::is(f2, (f))) + "\n\n";
166204

167-
f |= file_attributes::current;
205+
CPP2_UFCS(clear, f, f2);
206+
CPP2_UFCS(set, f, file_attributes::current | f2);
168207
f |= file_attributes::obsolete;
169208
f2 |= file_attributes::current;
170209

@@ -178,7 +217,7 @@ auto main() -> int{
178217
std::cout << "inspecting: " << [&] () -> std::string { auto&& __expr = std::move(f);
179218
if (cpp2::is(__expr, (file_attributes::current))) { if constexpr( requires{"exactly 'current'";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("exactly 'current'")),std::string> ) return "exactly 'current'"; else return std::string{}; else return std::string{}; }
180219
else if (cpp2::is(__expr, cpp2::has_flags(std::move(f2)))) { if constexpr( requires{"includes all f2's flags ('cached' and 'current')";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("includes all f2's flags ('cached' and 'current')")),std::string> ) return "includes all f2's flags ('cached' and 'current')"; else return std::string{}; else return std::string{}; }
181-
else return "no match"; }
220+
else return "something else"; }
182221
() << "\n";
183222
}
184223

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 8905:1016
2+
cppfront compiler v0.2.1 Build 8906:1741
33
Copyright(c) Herb Sutter All rights reserved
44

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

0 commit comments

Comments
 (0)