diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index 0d65fc33..12a8b689 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -445,4 +445,22 @@ inline Unexpected error(const Error& _err) { } // namespace rfl +#ifdef REFLECTCPP_USE_STD_EXPECTED +template <> +class std::bad_expected_access : public bad_expected_access { + public: + explicit constexpr bad_expected_access(rfl::Error er) : err_(std::move(er)) {} + const char* what() const noexcept override { return err_.what().c_str(); } + + template + [[nodiscard]] + auto error(this Self&& self) noexcept { + return std::forward(self).err_; + } + + private: + rfl::Error err_; +}; #endif + +#endif \ No newline at end of file diff --git a/tests/generic/test_bad_access_error.cpp b/tests/generic/test_bad_access_error.cpp new file mode 100644 index 00000000..5422512d --- /dev/null +++ b/tests/generic/test_bad_access_error.cpp @@ -0,0 +1,40 @@ +#ifdef REFLECTCPP_USE_STD_EXPECTED +#include +#endif + +#include +#include + +namespace test_exceptions { + +struct Person { + rfl::Rename<"firstName", std::string> first_name; + rfl::Rename<"lastName", std::string> last_name = "Flanders"; +}; + +TEST(generic, test_exceptions) { + const std::string error_message = "unified bad access message!"; + #ifdef REFLECTCPP_USE_STD_EXPECTED + rfl::Result person = std::unexpected(rfl::Error(error_message)); +#else + rfl::Result person(rfl::error(error_message)); +#endif + + try { + person.value(); + FAIL() << "Expected an exception!"; + } +#ifdef REFLECTCPP_USE_STD_EXPECTED + catch (std::bad_expected_access const& err) { + EXPECT_EQ(err.what(), error_message); + } +#else + catch (std::runtime_error const& err) { + EXPECT_EQ(err.what(), error_message); + } +#endif + catch (...) { + FAIL() << "Invalid exception type!"; + } +} +} // namespace test_exceptions