LeechCraft
0.6.70-18450-gabe19ee3b0
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/void.h
>
15
#include "
task.h
"
16
17
namespace
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>
37
struct
EitherAwaiter
38
{
39
Either<L, R>
Either_
;
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&>
82
detail::EitherAwaiter<L, R, F>
WithHandler
(
const
Either<L, R>
& either, F&& errorHandler)
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
119
namespace
LC
120
{
121
template
<
typename
L,
typename
R>
122
Util::detail::EitherAwaiter<L, R, std::identity>
operator
co_await
(
const
Util::Either<L, R>
& either)
123
{
124
return
{ either, {} };
125
}
126
}
LC::Util::Either
Definition
either.h:33
LC::Util::detail
Definition
fancytrayiconfreedesktop.cpp:24
LC::Util::detail::TerminateLeftyCoroutine
void TerminateLeftyCoroutine(std::coroutine_handle< Promise > handle, const auto &error)
Definition
either.h:25
LC::Util
Definition
icoreproxy.h:34
LC::Util::AsLeft
constexpr auto AsLeft
Definition
either.h:27
LC::Util::NonEmpty
Either< Void, T > NonEmpty(const T &t, auto &&msg, std::source_location loc=std::source_location::current())
Definition
either.h:94
LC::Util::WithHandler
detail::EitherAwaiter< L, R, F > WithHandler(const Either< L, R > &either, F &&errorHandler)
Definition
either.h:82
LC
Definition
constants.h:15
either.h
LC::Util::IgnoreLeft
Definition
either.h:19
LC::Util::Left
Definition
either.h:20
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:38
LC::Util::detail::EitherAwaiter::await_ready
bool await_ready() noexcept
Definition
either.h:44
LC::Util::detail::EitherAwaiter::await_resume
R await_resume() const noexcept
Definition
either.h:73
LC::Util::detail::EitherAwaiter::HandlerReturn_t
decltype(Handler_(Either_.GetLeft())) HandlerReturn_t
Definition
either.h:42
LC::Util::detail::EitherAwaiter::await_suspend
auto await_suspend(auto handle)
Definition
either.h:60
LC::Util::detail::EitherAwaiter::Either_
Either< L, R > Either_
Definition
either.h:39
LC::Util::detail::EitherAwaiter::Handler_
ErrorHandler Handler_
Definition
either.h:40
LC::Util::detail::EitherFailureAbort
Definition
task.h:60
task.h
void.h
src
util
threads
coro
either.h
Generated by
1.17.0