Skip to content

Commit

Permalink
Refactor error handling in result class
Browse files Browse the repository at this point in the history
  • Loading branch information
GregoryKogan committed Jan 7, 2024
1 parent 8ef9ab9 commit 6955baf
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
14 changes: 11 additions & 3 deletions result.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ template <typename E> class err {
explicit err(E error) : error_(std::move(error)) {}

template <typename T> operator result<T, E>() const; // NOLINT(google-explicit-constructor)
operator result<void, E>() const; // NOLINT(google-explicit-constructor)
};

template <typename E> template <typename T> inline err<E>::operator result<T, E>() const {
return result<T, E>(error_, false);
}

template <typename E> inline err<E>::operator result<void, E>() const { return result<void, E>(error_); }

} // namespace res

#include <variant>
Expand Down Expand Up @@ -109,7 +112,7 @@ template <typename E> class result<void, E> {
E error_;

explicit result() : successful_(true) {}
explicit result(const E &error) : error_(error), successful_(false) {}
explicit result(E error) : error_(std::move(error)), successful_(false) {}

template <typename U> friend class ok;
template <typename U> friend class err;
Expand All @@ -123,12 +126,17 @@ template <typename E> class result<void, E> {
};

template <typename T, typename E> inline auto result<T, E>::value() const -> const T & {
if (!is_ok()) { throw std::runtime_error("value() called on result with error"); }
if (!is_ok()) { throw std::logic_error("value() called on result with error"); }
return value_;
}

template <typename T, typename E> inline auto result<T, E>::error() const -> const E & {
if (is_ok()) { throw std::runtime_error("error() called on result with value"); }
if (is_ok()) { throw std::logic_error("error() called on result with value"); }
return error_;
}

template <typename E> inline auto result<void, E>::error() const -> const E & {
if (is_ok()) { throw std::logic_error("error() called on result with value"); }
return error_;
}

Expand Down
3 changes: 3 additions & 0 deletions src/err/err.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ template <typename E> class err {
explicit err(E error) : error_(std::move(error)) {}

template <typename T> operator result<T, E>() const; // NOLINT(google-explicit-constructor)
operator result<void, E>() const; // NOLINT(google-explicit-constructor)
};

template <typename E> template <typename T> inline err<E>::operator result<T, E>() const {
return result<T, E>(error_, false);
}

template <typename E> inline err<E>::operator result<void, E>() const { return result<void, E>(error_); }

} // namespace res
11 changes: 8 additions & 3 deletions src/result/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ template <typename E> class result<void, E> {
E error_;

explicit result() : successful_(true) {}
explicit result(const E &error) : error_(error), successful_(false) {}
explicit result(E error) : error_(std::move(error)), successful_(false) {}

template <typename U> friend class ok;
template <typename U> friend class err;
Expand All @@ -59,12 +59,17 @@ template <typename E> class result<void, E> {
};

template <typename T, typename E> inline auto result<T, E>::value() const -> const T & {
if (!is_ok()) { throw std::runtime_error("value() called on result with error"); }
if (!is_ok()) { throw std::logic_error("value() called on result with error"); }
return value_;
}

template <typename T, typename E> inline auto result<T, E>::error() const -> const E & {
if (is_ok()) { throw std::runtime_error("error() called on result with value"); }
if (is_ok()) { throw std::logic_error("error() called on result with value"); }
return error_;
}

template <typename E> inline auto result<void, E>::error() const -> const E & {
if (is_ok()) { throw std::logic_error("error() called on result with value"); }
return error_;
}

Expand Down
14 changes: 14 additions & 0 deletions tests/boolean_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ TEST(BooleanOperations, Ok) {
EXPECT_TRUE(result.is_ok());
EXPECT_FALSE(!result.is_ok());
EXPECT_EQ(result.value(), 42);
EXPECT_THROW(auto val = result.error(), std::logic_error); // NOLINT
}

TEST(BooleanOperations, Err) {
Expand All @@ -20,6 +21,7 @@ TEST(BooleanOperations, Err) {
EXPECT_FALSE(result.is_ok());
EXPECT_TRUE(!result.is_ok());
EXPECT_EQ(result.error(), "error");
EXPECT_THROW(auto val = result.value(), std::logic_error); // NOLINT
}

TEST(BooleanOperations, VoidOk) {
Expand All @@ -28,4 +30,16 @@ TEST(BooleanOperations, VoidOk) {
EXPECT_FALSE(!result);
EXPECT_TRUE(result.is_ok());
EXPECT_FALSE(!result.is_ok());
EXPECT_THROW(auto val = result.error(), std::logic_error); // NOLINT
}

TEST(BooleanOperations, VoidErr) {
const std::string error = "error";
res::result<void, std::string> result = res::err(error);
EXPECT_FALSE(result);
EXPECT_TRUE(!result);
EXPECT_FALSE(result.is_ok());
EXPECT_TRUE(!result.is_ok());
EXPECT_EQ(result.error(), "error");
// EXPECT_THROW(auto val = result.value(), std::logic_error); - Should not compile
}

0 comments on commit 6955baf

Please sign in to comment.