4#include "./error_code.h"
14 template <
typename T,
typename E = ErrorCode>
29 Result(
const T &t)
noexcept(
30 std::is_nothrow_copy_constructible<T>::value) : mValue{t}
34 Result(T &&t)
noexcept(
35 std::is_nothrow_move_constructible<T>::value) : mValue{std::move(t)}
39 explicit Result(
const E &e)
noexcept(
40 std::is_nothrow_copy_constructible<E>::value) : mError{e}
44 explicit Result(E &&e)
noexcept(
45 std::is_nothrow_move_constructible<E>::value) : mError{std::move(e)}
49 Result(
const Result &other)
noexcept(
50 std::is_nothrow_copy_assignable<T>::value &&
51 std::is_nothrow_copy_assignable<E>::value)
56 mValue = other.mValue;
60 mError = other.mError;
64 Result(Result &&other)
noexcept(
65 std::is_nothrow_move_assignable<T>::value &&
66 std::is_nothrow_move_assignable<E>::value)
71 mValue = std::move(other.mValue);
75 mError = std::move(other.mError);
79 ~Result() noexcept = default;
84 static Result
FromValue(const T &t) noexcept(
85 std::is_nothrow_copy_constructible<T>::value);
91 std::is_nothrow_move_constructible<T>::value);
96 static Result
FromError(const E &e) noexcept(
97 std::is_nothrow_copy_constructible<E>::value);
103 std::is_nothrow_move_constructible<E>::value);
105 Result &operator=(Result const &other) noexcept(
106 std::is_nothrow_copy_assignable<T>::value &&
107 std::is_nothrow_copy_assignable<E>::value)
110 if (other.HasValue())
112 mValue = other.mValue;
117 mError = other.mError;
124 Result &operator=(Result &&other)
noexcept(
125 std::is_nothrow_move_assignable<T>::value &&
126 std::is_nothrow_move_assignable<E>::value)
129 if (other.HasValue())
131 mValue = std::move(other.mValue);
136 mError = std::move(other.mError);
145 template <
typename... Args>
148 mValue = T{std::move(args...)};
154 template <
typename... Args>
157 mError = E{std::move(args...)};
164 std::is_nothrow_move_assignable<T>::value &&
165 std::is_nothrow_move_assignable<E>::value)
169 std::swap(mValue, other.mValue);
171 else if (
HasValue() && !other.HasValue())
173 mError = std::move(other.mError);
174 other.mValue = std::move(mValue);
176 else if (!
HasValue() && other.HasValue())
178 mValue = std::move(other.mValue);
179 other.mError = std::move(mError);
183 std::swap(mError, other.mError);
195 explicit operator bool() const noexcept
204 return mValue.
Value();
211 return std::move(mValue).Value();
218 return &mValue.
Value();
226 return mValue.
Value();
234 return std::move(mValue).Value();
242 return mError.
Value();
250 return std::move(mError).Value();
264 return std::move(mValue);
278 return std::move(mError);
285 template <
typename U>
288 return mValue.
ValueOr(defaultValue);
295 template <
typename U>
298 return std::move(mValue).ValueOr(defaultValue);
305 template <
typename G>
308 return mError.
ValueOr(defaultError);
315 template <
typename G>
318 return std::move(mError).ValueOr(defaultError);
324 template <
typename G>
334 E _error =
static_cast<E
>(error);
335 return mError.
Value() == _error;
344 return mValue.
Value();
352 return std::move(mValue).Value();
359 template <
typename F>
369 template <
typename F>
385 template <
typename T,
typename E>
387 std::is_nothrow_copy_constructible<T>::value)
393 template <
typename T,
typename E>
395 std::is_nothrow_move_constructible<T>::value)
397 Result _result{std::move(t)};
401 template <
typename T,
typename E>
403 std::is_nothrow_copy_constructible<E>::value)
409 template <
typename T,
typename E>
411 std::is_nothrow_move_constructible<E>::value)
413 Result _result{std::move(e)};
418 template <
typename T,
typename E>
440 template <
typename T,
typename E>
461 template <
typename T,
typename E>
462 inline bool operator==(
const Result<T, E> &lhs,
const T &rhs)
464 bool _result = lhs.HasValue() ? lhs.Value() == rhs :
false;
468 template <
typename T,
typename E>
469 inline bool operator==(
const T &lhs,
const Result<T, E> &rhs)
471 bool _result = rhs.HasValue() ? lhs == rhs.Value() :
false;
475 template <
typename T,
typename E>
476 inline bool operator!=(
const Result<T, E> &lhs,
const T &rhs)
478 bool _result = lhs.HasValue() ? lhs.Value() != rhs :
true;
482 template <
typename T,
typename E>
483 inline bool operator!=(
const T &lhs,
const Result<T, E> &rhs)
485 bool _result = rhs.HasValue() ? lhs != rhs.Value() :
true;
489 template <
typename T,
typename E>
490 inline bool operator==(
const Result<T, E> &lhs,
const E &rhs)
492 bool _result = lhs.HasValue() ? false : lhs.Error() == rhs;
496 template <
typename T,
typename E>
497 inline bool operator==(
const E &lhs,
const Result<T, E> &rhs)
499 bool _result = rhs.HasValue() ? false : lhs == rhs.Error();
503 template <
typename T,
typename E>
504 inline bool operator!=(
const Result<T, E> &lhs,
const E &rhs)
506 bool _result = lhs.HasValue() ? true : lhs.Error() != rhs;
510 template <
typename T,
typename E>
511 inline bool operator!=(
const E &lhs,
const Result<T, E> &rhs)
513 bool _result = rhs.HasValue() ? true : lhs != rhs.Error();
519 template <
typename E>
525 bool hasError()
const noexcept
536 Result() noexcept = default;
538 explicit
Result(const E &e) noexcept(
539 std::is_nothrow_copy_constructible<E>::value) : mError{e}
543 explicit Result(E &&e)
noexcept(
544 std::is_nothrow_move_constructible<E>::value) : mError{std::move(e)}
548 Result(
const Result &other)
noexcept(
549 std::is_nothrow_copy_assignable<E>::value)
551 if (other.hasError())
553 mError = other.mError;
557 Result(Result &&other)
noexcept(
558 std::is_nothrow_move_assignable<E>::value)
560 if (other.hasError())
562 mError = std::move(other.mError);
566 ~Result() noexcept = default;
575 static Result
FromError(const E &e) noexcept(
576 std::is_nothrow_copy_constructible<E>::value);
582 std::is_nothrow_move_constructible<E>::value);
586 template <typename... Args>
590 std::is_nothrow_copy_assignable<E>::value)
592 if (other.hasError())
594 mError = other.mError;
605 std::is_nothrow_move_assignable<E>::value)
609 mError = std::move(other.mError);
621 template <
typename... Args>
630 std::is_nothrow_move_assignable<E>::value)
632 if (hasError() && other.hasError())
634 std::swap(mError, other.mError);
636 else if (hasError() && !other.hasError())
638 other.mError = std::move(mError);
640 else if (!hasError() && other.hasError())
642 mError = std::move(other.mError);
654 constexpr explicit operator bool() const noexcept
659 constexpr void operator*() const noexcept
670 constexpr void Value() const noexcept
680 return mError.
Value();
688 return std::move(mError).Value();
702 return std::move(mError);
706 template <
typename U>
716 template <
typename G>
719 return mError.
ValueOr(defaultError);
726 template <
typename G>
729 return std::move(mError).ValueOr(defaultError);
735 template <
typename G>
740 E _error =
static_cast<E
>(error);
741 return mError.
Value() == _error;
754 throw std::runtime_error(
"Result contains no value.");
760 template <
typename F>
773 template <
typename F>
783 Result<
decltype(f()), E> _result{f()};
789 template <
typename E>
796 template <
typename E>
798 std::is_nothrow_copy_constructible<E>::value)
804 template <
typename E>
806 std::is_nothrow_move_constructible<E>::value)
808 Result _result{std::move(e)};
812 template <
typename E>
813 template <
typename... Args>
816 E _error{std::move(args...)};
817 Result _result{_error};
823 template <
typename E>
845 template <
typename E>
A wrapper around a possible value.
Definition: optional.h:16
void Reset() noexcept
Reset the instance value.
Definition: optional.h:134
constexpr bool HasValue() const noexcept
Indicate whether the instance has a value or not.
Definition: optional.h:145
T ValueOr(U &&defaultValue) const &
Get the instance value or the default value.
Definition: optional.h:236
const T & Value() const &
Get instance possible value.
Definition: optional.h:201
A wrapper around the callee's possible error.
Definition: result.h:521
constexpr bool HasValue() const noexcept
Indicate whether the instance contains an error or not.
Definition: result.h:648
Optional< E > Err() &&
Get optional instance error.
Definition: result.h:700
auto Bind(F &&f) const -> Result< decltype(f()), E >
Create a new Result by invoking a callable.
Definition: result.h:774
E error_type
Result error type alias.
Definition: result.h:534
Optional< E > Err() const &
Get optional instance error.
Definition: result.h:693
void Swap(Result &other) noexcept(std::is_nothrow_move_assignable< E >::value)
Swap the current instance with another one.
Definition: result.h:629
bool CheckError(G &&error) const
Check an error with the instance error.
Definition: result.h:736
const E & Error() const &
Get instance possible error.
Definition: result.h:678
E ErrorOr(G &&defaultError) const &
Get the instance error or the default error.
Definition: result.h:717
E ErrorOr(G &&defaultError) &&
Get the instance error or the default error.
Definition: result.h:727
void Resolve(F &&f) const
Invoke a callable.
Definition: result.h:761
E && Error() &&
Get instance possible error.
Definition: result.h:686
void EmplaceError(Args &&...args)
Construct a new error from the give argument(s) and assign it to the instance error.
Definition: result.h:622
constexpr void Value() const noexcept
The function does nothing.
Definition: result.h:670
void ValueOrThrow() const noexcept(false)
Throw an exception.
Definition: result.h:752
void ValueOr(U &&defaultValue) const noexcept
The function does nothing.
Definition: result.h:707
void value_type
Void value type alias.
Definition: result.h:532
A wrapper around the callee's return value and its possible error.
Definition: result.h:16
static Result FromError(const E &e) noexcept(std::is_nothrow_copy_constructible< E >::value)
Result factory by copying its error.
Definition: result.h:402
Optional< T > Ok() const &
Get optional instance value.
Definition: result.h:255
Optional< E > Err() &&
Get optional instance error.
Definition: result.h:276
const T & ValueOrThrow() const &noexcept(false)
Get instance possible value or throw an exception.
Definition: result.h:342
const T & operator*() const &
Definition: result.h:202
void EmplaceError(Args &&...args)
Construct a new error from the give argument(s) and assign it to the instance error.
Definition: result.h:155
T ValueOr(U &&defaultValue) const &
Get the instance value or the default value.
Definition: result.h:286
bool CheckError(G &&error) const
Check an error with the instance error.
Definition: result.h:325
auto Bind(F &&f) const -> Result< decltype(f(Value())), E >
Create a new Result by passing the instance value (if exists) to a callable.
Definition: result.h:370
T Resolve(F &&f) const
Get the instance value or a callable result.
Definition: result.h:360
T value_type
Result value type alias.
Definition: result.h:23
T && operator*() &&
Definition: result.h:209
const T * operator->() const
Definition: result.h:216
void EmplaceValue(Args &&...args)
Construct a new value from the give argument(s) and assign it to the instance value.
Definition: result.h:146
bool HasValue() const noexcept
Indicate whether the instance has a value or not.
Definition: result.h:189
static Result FromValue(const T &t) noexcept(std::is_nothrow_copy_constructible< T >::value)
Result factory by copying its value.
Definition: result.h:386
E ErrorOr(G &&defaultError) const &
Get the instance error or the default error.
Definition: result.h:306
const T & Value() const &
Get instance possible value.
Definition: result.h:224
void Swap(Result &other) noexcept(std::is_nothrow_move_assignable< T >::value &&std::is_nothrow_move_assignable< E >::value)
Swap the current instance with another one.
Definition: result.h:163
E ErrorOr(G &&defaultError) &&
Get the instance error or the default error.
Definition: result.h:316
T && Value() &&
Get instance possible value.
Definition: result.h:232
Optional< E > Err() const &
Get optional instance error.
Definition: result.h:269
E && Error() &&
Get instance possible error.
Definition: result.h:248
const E & Error() const &
Get instance possible error.
Definition: result.h:240
E error_type
Result error type alias.
Definition: result.h:25
T && ValueOrThrow() &&noexcept(false)
Get instance possible value or throw an exception.
Definition: result.h:350
T ValueOr(U &&defaultValue) &&
Get the instance value or the default value.
Definition: result.h:296
Optional< T > Ok() &&
Get optional instance value.
Definition: result.h:262
bool operator==(Ipv4Address address1, Ipv4Address address2)
Ipv4Address equality operator override.
Definition: ipv4_address.h:63
bool operator!=(Ipv4Address address1, Ipv4Address address2)
Ipv4Address inequality operator override.
Definition: ipv4_address.h:78