From bd6be76a35631c813825fa93595141731408b344 Mon Sep 17 00:00:00 2001 From: Yuming He Date: Thu, 25 Jun 2026 16:27:34 +0800 Subject: [PATCH 1/3] feat: implement LWG-4031 Signed-off-by: Yuming He --- include/zeus/expected.hpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/zeus/expected.hpp b/include/zeus/expected.hpp index 711f744..864be89 100644 --- a/include/zeus/expected.hpp +++ b/include/zeus/expected.hpp @@ -235,14 +235,16 @@ template<> class bad_expected_access : public std::exception { public: - virtual const char *what() const noexcept override { return "Bad expected access"; } + [[nodiscard]] const char *what() const noexcept override { return "Bad expected access"; } protected: - bad_expected_access() = default; - bad_expected_access(const bad_expected_access &) = default; - bad_expected_access(bad_expected_access &&) = default; - bad_expected_access &operator=(const bad_expected_access &) = default; - bad_expected_access &operator=(bad_expected_access &&) = default; + // LWG-4031 + bad_expected_access() noexcept = default; + bad_expected_access(const bad_expected_access &) noexcept = default; + bad_expected_access(bad_expected_access &&) noexcept = default; + bad_expected_access &operator=(const bad_expected_access &) noexcept = default; + bad_expected_access &operator=(bad_expected_access &&) noexcept = default; + ~bad_expected_access() override = default; }; template From cf1a24b05272c361c1eb71b8c1703eed7f7e1bed Mon Sep 17 00:00:00 2001 From: Yuming He Date: Thu, 25 Jun 2026 16:28:41 +0800 Subject: [PATCH 2/3] test: add tests for LWG-4031 Signed-off-by: Yuming He --- tests/test_expected/CMakeLists.txt | 1 + tests/test_expected/lwg_4031_tests.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 tests/test_expected/lwg_4031_tests.cpp diff --git a/tests/test_expected/CMakeLists.txt b/tests/test_expected/CMakeLists.txt index 229ef3b..2d47aeb 100644 --- a/tests/test_expected/CMakeLists.txt +++ b/tests/test_expected/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES noexcept_tests.cpp equality_tests.cpp lwg_3886_tests.cpp + lwg_4031_tests.cpp ) find_package(Catch2 3 REQUIRED) diff --git a/tests/test_expected/lwg_4031_tests.cpp b/tests/test_expected/lwg_4031_tests.cpp new file mode 100644 index 0000000..1d154da --- /dev/null +++ b/tests/test_expected/lwg_4031_tests.cpp @@ -0,0 +1,24 @@ +#include + +#include + +using namespace zeus; + +namespace +{ +// Exposing all members for testing +struct test_bad_expected_access : public bad_expected_access +{ + using bad_expected_access::bad_expected_access; +}; +} + +TEST_CASE("bad_expected_access special members are noexcept", "[LWG-4031]") +{ + STATIC_REQUIRE(std::is_nothrow_default_constructible_v); + STATIC_REQUIRE(std::is_nothrow_copy_constructible_v); + STATIC_REQUIRE(std::is_nothrow_move_constructible_v); + STATIC_REQUIRE(std::is_nothrow_copy_assignable_v); + STATIC_REQUIRE(std::is_nothrow_move_assignable_v); + STATIC_REQUIRE(std::is_nothrow_destructible_v); +} From f1b93da185184cecb11483d7148e9a43cc498bae Mon Sep 17 00:00:00 2001 From: Yuming He Date: Thu, 25 Jun 2026 16:29:06 +0800 Subject: [PATCH 3/3] doc: add features of LWG-4031 Signed-off-by: Yuming He --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2636fa3..558192b 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Implemented LWG Issues: - [x] [LWG-4026](https://wg21.link/lwg4026) Assignment operators of `std::expected` should propagate triviality - [x] [LWG-3877](https://wg21.link/lwg3877) incorrect constraints on const-qualified monadic overloads for `std::expected` - [x] [LWG-3886](https://wg21.link/lwg3886) Monad mo' problems +- [x] [LWG-4031](https://wg21.link/lwg4031) `bad_expected_access` member functions should be noexcept Enhancements: