Merge branch 'master' of github.com:TartanLlama/expected

This commit is contained in:
Simon Brand
2018-05-28 21:48:14 +01:00
3 changed files with 230 additions and 20 deletions
+40 -19
View File
@@ -1369,11 +1369,11 @@ public:
#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>`.
/// \requires `F` is invokable with `E`, and `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)()`.
/// Otherwise, if `f` returns `void`, calls `std::forward<F>(f)(E)` and returns
/// `std::nullopt`. Otherwise, returns `std::forward<F>(f)(E)`.
///
/// \group or_else
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
@@ -1388,10 +1388,11 @@ public:
return or_else_impl(*this, std::forward<F>(f));
}
#ifndef TL_EXPECTED_NO_CONSTRR
template <class F> expected constexpr or_else(F &&f) const && {
return or_else_impl(std::move(*this), std::forward<F>(f));
}
#endif
constexpr expected() = default;
constexpr expected(const expected &rhs) = default;
constexpr expected(expected &&rhs) = default;
@@ -2009,31 +2010,51 @@ auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
}
#endif
#ifdef TL_EXPECTED_CXX14
template <class Exp, class F,
class Ret = decltype(detail::invoke(std::declval<F>(),
*std::declval<Exp>())),
std::declval<Exp>().error())),
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));
constexpr auto or_else_impl(Exp &&exp, F &&f) {
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
return exp.has_value()
? std::forward<Exp>(exp)
: detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
}
template <class Exp, class F,
class Ret = decltype(detail::invoke(std::declval<F>(),
*std::declval<Exp>())),
std::declval<Exp>().error())),
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);
return exp.has_value()
? std::forward<Exp>(exp)
: (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
std::forward<Exp>(exp));
}
#else
template <class Exp, class F,
class Ret = decltype(detail::invoke(std::declval<F>(),
std::declval<Exp>().error())),
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
auto or_else_impl(Exp &&exp, F &&f) -> Ret {
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
return exp.has_value()
? std::forward<Exp>(exp)
: detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
}
template <class Exp, class F,
class Ret = decltype(detail::invoke(std::declval<F>(),
std::declval<Exp>().error())),
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
return exp.has_value()
? std::forward<Exp>(exp)
: (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
std::forward<Exp>(exp));
}
#endif
} // namespace detail
template <class T, class E, class U, class F>