Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions include/rfl/Result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,4 +445,22 @@ inline Unexpected<Error> error(const Error& _err) {

} // namespace rfl

#ifdef REFLECTCPP_USE_STD_EXPECTED
template <>
class std::bad_expected_access<rfl::Error> : public bad_expected_access<void> {
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 <typename Self>
[[nodiscard]]
auto error(this Self&& self) noexcept {
return std::forward<Self>(self).err_;
}

private:
rfl::Error err_;
};
#endif

#endif
40 changes: 40 additions & 0 deletions tests/generic/test_bad_access_error.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifdef REFLECTCPP_USE_STD_EXPECTED
#include <expected>
#endif

#include <rfl.hpp>
#include <gtest/gtest.h>

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> person = std::unexpected(rfl::Error(error_message));
#else
rfl::Result<Person> person(rfl::error(error_message));
#endif

try {
person.value();
FAIL() << "Expected an exception!";
}
#ifdef REFLECTCPP_USE_STD_EXPECTED
catch (std::bad_expected_access<rfl::Error> 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
Loading