Skip to content

Commit ec48efc

Browse files
committed
Allow arbitrary expressions as enumerator initializers
Example: `cached_and_current := cached | current;` However, because we're not actually evaluating expressions: - They are required to be last - Using them requires specifying the underlying type (note this is desirable in general, because arbitrary expressions could change value over time and we wouldn't want the size of the type to depend on possibly-distant changes that change those values)
1 parent b1c03f2 commit ec48efc

File tree

9 files changed

+167
-116
lines changed

9 files changed

+167
-116
lines changed

include/cpp2util.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,26 +1613,26 @@ class strict_value {
16131613
template <typename U> requires std::is_convertible_v<T,U>
16141614
explicit constexpr operator U() { return t; }
16151615

1616-
auto operator<=>( strict_value const& ) const -> std::strong_ordering = default;
1616+
constexpr auto operator<=>( strict_value const& ) const -> std::strong_ordering = default;
16171617

16181618
auto to_string() const -> std::string { return Tag::to_string(*this); }
16191619

16201620
friend auto operator<<(std::ostream& o, strict_value const& v) -> std::ostream& { return o << v.to_string(); }
16211621

16221622
// Bitwise operations
16231623

1624-
auto operator|=( strict_value const& that ) -> strict_value requires BitwiseOps { t |= that.t; return *this; }
1625-
auto operator&=( strict_value const& that ) -> strict_value requires BitwiseOps { t &= that.t; return *this; }
1626-
auto operator^=( strict_value const& that ) -> strict_value requires BitwiseOps { t ^= that.t; return *this; }
1624+
constexpr auto operator|=( strict_value const& that ) -> strict_value requires BitwiseOps { t |= that.t; return *this; }
1625+
constexpr auto operator&=( strict_value const& that ) -> strict_value requires BitwiseOps { t &= that.t; return *this; }
1626+
constexpr auto operator^=( strict_value const& that ) -> strict_value requires BitwiseOps { t ^= that.t; return *this; }
16271627

1628-
auto operator| ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t | that.t); }
1629-
auto operator& ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t & that.t); }
1630-
auto operator^ ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t ^ that.t); }
1628+
constexpr auto operator| ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t | that.t); }
1629+
constexpr auto operator& ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t & that.t); }
1630+
constexpr auto operator^ ( strict_value const& that ) const -> strict_value requires BitwiseOps { return strict_value(t ^ that.t); }
16311631

1632-
auto has ( strict_value const& that ) const -> bool requires BitwiseOps { return t & that.t; }
1632+
constexpr auto has ( strict_value const& that ) const -> bool requires BitwiseOps { return t & that.t; }
16331633

1634-
auto set ( strict_value const& that ) -> void requires BitwiseOps { t |= that.t; }
1635-
auto clear ( strict_value const& that ) -> void requires BitwiseOps { t &= ~that.t; }
1634+
constexpr auto set ( strict_value const& that ) -> void requires BitwiseOps { t |= that.t; }
1635+
constexpr auto clear ( strict_value const& that ) -> void requires BitwiseOps { t &= ~that.t; }
16361636
};
16371637

16381638
template <typename T, typename Tag>

regression-tests/pure2-enum.cpp2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ rgb: @enum type = {
1515
}
1616

1717
file_attributes: @flag_enum type = {
18-
cached; // 1
19-
current; // 2
20-
obsolete; // 4
21-
cached_and_current := 3;
18+
cached: u8; // 1
19+
current; // 2
20+
obsolete; // 4
21+
cached_and_current := cached | current;
2222
}
2323

2424
main: () = {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ public: file_attributes(cpp2::in<cpp2::strict_value<cpp2::u8,file_attributes,tru
6767
public: auto static constexpr cached = cpp2::strict_value<cpp2::u8,file_attributes,true>(1);
6868
public: auto static constexpr current = cpp2::strict_value<cpp2::u8,file_attributes,true>(2);
6969
public: auto static constexpr obsolete = cpp2::strict_value<cpp2::u8,file_attributes,true>(4);
70-
public: auto static constexpr cached_and_current = cpp2::strict_value<cpp2::u8,file_attributes,true>(3);
70+
public: auto static constexpr cached_and_current = cpp2::strict_value<cpp2::u8,file_attributes,true>(cached | current);
7171
public: auto static constexpr none = cpp2::strict_value<cpp2::u8,file_attributes,true>(0);
7272
public: [[nodiscard]] static auto size() -> auto;
7373
public: [[nodiscard]] static auto to_string(cpp2::in<cpp2::strict_value<cpp2::u8,file_attributes,true>> value) -> std::string;
7474
public: [[nodiscard]] auto to_string() const& -> std::string;
7575
public: file_attributes(file_attributes const& that);
7676
public: explicit file_attributes();
7777

78-
// 1
79-
// 2
80-
// 4
78+
// 1
79+
// 2
80+
// 4
8181

8282
#line 22 "pure2-enum.cpp2"
8383
};

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,19 @@ class name_or_number {
1919
private: std::array<std::byte,cpp2::max(sizeof(std::string), sizeof(cpp2::i32))> storage__ {}; private: cpp2::i8 discriminator__ {-1}; public: [[nodiscard]] auto is_name() const& -> bool;
2020
public: [[nodiscard]] auto get_name() const& -> auto&&;
2121
public: [[nodiscard]] auto get_name() & -> auto&&;
22-
public: auto set_name(auto&& value) & -> void
23-
CPP2_REQUIRES_ (std::is_same_v<CPP2_TYPEOF(value), std::string>);
22+
public: auto set_name(cpp2::in<std::string> value) & -> void;
2423
public: [[nodiscard]] auto is_num() const& -> bool;
2524
public: [[nodiscard]] auto get_num() const& -> auto&&;
2625
public: [[nodiscard]] auto get_num() & -> auto&&;
27-
public: auto set_num(auto&& value) & -> void
28-
CPP2_REQUIRES_ (std::is_same_v<CPP2_TYPEOF(value), cpp2::i32>);
26+
public: auto set_num(cpp2::in<cpp2::i32> value) & -> void;
2927
private: auto destroy() & -> void;
3028
public: ~name_or_number() noexcept;
3129

3230
public: name_or_number() = default;
3331
public: name_or_number(name_or_number const&) = delete; /* No 'that' constructor, suppress copy */
3432
public: auto operator=(name_or_number const&) -> void = delete;
3533

34+
3635
#line 5 "pure2-union.cpp2"
3736
};
3837

@@ -52,15 +51,13 @@ auto main() -> int;
5251
cpp2::Default.expects(is_name(), "");return *cpp2::assert_not_null(reinterpret_cast<std::string const*>(&storage__)); }
5352
[[nodiscard]] auto name_or_number::get_name() & -> auto&& {
5453
cpp2::Default.expects(is_name(), "");return *cpp2::assert_not_null(reinterpret_cast<std::string*>(&storage__)); }
55-
auto name_or_number::set_name(auto&& value) & -> void
56-
requires (std::is_same_v<CPP2_TYPEOF(value), std::string>){if (!(is_name())) {destroy();std::construct_at(reinterpret_cast<std::string*>(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast<std::string*>(&storage__)) = value;}discriminator__ = 0;}
54+
auto name_or_number::set_name(cpp2::in<std::string> value) & -> void{if (!(is_name())) {destroy();std::construct_at(reinterpret_cast<std::string*>(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast<std::string*>(&storage__)) = value;}discriminator__ = 0;}
5755
[[nodiscard]] auto name_or_number::is_num() const& -> bool { return discriminator__ == 1; }
5856
[[nodiscard]] auto name_or_number::get_num() const& -> auto&& {
5957
cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast<cpp2::i32 const*>(&storage__)); }
6058
[[nodiscard]] auto name_or_number::get_num() & -> auto&& {
6159
cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast<cpp2::i32*>(&storage__)); }
62-
auto name_or_number::set_num(auto&& value) & -> void
63-
requires (std::is_same_v<CPP2_TYPEOF(value), cpp2::i32>){if (!(is_num())) {destroy();std::construct_at(reinterpret_cast<cpp2::i32*>(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast<cpp2::i32*>(&storage__)) = value;}discriminator__ = 1;}
60+
auto name_or_number::set_num(cpp2::in<cpp2::i32> value) & -> void{if (!(is_num())) {destroy();std::construct_at(reinterpret_cast<cpp2::i32*>(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast<cpp2::i32*>(&storage__)) = value;}discriminator__ = 1;}
6461
auto name_or_number::destroy() & -> void{
6562
if (discriminator__ == 0) {std::destroy_at(reinterpret_cast<std::string*>(&storage__));}
6663
if (discriminator__ == 1) {std::destroy_at(reinterpret_cast<cpp2::i32*>(&storage__));}

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 8913:1723
2+
cppfront compiler v0.2.1 Build 8914:0944
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-
"8913:1723"
1+
"8914:0944"

source/common.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,20 @@ auto to_upper_and_underbar(std::string_view s)
478478
}
479479

480480

481+
auto is_empty_or_a_decimal_number(std::string_view s)
482+
-> bool
483+
{
484+
auto size = std::ssize(s);
485+
if (size == 0) { return true; }
486+
487+
auto i = 0;
488+
while (i < size && isspace(s[i]) ) { ++i; }
489+
while (i < size && isdigit(s[i]) ) { ++i; }
490+
while (i < size && isspace(s[i]) ) { ++i; }
491+
return i == size;
492+
}
493+
494+
481495
auto starts_with(
482496
std::string const& s,
483497
std::string_view sv

0 commit comments

Comments
 (0)