LeechCraft
0.6.70-19214-g121e5318a7
Modular cross-platform feature rich live environment.
Toggle main menu visibility
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/logging.h
>
15
#include <
util/sll/void.h
>
16
#include "
task.h
"
17
18
namespace
LC::Util
19
{
20
struct
IgnoreLeft
{};
21
22
namespace
detail
23
{
24
template
<
typename
Promise>
25
[[noreturn]]
26
void
TerminateLeftyCoroutine
(std::coroutine_handle<Promise> handle,
const
auto
& error)
27
{
28
auto
& promise = handle.promise ();
29
if
constexpr
(Promise::IsVoid)
30
promise.return_void ();
31
else
32
promise.return_value (
Left
{ error });
33
34
throw
EitherFailureAbort
{};
35
}
36
37
template
<
typename
L,
typename
R,
typename
ErrorHandler>
38
struct
EitherAwaiter
39
{
40
Either<L, R>
Either_
;
41
ErrorHandler
Handler_
;
42
43
using
HandlerReturn_t
=
decltype
(
Handler_
(
Either_
.
GetLeft
()));
44
45
bool
await_ready
() noexcept
46
{
47
if
(
Either_
.
IsRight
())
48
return
true
;
49
50
if
constexpr
(std::is_same_v<IgnoreLeft, HandlerReturn_t>)
51
{
52
static_assert
(std::is_default_constructible_v<R>);
53
Handler_
(
Either_
.
GetLeft
());
54
Either_
= R {};
55
return
true
;
56
}
57
58
return
false
;
59
}
60
61
auto
await_suspend
(
auto
handle)
62
{
63
if
constexpr
(std::is_same_v<void, HandlerReturn_t>)
64
{
65
Handler_
(
Either_
.
GetLeft
());
66
TerminateLeftyCoroutine
(handle,
Either_
.
GetLeft
());
67
}
68
else
if
constexpr
(std::is_same_v<IgnoreLeft, HandlerReturn_t>)
69
qFatal () <<
"shall never suspend when ignoring left"
;
70
else
71
TerminateLeftyCoroutine
(handle,
Handler_
(
Either_
.
GetLeft
()));
72
}
73
74
R
await_resume
() const noexcept
75
{
76
return
Either_
.
GetRight
();
77
}
78
};
79
}
80
81
template
<
typename
L,
typename
R,
typename
F>
82
requires
std::invocable<F, const L&>
83
detail::EitherAwaiter<L, R, F>
WithHandler
(
const
Either<L, R>
& either, F&& errorHandler)
84
{
85
return
{ either, std::forward<F> (errorHandler) };
86
}
87
88
template
<
typename
L,
typename
R>
89
auto
WithHandler
(
const
Either<L, R>
& either,
IgnoreLeft
)
90
{
91
return
WithHandler
(either, [] (
const
auto
&) {
return
IgnoreLeft
{}; });
92
}
93
94
template
<
typename
T>
95
Either<Void, T>
NonEmpty
(
const
T& t,
auto
&& msg, std::source_location loc = std::source_location::current ())
96
{
97
if
(t)
98
return
t;
99
100
LogAt
(loc).warning () << msg;
101
return
{
AsLeft
,
Void
{} };
102
}
103
104
template
<
typename
T,
typename
... Msgs>
105
Either<Void, T>
NonEmpty
(
const
T& t,
const
std::tuple<Msgs...>& msgsTuple,
106
std::source_location loc = std::source_location::current ())
107
{
108
if
(t)
109
return
t;
110
111
std::apply ([&]<
typename
... AMsgs> (AMsgs&&... amsgs)
112
{
113
(
LogAt
(loc).warning () << ... << std::forward<AMsgs> (amsgs));
114
}, msgsTuple);
115
return
{
AsLeft
,
Void
{} };
116
}
117
118
template
<
typename
L,
typename
R>
119
detail::EitherAwaiter<L, R, std::identity>
GetAwaiter
(
const
Either<L, R>
& either,
AwaiterCPO
)
120
{
121
return
{ either, {} };
122
}
123
}
124
125
namespace
LC
126
{
127
template
<
typename
L,
typename
R>
128
auto
operator
co_await
(
const
Util::Either<L, R>
& either)
129
{
130
return
Util::GetAwaiter
(either, {});
131
}
132
}
LC::Util::Either
Definition
either.h:34
LC::Util::Either::GetLeft
const L & GetLeft() const
Definition
either.h:94
LC::Util::Either::IsRight
bool IsRight() const
Definition
either.h:89
LC::Util::Either::GetRight
const R & GetRight() const
Definition
either.h:108
logging.h
LC::Util::detail
Definition
fancytrayiconfreedesktop.cpp:24
LC::Util::detail::TerminateLeftyCoroutine
void TerminateLeftyCoroutine(std::coroutine_handle< Promise > handle, const auto &error)
Definition
either.h:26
LC::Util
Definition
icoreproxy.h:34
LC::Util::AsLeft
constexpr auto AsLeft
Definition
either.h:28
LC::Util::NonEmpty
Either< Void, T > NonEmpty(const T &t, auto &&msg, std::source_location loc=std::source_location::current())
Definition
either.h:95
LC::Util::LogAt
QMessageLogger LogAt(std::source_location loc)
Definition
logging.cpp:14
LC::Util::GetAwaiter
detail::EitherAwaiter< L, R, std::identity > GetAwaiter(const Either< L, R > &either, AwaiterCPO)
Definition
either.h:119
LC::Util::WithHandler
detail::EitherAwaiter< L, R, F > WithHandler(const Either< L, R > &either, F &&errorHandler)
Definition
either.h:83
LC
Definition
constants.h:15
either.h
LC::Util::AwaiterCPO
Definition
taskfwd.h:22
LC::Util::IgnoreLeft
Definition
either.h:20
LC::Util::Left
Definition
either.h:21
LC::Util::Void
A proper void type, akin to unit (or ()) type in functional languages.
Definition
void.h:21
LC::Util::detail::EitherAwaiter
Definition
either.h:39
LC::Util::detail::EitherAwaiter::await_ready
bool await_ready() noexcept
Definition
either.h:45
LC::Util::detail::EitherAwaiter::await_resume
R await_resume() const noexcept
Definition
either.h:74
LC::Util::detail::EitherAwaiter::HandlerReturn_t
decltype(Handler_(Either_.GetLeft())) HandlerReturn_t
Definition
either.h:43
LC::Util::detail::EitherAwaiter::await_suspend
auto await_suspend(auto handle)
Definition
either.h:61
LC::Util::detail::EitherAwaiter::Either_
Either< L, R > Either_
Definition
either.h:40
LC::Util::detail::EitherAwaiter::Handler_
ErrorHandler Handler_
Definition
either.h:41
LC::Util::detail::EitherFailureAbort
Definition
task.h:68
task.h
void.h
src
util
threads
coro
either.h
Generated by
1.18.0