diff --git a/regression-tests/pure2-union.cpp2 b/regression-tests/pure2-union.cpp2 new file mode 100644 index 000000000..26e83c098 --- /dev/null +++ b/regression-tests/pure2-union.cpp2 @@ -0,0 +1,26 @@ + +name_or_number: @union type = { + name: std::string; + num : i32; +} + +print_name: (non: name_or_number) = { + if non.is_name() { + std::cout << non.get_name() << "\n"; + } + else { + std::cout << "(not a name)\n"; + } +} + +main: () = { + x: name_or_number = (); + std::cout << "sizeof(x) is (sizeof(x))$\n"; + + x.print_name(); + + s: std::string = "xyzzy"; + x.set_name( s ); + + x.print_name(); +} diff --git a/regression-tests/test-results/clang-12/pure2-union.cpp.execution b/regression-tests/test-results/clang-12/pure2-union.cpp.execution new file mode 100644 index 000000000..a2ffc0de8 --- /dev/null +++ b/regression-tests/test-results/clang-12/pure2-union.cpp.execution @@ -0,0 +1,3 @@ +sizeof(x) is 33 +(not a name) +xyzzy diff --git a/regression-tests/test-results/clang-12/pure2-union.cpp.output b/regression-tests/test-results/clang-12/pure2-union.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/gcc-10/pure2-union.cpp.output b/regression-tests/test-results/gcc-10/pure2-union.cpp.output new file mode 100644 index 000000000..30dac4442 --- /dev/null +++ b/regression-tests/test-results/gcc-10/pure2-union.cpp.output @@ -0,0 +1,14 @@ +pure2-union.cpp2:6:42: error: expected ‘;’ at end of member declaration +In file included from pure2-union.cpp:7: +../../../include/cpp2util.h:10005: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. +pure2-union.cpp2:7:1: note: in expansion of macro ‘CPP2_REQUIRES_’ +pure2-union.cpp2:11:41: error: expected ‘;’ at end of member declaration +In file included from pure2-union.cpp:7: +../../../include/cpp2util.h:10005: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. +pure2-union.cpp2:12:1: note: in expansion of macro ‘CPP2_REQUIRES_’ +pure2-union.cpp2:28:6: error: no declaration matches ‘void name_or_number::set_name(auto:82&&) & requires is_same_v::type>::type, std::__cxx11::string>’ +pure2-union.cpp2:6:14: note: candidate is: ‘template void name_or_number::set_name(auto:80&&) &’ +pure2-union.cpp2:2:7: note: ‘class name_or_number’ defined here +pure2-union.cpp2:35:6: error: no declaration matches ‘void name_or_number::set_num(auto:83&&) & requires is_same_v::type>::type, cpp2::i32>’ +pure2-union.cpp2:11:14: note: candidate is: ‘template void name_or_number::set_num(auto:81&&) &’ +pure2-union.cpp2:2:7: note: ‘class name_or_number’ defined here diff --git a/regression-tests/test-results/gcc-13/pure2-union.cpp.execution b/regression-tests/test-results/gcc-13/pure2-union.cpp.execution new file mode 100644 index 000000000..a2ffc0de8 --- /dev/null +++ b/regression-tests/test-results/gcc-13/pure2-union.cpp.execution @@ -0,0 +1,3 @@ +sizeof(x) is 33 +(not a name) +xyzzy diff --git a/regression-tests/test-results/gcc-13/pure2-union.cpp.output b/regression-tests/test-results/gcc-13/pure2-union.cpp.output new file mode 100644 index 000000000..e69de29bb diff --git a/regression-tests/test-results/msvc-2022/pure2-union.cpp.execution b/regression-tests/test-results/msvc-2022/pure2-union.cpp.execution new file mode 100644 index 000000000..911720f23 --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-union.cpp.execution @@ -0,0 +1,3 @@ +sizeof(x) is 25 +(not a name) +xyzzy diff --git a/regression-tests/test-results/msvc-2022/pure2-union.cpp.output b/regression-tests/test-results/msvc-2022/pure2-union.cpp.output new file mode 100644 index 000000000..e4baed02d --- /dev/null +++ b/regression-tests/test-results/msvc-2022/pure2-union.cpp.output @@ -0,0 +1 @@ +pure2-union.cpp diff --git a/regression-tests/test-results/pure2-union.cpp b/regression-tests/test-results/pure2-union.cpp new file mode 100644 index 000000000..e4abb94f3 --- /dev/null +++ b/regression-tests/test-results/pure2-union.cpp @@ -0,0 +1,91 @@ + +#define CPP2_USE_MODULES Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + + +#line 2 "pure2-union.cpp2" +class name_or_number; + + +//=== Cpp2 type definitions and function declarations =========================== + + +#line 2 "pure2-union.cpp2" +class name_or_number { +private: std::array storage__ {}; private: cpp2::i8 discriminator__ {-1}; public: [[nodiscard]] auto is_name() const& -> bool; +public: [[nodiscard]] auto get_name() const& -> auto&&; +public: [[nodiscard]] auto get_name() & -> auto&&; +public: auto set_name(auto&& value) & -> void +CPP2_REQUIRES_ (std::is_same_v); +public: [[nodiscard]] auto is_num() const& -> bool; +public: [[nodiscard]] auto get_num() const& -> auto&&; +public: [[nodiscard]] auto get_num() & -> auto&&; +public: auto set_num(auto&& value) & -> void +CPP2_REQUIRES_ (std::is_same_v); +private: auto destroy() & -> void; +public: ~name_or_number() noexcept; + + public: name_or_number() = default; + public: name_or_number(name_or_number const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(name_or_number const&) -> void = delete; + +#line 5 "pure2-union.cpp2" +}; + +auto print_name(cpp2::in non) -> void; + + +#line 16 "pure2-union.cpp2" +auto main() -> int; + + +//=== Cpp2 function definitions ================================================= + + + + [[nodiscard]] auto name_or_number::is_name() const& -> bool { return discriminator__ == 0; } +[[nodiscard]] auto name_or_number::get_name() const& -> auto&& { + cpp2::Default.expects(is_name(), "");return *cpp2::assert_not_null(reinterpret_cast(&storage__)); } +[[nodiscard]] auto name_or_number::get_name() & -> auto&& { + cpp2::Default.expects(is_name(), "");return *cpp2::assert_not_null(reinterpret_cast(&storage__)); } +auto name_or_number::set_name(auto&& value) & -> void +requires (std::is_same_v){if (!(is_name())) {destroy();std::construct_at(reinterpret_cast(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast(&storage__)) = value;}discriminator__ = 0;} +[[nodiscard]] auto name_or_number::is_num() const& -> bool { return discriminator__ == 1; } +[[nodiscard]] auto name_or_number::get_num() const& -> auto&& { + cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast(&storage__)); } +[[nodiscard]] auto name_or_number::get_num() & -> auto&& { + cpp2::Default.expects(is_num(), "");return *cpp2::assert_not_null(reinterpret_cast(&storage__)); } +auto name_or_number::set_num(auto&& value) & -> void +requires (std::is_same_v){if (!(is_num())) {destroy();std::construct_at(reinterpret_cast(&storage__), value);}else {*cpp2::assert_not_null(reinterpret_cast(&storage__)) = value;}discriminator__ = 1;} +auto name_or_number::destroy() & -> void{ + if (discriminator__ == 0) {std::destroy_at(reinterpret_cast(&storage__));} + if (discriminator__ == 1) {std::destroy_at(reinterpret_cast(&storage__));} + } + + name_or_number::~name_or_number() noexcept{destroy();} +#line 7 "pure2-union.cpp2" +auto print_name(cpp2::in non) -> void{ + if (CPP2_UFCS_0(is_name, non)) { + std::cout << CPP2_UFCS_0(get_name, non) << "\n"; + } + else { + std::cout << "(not a name)\n"; + } +} + +auto main() -> int{ + name_or_number x {}; + std::cout << "sizeof(x) is " + cpp2::to_string(sizeof(x)) + "\n"; + + CPP2_UFCS_0(print_name, x); + + std::string s {"xyzzy"}; + CPP2_UFCS(set_name, x, std::move(s)); + + CPP2_UFCS_0(print_name, std::move(x)); +} + diff --git a/regression-tests/test-results/pure2-union.cpp2.output b/regression-tests/test-results/pure2-union.cpp2.output new file mode 100644 index 000000000..7b95a32a3 --- /dev/null +++ b/regression-tests/test-results/pure2-union.cpp2.output @@ -0,0 +1,2 @@ +pure2-union.cpp2... ok (all Cpp2, passes safety checks) +