result is a C++ library that provides a Result<T, E> type, which can be used to return and propagate errors. It's inspired by Rust's std::Result type.
More...
-#include <stdexcept>
+
#include <optional>
+#include <stdexcept>
#include <utility>
#include <variant>
diff --git a/result_8h_source.html b/result_8h_source.html
index cec3776..cac73b6 100644
--- a/result_8h_source.html
+++ b/result_8h_source.html
@@ -140,170 +140,172 @@
-
-
-
-
+
+
+
+
-
22template <
typename T,
typename E>
class result;
-
23template <
typename E>
class result<void, E>;
-
-
28template <
typename E>
class err {
-
-
-
-
-
33 explicit err(E error) : error_(std::move(error)) {}
-
-
-
-
-
-
-
-
-
-
43template <
typename E>
inline err<E>::operator result<void, E>()
const {
-
44 return result<void, E>(result<void, E>::Unsuccessful::UNSUCCESSFUL, error_);
-
-
-
+
+
+
24template <
typename T,
typename E>
class result;
+
25template <
typename E>
class result<void, E>;
+
+
30template <
typename E>
class err {
+
+
+
+
+
35 explicit err(E error) : error_(std::move(error)) {}
+
+
+
+
+
+
+
+
+
+
45template <
typename E>
inline err<E>::operator result<void, E>()
const {
+
46 return result<void, E>(result<void, E>::Unsuccessful::UNSUCCESSFUL, error_);
+
-
+
-
+
-
53template <
typename T,
typename E>
class result;
-
54template <
typename E>
class result<void, E>;
-
-
59template <
typename T = std::monostate>
class ok {
-
-
-
-
-
64 explicit ok(T value) : value_(std::move(value)) {}
-
-
-
-
-
-
-
-
-
-
74template <
typename T>
template <
typename E>
inline ok<T>::operator result<void, E>()
const {
-
75 return result<void, E>(result<void, E>::Successful::SUCCESSFUL);
-
-
-
+
+
+
55template <
typename T,
typename E>
class result;
+
56template <
typename E>
class result<void, E>;
+
+
61template <
typename T = std::monostate>
class ok {
+
+
+
+
+
66 explicit ok(T value) : value_(std::move(value)) {}
+
+
+
+
+
+
+
+
+
+
76template <
typename T>
template <
typename E>
inline ok<T>::operator result<void, E>()
const {
+
77 return result<void, E>(result<void, E>::Successful::SUCCESSFUL);
+
-
+
-
88template <
typename T,
typename E>
class result {
-
89 static_assert(!std::is_same_v<T, void>,
"T (value type) must not be void");
-
90 static_assert(!std::is_same_v<E, void>,
"E (error type) must not be void");
-
-
-
-
+
+
+
90template <
typename T,
typename E>
class result {
+
91 static_assert(!std::is_same_v<T, void>,
"T (value type) must not be void");
+
92 static_assert(!std::is_same_v<E, void>,
"E (error type) must not be void");
+
+
94 std::variant<T, E> content_;
-
+
97 enum Successful { SUCCESSFUL };
98 enum Unsuccessful { UNSUCCESSFUL };
-
99 result(Successful successful, T value) : successful_(
true), value_(std::move(value)) {}
-
100 result(Unsuccessful unsuccessful, E error) : successful_(
false), error_(std::move(error)) {}
+
99 result(Successful successful, T value) { content_.template emplace<0>(std::move(value)); }
+
100 result(Unsuccessful unsuccessful, E error) { content_.template emplace<1>(std::move(error)); }
-
102 auto make_successful(T value) ->
void {
-
-
104 value_ = std::move(value);
-
-
106 auto make_unsuccessful(E error) ->
void {
-
-
108 error_ = std::move(error);
-
+
102 template <
typename U>
friend class ok;
+
103 template <
typename U>
friend class err;
+
+
+
+
107 [[nodiscard]]
auto is_ok()
const ->
bool {
return content_.index() == 0; }
+
108 explicit operator bool()
const {
return is_ok(); }
+
109 auto operator!()
const ->
bool {
return !is_ok(); }
-
111 template <
typename U>
friend class ok;
-
112 template <
typename U>
friend class err;
-
-
-
-
116 [[nodiscard]]
auto is_ok()
const ->
bool {
return successful_; }
-
117 explicit operator bool()
const {
return is_ok(); }
-
118 auto operator!()
const ->
bool {
return !is_ok(); }
-
-
120 [[nodiscard]]
auto value()
const ->
const T &;
-
121 [[nodiscard]]
auto value_or(T &&default_value)
const -> T;
-
122 [[nodiscard]]
auto error()
const ->
const E &;
-
-
-
-
-
-
128 template <
typename F,
typename U = std::invoke_result_t<F, T>>
auto map(F &&functor)
const ->
result<U, E> {
-
129 if (is_ok()) {
return ok<U>(std::forward<F>(functor)(value_)); }
-
-
-
-
-
135template <
typename E>
class result<void, E> {
-
136 static_assert(!std::is_same_v<E, void>,
"E (error type) must not be void");
+
111 [[nodiscard]]
auto value()
const ->
const T &;
+
112 [[nodiscard]]
auto value_or(T &&default_value)
const -> T;
+
113 [[nodiscard]]
auto error()
const ->
const E &;
+
+
+
+
+
+
119 template <
typename F,
typename R = std::invoke_result_t<F, T>>
auto map(F &&functor)
const ->
result<R, E> {
+
120 if (is_ok()) {
return ok<R>(std::forward<F>(functor)(value())); }
+
+
+
+
+
+
126 template <
typename F,
typename U = std::invoke_result_t<F, E>>
auto map_err(F &&functor)
const ->
result<T, U> {
+
127 if (!is_ok()) {
return err<U>(std::forward<F>(functor)(error())); }
+
128 return ok<T>(value());
+
+
+
+
133template <
typename E>
class result<void, E> {
+
134 static_assert(!std::is_same_v<E, void>,
"E (error type) must not be void");
+
+
136 std::optional<E> error_;
-
-
-
-
-
142 enum Successful { SUCCESSFUL };
-
143 enum Unsuccessful { UNSUCCESSFUL };
-
144 explicit result(Successful successful) : successful_(
true) {}
-
145 result(Unsuccessful unsuccessful, E error) : successful_(
false), error_(std::move(error)) {}
+
+
139 enum Successful { SUCCESSFUL };
+
140 enum Unsuccessful { UNSUCCESSFUL };
+
141 explicit result(Successful successful) {}
+
142 result(Unsuccessful unsuccessful, E error) : error_(std::move(error)) {}
+
+
144 template <
typename U>
friend class ok;
+
145 template <
typename U>
friend class err;
-
147 template <
typename U>
friend class ok;
-
148 template <
typename U>
friend class err;
-
-
-
-
152 [[nodiscard]]
auto is_ok()
const ->
bool {
return successful_; }
-
153 explicit operator bool()
const {
return is_ok(); }
-
154 auto operator!()
const ->
bool {
return !is_ok(); }
-
-
156 [[nodiscard]]
auto error()
const ->
const E &;
-
-
-
-
-
-
162 template <
typename F,
typename U = std::invoke_result_t<F>>
auto map(F &&functor)
const ->
result<U, E> {
-
163 if (is_ok()) {
return ok<U>(std::forward<F>(functor)()); }
-
-
-
-
-
-
169 if (!is_ok()) {
throw std::logic_error(
"value() called on result with error"); }
-
-
-
-
173template <
typename T,
typename E>
inline auto result<T, E>::value_or(T &&default_value)
const -> T {
-
174 if (is_ok()) {
return value_; }
-
175 return std::move(default_value);
-
-
-
178template <
typename T,
typename E>
inline auto result<T, E>::error() const -> const E & {
-
179 if (is_ok()) {
throw std::logic_error(
"error() called on result with value"); }
-
-
-
-
183template <
typename E>
inline auto result<void, E>::error() const -> const E & {
-
184 if (is_ok()) {
throw std::logic_error(
"error() called on result with value"); }
-
-
-
-
+
+
+
149 [[nodiscard]]
auto is_ok()
const ->
bool {
return !error_.has_value(); }
+
150 explicit operator bool()
const {
return is_ok(); }
+
151 auto operator!()
const ->
bool {
return !is_ok(); }
+
+
153 [[nodiscard]]
auto error()
const ->
const E &;
+
+
+
+
+
+
159 template <
typename F,
typename R = std::invoke_result_t<F>>
auto map(F &&functor)
const ->
result<R, E> {
+
160 if (is_ok()) {
return ok<R>(std::forward<F>(functor)()); }
+
161 return err<E>(error_.value());
+
+
+
164 template <
typename F,
typename U = std::invoke_result_t<F, E>>
auto map_err(F &&functor)
const ->
result<void, U> {
+
165 if (!is_ok()) {
return err<U>(std::forward<F>(functor)(error_.value())); }
+
+
+
+
+
+
171 if (!is_ok()) {
throw std::logic_error(
"value() called on result with error"); }
+
172 return std::get<0>(content_);
+
+
+
175template <
typename T,
typename E>
inline auto result<T, E>::value_or(T &&default_value)
const -> T {
+
176 if (is_ok()) {
return std::get<0>(content_); }
+
177 return std::move(default_value);
+
+
+
180template <
typename T,
typename E>
inline auto result<T, E>::error() const -> const E & {
+
181 if (is_ok()) {
throw std::logic_error(
"error() called on result with value"); }
+
182 return std::get<1>(content_);
+
+
+
185template <
typename E>
inline auto result<void, E>::error() const -> const E & {
+
186 if (is_ok()) {
throw std::logic_error(
"error() called on result with value"); }
+
187 return error_.value();
+
-
-
Err object represents an unsuccessful outcome and can be implicitly converted to a result.
Definition: result.h:28
-
Ok object represents a successful outcome and can be implicitly converted to a result.
Definition: result.h:59
-
result is a type that represents either success or failure.
Definition: result.h:88
+
+
+
+
Err object represents an unsuccessful outcome and can be implicitly converted to a result.
Definition: result.h:30
+
Ok object represents a successful outcome and can be implicitly converted to a result.
Definition: result.h:61
+
result is a type that represents either success or failure.
Definition: result.h:90