Skip to content

Commit d43a1f6

Browse files
committed
Allow flag enumerators with multiple flags set (aka groups)
1 parent 9907337 commit d43a1f6

File tree

10 files changed

+26
-28
lines changed

10 files changed

+26
-28
lines changed

regression-tests/pure2-enum.cpp2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ file_attributes: @flag_enum type = {
1818
cached; // 1
1919
current; // 2
2020
obsolete; // 4
21+
cached_and_current := 3;
2122
}
2223

2324
main: () = {
@@ -61,7 +62,7 @@ main: () = {
6162

6263
x = skat_game::diamonds; // ok, can assign one skat_game from another
6364

64-
f := file_attributes::current | file_attributes::cached;
65+
f := file_attributes::cached_and_current;
6566
f &= file_attributes::cached | file_attributes::obsolete;
6667

6768
f2 := file_attributes::cached;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ f2 as int is 1
88
f is (f2) is 1
99
f2 is (f ) is 1
1010

11-
f is (cached, current, obsolete)
12-
f2 is (cached, current)
11+
f is (cached, current, obsolete, cached_and_current)
12+
f2 is (cached, current, cached_and_current)
1313
f as int is 7
1414
f2 as int is 3
1515
f == f2 is 0

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ f2 as int is 1
88
f is (f2) is 1
99
f2 is (f ) is 1
1010

11-
f is (cached, current, obsolete)
12-
f2 is (cached, current)
11+
f is (cached, current, obsolete, cached_and_current)
12+
f2 is (cached, current, cached_and_current)
1313
f as int is 7
1414
f2 as int is 3
1515
f == f2 is 0

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ f2 as int is 1
88
f is (f2) is 1
99
f2 is (f ) is 1
1010

11-
f is (cached, current, obsolete)
12-
f2 is (cached, current)
11+
f is (cached, current, obsolete, cached_and_current)
12+
f2 is (cached, current, cached_and_current)
1313
f as int is 7
1414
f2 as int is 3
1515
f == f2 is 0

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ f2 as int is 1
88
f is (f2) is 1
99
f2 is (f ) is 1
1010

11-
f is (cached, current, obsolete)
12-
f2 is (cached, current)
11+
f is (cached, current, obsolete, cached_and_current)
12+
f2 is (cached, current, cached_and_current)
1313
f as int is 7
1414
f2 as int is 3
1515
f == f2 is 0

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class file_attributes {
7373
public: auto static constexpr cached = cpp2::strict_value<cpp2::u8,file_attributes,1>(1);
7474
public: auto static constexpr current = cpp2::strict_value<cpp2::u8,file_attributes,1>(2);
7575
public: auto static constexpr obsolete = cpp2::strict_value<cpp2::u8,file_attributes,1>(4);
76+
public: auto static constexpr cached_and_current = cpp2::strict_value<cpp2::u8,file_attributes,1>(3);
7677
public: auto static constexpr none = cpp2::strict_value<cpp2::u8,file_attributes,1>(0);
7778
public: [[nodiscard]] static auto size() -> auto;
7879
public: [[nodiscard]] static auto to_string(cpp2::in<cpp2::strict_value<cpp2::u8,file_attributes,1>> value) -> std::string;
@@ -88,7 +89,8 @@ public: explicit file_attributes();
8889
// 1
8990
// 2
9091
// 4
91-
#line 21 "pure2-enum.cpp2"
92+
93+
#line 22 "pure2-enum.cpp2"
9294
};
9395

9496
auto main() -> int;
@@ -142,14 +144,15 @@ rgb::rgb([[maybe_unused]] rgb&& that) noexcept{}
142144
auto rgb::operator=([[maybe_unused]] rgb&& that) noexcept -> rgb& {
143145
return *this;}
144146
rgb::rgb(){}
145-
[[nodiscard]] auto file_attributes::size() -> auto { return 4; }
147+
[[nodiscard]] auto file_attributes::size() -> auto { return 5; }
146148
[[nodiscard]] auto file_attributes::to_string(cpp2::in<cpp2::strict_value<cpp2::u8,file_attributes,1>> value) -> std::string{
147149

148150
std::string ret {};
149151
ret = "(";
150152
if (CPP2_UFCS(has, value, cached)) {ret += "cached";}
151153
if (CPP2_UFCS(has, value, current)) {ret += std::string(", ") + "current";}
152154
if (CPP2_UFCS(has, value, obsolete)) {ret += std::string(", ") + "obsolete";}
155+
if (CPP2_UFCS(has, value, cached_and_current)) {ret += std::string(", ") + "cached_and_current";}
153156
if (CPP2_UFCS(has, value, none)) {ret += std::string(", ") + "none";}
154157
if (CPP2_UFCS_0(empty, ret)) {ret = "(invalid file_attributes enumerator value)";}
155158
return ret + ")";
@@ -162,7 +165,7 @@ file_attributes::file_attributes([[maybe_unused]] file_attributes&& that) noexce
162165
auto file_attributes::operator=([[maybe_unused]] file_attributes&& that) noexcept -> file_attributes& {
163166
return *this;}
164167
file_attributes::file_attributes(){}
165-
#line 23 "pure2-enum.cpp2"
168+
#line 24 "pure2-enum.cpp2"
166169
auto main() -> int{
167170
// x : skat_game = 9; // error, can't construct skat_game from integer
168171

@@ -204,7 +207,7 @@ auto main() -> int{
204207

205208
x = skat_game::diamonds; // ok, can assign one skat_game from another
206209

207-
auto f {file_attributes::current | file_attributes::cached};
210+
auto f {file_attributes::cached_and_current};
208211
f &= file_attributes::cached | file_attributes::obsolete;
209212

210213
auto f2 {file_attributes::cached};

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 8909:1522
2+
cppfront compiler v0.2.1 Build 8909:1547
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-
"8909:1522"
1+
"8909:1547"

source/reflect.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class alias_declaration;
3838
#line 807 "reflect.h2"
3939
class enumerator_info;
4040

41-
#line 1017 "reflect.h2"
41+
#line 1014 "reflect.h2"
4242
}
4343
}
4444

@@ -630,8 +630,8 @@ struct basic_enum__ret { std::string underlying_type; std::string strict_underly
630630
//-----------------------------------------------------------------------
631631
//
632632
// "An enum[...] is a totally ordered value type that stores a
633-
// value of its enumerators’s type, and otherwise has only public
634-
// member variables of its enumerators’s type, all of which are
633+
// value of its enumerators's type, and otherwise has only public
634+
// member variables of its enumerator's type, all of which are
635635
// naturally scoped because they are members of a type."
636636
//
637637
// -- P0707R4, section 3
@@ -642,7 +642,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void;
642642
//-----------------------------------------------------------------------
643643
//
644644
// "flag_enum expresses an enumeration that stores values
645-
// corresponding to bitwise-or’d enumerators. The enumerators must
645+
// corresponding to bitwise-or'd enumerators. The enumerators must
646646
// be powers of two, and are automatically generated [...] A none
647647
// value is provided [...] Operators | and & are provided to
648648
// combine and extract values."
@@ -651,7 +651,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void;
651651
//
652652
auto flag_enum(meta::type_declaration& t) -> void;
653653

654-
#line 1015 "reflect.h2"
654+
#line 1012 "reflect.h2"
655655
//=======================================================================
656656
// Switch to Cpp1 and close subnamespace meta
657657
}
@@ -1492,12 +1492,9 @@ auto flag_enum(meta::type_declaration& t) -> void
14921492

14931493
// Let basic_enum do its thing, with a power-of-two value generator
14941494
static_cast<void>(CPP2_UFCS(basic_enum, t,
1495-
[_0 = t](cpp2::i64& value, cpp2::in<std::string> specified_value) -> void{
1495+
[](cpp2::i64& value, cpp2::in<std::string> specified_value) -> void{
14961496
if (!(CPP2_UFCS_0(empty, specified_value))) {
14971497
value = std::strtoll(&cpp2::assert_in_bounds(specified_value, 0), nullptr, 10);
1498-
if ((value & (value - 1)) != 0) {
1499-
CPP2_UFCS(error, _0, "a flag_enum value must be a power of two");
1500-
}
15011498
}else {
15021499
if (cpp2::cmp_less(value,1)) {
15031500
value = 1;
@@ -1511,7 +1508,7 @@ auto flag_enum(meta::type_declaration& t) -> void
15111508
));
15121509
}
15131510

1514-
#line 1017 "reflect.h2"
1511+
#line 1014 "reflect.h2"
15151512
}
15161513
}
15171514

source/reflect.h2

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -995,9 +995,6 @@ flag_enum: (inout t: meta::type_declaration) =
995995
:(inout value: i64, specified_value: std::string) = {
996996
if !specified_value.empty() {
997997
value = std::strtoll(specified_value[0]&, nullptr, 10);
998-
if (value & (value - 1)) != 0 {
999-
t$.error( "a flag_enum value must be a power of two" );
1000-
}
1001998
} else {
1002999
if value < 1 {
10031000
value = 1;

0 commit comments

Comments
 (0)