|
| 1 | + |
| 2 | +#define CPP2_USE_MODULES Yes |
| 3 | + |
| 4 | +//=== Cpp2 type declarations ==================================================== |
| 5 | + |
| 6 | + |
| 7 | +#include "cpp2util.h" |
| 8 | + |
| 9 | + |
| 10 | +#line 2 "pure2-union.cpp2" |
| 11 | +class name_or_number; |
| 12 | + |
| 13 | + |
| 14 | +//=== Cpp2 type definitions and function declarations =========================== |
| 15 | + |
| 16 | + |
| 17 | +#line 2 "pure2-union.cpp2" |
| 18 | +class name_or_number { |
| 19 | +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; |
| 20 | +public: [[nodiscard]] auto get_name() const& -> auto&&; |
| 21 | +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>); |
| 24 | +public: [[nodiscard]] auto is_num() const& -> bool; |
| 25 | +public: [[nodiscard]] auto get_num() const& -> auto&&; |
| 26 | +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>); |
| 29 | +private: auto destroy() & -> void; |
| 30 | +public: ~name_or_number() noexcept; |
| 31 | + |
| 32 | + public: name_or_number() = default; |
| 33 | + public: name_or_number(name_or_number const&) = delete; /* No 'that' constructor, suppress copy */ |
| 34 | + public: auto operator=(name_or_number const&) -> void = delete; |
| 35 | + |
| 36 | +#line 5 "pure2-union.cpp2" |
| 37 | +}; |
| 38 | + |
| 39 | +auto print_name(cpp2::in<name_or_number> non) -> void; |
| 40 | + |
| 41 | + |
| 42 | +#line 16 "pure2-union.cpp2" |
| 43 | +auto main() -> int; |
| 44 | + |
| 45 | + |
| 46 | +//=== Cpp2 function definitions ================================================= |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | + [[nodiscard]] auto name_or_number::is_name() const& -> bool { return discriminator__ == 0; } |
| 51 | +[[nodiscard]] auto name_or_number::get_name() const& -> auto&& { |
| 52 | + cpp2::Default.expects(is_name(), "");return *cpp2::assert_not_null(reinterpret_cast<std::string const*>(&storage__)); } |
| 53 | +[[nodiscard]] auto name_or_number::get_name() & -> auto&& { |
| 54 | + 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;} |
| 57 | +[[nodiscard]] auto name_or_number::is_num() const& -> bool { return discriminator__ == 1; } |
| 58 | +[[nodiscard]] auto name_or_number::get_num() const& -> auto&& { |
| 59 | + cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast<cpp2::i32 const*>(&storage__)); } |
| 60 | +[[nodiscard]] auto name_or_number::get_num() & -> auto&& { |
| 61 | + 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;} |
| 64 | +auto name_or_number::destroy() & -> void{ |
| 65 | + if (discriminator__ == 0) {std::destroy_at(reinterpret_cast<std::string*>(&storage__));} |
| 66 | + if (discriminator__ == 1) {std::destroy_at(reinterpret_cast<cpp2::i32*>(&storage__));} |
| 67 | + } |
| 68 | + |
| 69 | + name_or_number::~name_or_number() noexcept{destroy();} |
| 70 | +#line 7 "pure2-union.cpp2" |
| 71 | +auto print_name(cpp2::in<name_or_number> non) -> void{ |
| 72 | + if (CPP2_UFCS_0(is_name, non)) { |
| 73 | + std::cout << CPP2_UFCS_0(get_name, non) << "\n"; |
| 74 | + } |
| 75 | + else { |
| 76 | + std::cout << "(not a name)\n"; |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +auto main() -> int{ |
| 81 | + name_or_number x {}; |
| 82 | + std::cout << "sizeof(x) is " + cpp2::to_string(sizeof(x)) + "\n"; |
| 83 | + |
| 84 | + CPP2_UFCS_0(print_name, x); |
| 85 | + |
| 86 | + std::string s {"xyzzy"}; |
| 87 | + CPP2_UFCS(set_name, x, std::move(s)); |
| 88 | + |
| 89 | + CPP2_UFCS_0(print_name, std::move(x)); |
| 90 | +} |
| 91 | + |
0 commit comments