mirror of
https://github.com/TartanLlama/expected.git
synced 2025-08-02 10:24:31 +02:00
Add or_else
This commit is contained in:
53
expected.hpp
53
expected.hpp
@@ -1138,11 +1138,35 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// \brief Calls `f` if the expectd is in the unexpected state
|
||||||
|
/// \requires `std::invoke_result_t<F>` must be void or convertible to
|
||||||
|
/// `expcted<T,E>`.
|
||||||
|
/// \effects If `*this` has a value, returns `*this`.
|
||||||
|
/// Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns
|
||||||
|
/// `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`.
|
||||||
|
///
|
||||||
|
/// \group or_else
|
||||||
|
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
|
||||||
|
return or_else_impl(*this, std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && {
|
||||||
|
return or_else_impl(std::move(*this), std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F> expected constexpr or_else(F &&f) const & {
|
||||||
|
return or_else_impl(*this, std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F> expected constexpr or_else(F &&f) const && {
|
||||||
|
return or_else_impl(std::move(*this), std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
constexpr expected() = default;
|
constexpr expected() = default;
|
||||||
constexpr expected(const expected &rhs) = default;
|
constexpr expected(const expected &rhs) = default;
|
||||||
constexpr expected(expected &&rhs) = default;
|
constexpr expected(expected &&rhs) = default;
|
||||||
expected &operator=(const expected &rhs) = default;
|
expected &operator=(const expected &rhs) = default;
|
||||||
expected &operator=(expected &&rhs) = default;
|
expected &operator=(expected &&rhs) = default;
|
||||||
|
|
||||||
template <class... Args,
|
template <class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
||||||
@@ -1592,6 +1616,31 @@ constexpr auto map_error_impl(Exp &&exp, F &&f) -> ret_t<Exp, Ret> {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <class Exp, class F,
|
||||||
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
*std::declval<Exp>())),
|
||||||
|
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||||
|
constexpr detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
|
||||||
|
if (exp.has_value()) {
|
||||||
|
return std::forward<Exp>(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Exp, class F,
|
||||||
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
*std::declval<Exp>())),
|
||||||
|
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
|
||||||
|
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
|
||||||
|
if (exp.has_value()) {
|
||||||
|
return std::forward<Exp>(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
|
||||||
|
return std::forward<Exp>(exp);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
|
Reference in New Issue
Block a user