11#include <source_location>
23 template<
typename Promise>
27 auto& promise = handle.promise ();
28 if constexpr (Promise::IsVoid)
29 promise.return_void ();
31 promise.return_value (
Left { error });
36 template<
typename L,
typename R,
typename ErrorHandler>
49 if constexpr (std::is_same_v<IgnoreLeft, HandlerReturn_t>)
51 static_assert (std::is_default_constructible_v<R>);
62 if constexpr (std::is_same_v<void, HandlerReturn_t>)
67 else if constexpr (std::is_same_v<IgnoreLeft, HandlerReturn_t>)
68 qFatal () <<
"shall never suspend when ignoring left";
80 template<
typename L,
typename R,
typename F>
81 requires std::invocable<F, const L&>
84 return { either, std::forward<F> (errorHandler) };
87 template<
typename L,
typename R>
99 QMessageLogger { loc.file_name (),
static_cast<int> (loc.line ()), loc.function_name () }.warning () << msg;
103 template<
typename T,
typename... Msgs>
105 std::source_location loc = std::source_location::current ())
110 std::apply ([&]<
typename... AMsgs> (AMsgs&&... amsgs)
112 const QMessageLogger log { loc.file_name (),
static_cast<int> (loc.line ()), loc.function_name () };
113 (log.warning () << ... << std::forward<AMsgs> (amsgs));
121 template<
typename L,
typename R>
124 return { either, {} };
void TerminateLeftyCoroutine(std::coroutine_handle< Promise > handle, const auto &error)
Either< Void, T > NonEmpty(const T &t, auto &&msg, std::source_location loc=std::source_location::current())
detail::EitherAwaiter< L, R, F > WithHandler(const Either< L, R > &either, F &&errorHandler)
A proper void type, akin to unit (or ()) type in functional languages.
bool await_ready() noexcept
R await_resume() const noexcept
decltype(Handler_(Either_.GetLeft())) HandlerReturn_t
auto await_suspend(auto handle)