LeechCraft 0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
either.h
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <source_location>
12#include <QtDebug>
13#include <util/sll/either.h>
14#include <util/sll/void.h>
15#include "task.h"
16
17namespace LC::Util
18{
19 struct IgnoreLeft {};
20
21 namespace detail
22 {
23 template<typename Promise>
24 [[noreturn]]
25 void TerminateLeftyCoroutine (std::coroutine_handle<Promise> handle, const auto& error)
26 {
27 auto& promise = handle.promise ();
28 if constexpr (Promise::IsVoid)
29 promise.return_void ();
30 else
31 promise.return_value (Left { error });
32
33 throw EitherFailureAbort {};
34 }
35
36 template<typename L, typename R, typename ErrorHandler>
38 {
40 ErrorHandler Handler_;
41
42 using HandlerReturn_t = decltype (Handler_ (Either_.GetLeft ()));
43
44 bool await_ready () noexcept
45 {
46 if (Either_.IsRight ())
47 return true;
48
49 if constexpr (std::is_same_v<IgnoreLeft, HandlerReturn_t>)
50 {
51 static_assert (std::is_default_constructible_v<R>);
52 Handler_ (Either_.GetLeft ());
53 Either_ = R {};
54 return true;
55 }
56
57 return false;
58 }
59
60 auto await_suspend (auto handle)
61 {
62 if constexpr (std::is_same_v<void, HandlerReturn_t>)
63 {
64 Handler_ (Either_.GetLeft ());
65 TerminateLeftyCoroutine (handle, Either_.GetLeft ());
66 }
67 else if constexpr (std::is_same_v<IgnoreLeft, HandlerReturn_t>)
68 qFatal () << "shall never suspend when ignoring left";
69 else
70 TerminateLeftyCoroutine (handle, Handler_ (Either_.GetLeft ()));
71 }
72
73 R await_resume () const noexcept
74 {
75 return Either_.GetRight ();
76 }
77 };
78 }
79
80 template<typename L, typename R, typename F>
81 requires std::invocable<F, const L&>
83 {
84 return { either, std::forward<F> (errorHandler) };
85 }
86
87 template<typename L, typename R>
88 auto WithHandler (const Either<L, R>& either, IgnoreLeft)
89 {
90 return WithHandler (either, [] (const auto&) { return IgnoreLeft {}; });
91 }
92
93 template<typename T>
94 Either<Void, T> NonEmpty (const T& t, auto&& msg, std::source_location loc = std::source_location::current ())
95 {
96 if (t)
97 return t;
98
99 QMessageLogger { loc.file_name (), static_cast<int> (loc.line ()), loc.function_name () }.warning () << msg;
100 return { AsLeft, Void {} };
101 }
102
103 template<typename T, typename... Msgs>
104 Either<Void, T> NonEmpty (const T& t, const std::tuple<Msgs...>& msgsTuple,
105 std::source_location loc = std::source_location::current ())
106 {
107 if (t)
108 return t;
109
110 std::apply ([&]<typename... AMsgs> (AMsgs&&... amsgs)
111 {
112 const QMessageLogger log { loc.file_name (), static_cast<int> (loc.line ()), loc.function_name () };
113 (log.warning () << ... << std::forward<AMsgs> (amsgs));
114 }, msgsTuple);
115 return { AsLeft, Void {} };
116 }
117}
118
119namespace LC
120{
121 template<typename L, typename R>
123 {
124 return { either, {} };
125 }
126}
void TerminateLeftyCoroutine(std::coroutine_handle< Promise > handle, const auto &error)
Definition either.h:25
constexpr auto AsLeft
Definition either.h:27
Either< Void, T > NonEmpty(const T &t, auto &&msg, std::source_location loc=std::source_location::current())
Definition either.h:94
detail::EitherAwaiter< L, R, F > WithHandler(const Either< L, R > &either, F &&errorHandler)
Definition either.h:82
Definition constants.h:15
A proper void type, akin to unit (or ()) type in functional languages.
Definition void.h:21
bool await_ready() noexcept
Definition either.h:44
R await_resume() const noexcept
Definition either.h:73
decltype(Handler_(Either_.GetLeft())) HandlerReturn_t
Definition either.h:42
auto await_suspend(auto handle)
Definition either.h:60