LeechCraft 0.6.70-19214-g121e5318a7
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/logging.h>
15#include <util/sll/void.h>
16#include "task.h"
17
18namespace 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>
39 {
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>);
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 {
67 }
68 else if constexpr (std::is_same_v<IgnoreLeft, HandlerReturn_t>)
69 qFatal () << "shall never suspend when ignoring left";
70 else
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&>
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>
120 {
121 return { either, {} };
122 }
123}
124
125namespace 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}
const L & GetLeft() const
Definition either.h:94
bool IsRight() const
Definition either.h:89
const R & GetRight() const
Definition either.h:108
void TerminateLeftyCoroutine(std::coroutine_handle< Promise > handle, const auto &error)
Definition either.h:26
constexpr auto AsLeft
Definition either.h:28
Either< Void, T > NonEmpty(const T &t, auto &&msg, std::source_location loc=std::source_location::current())
Definition either.h:95
QMessageLogger LogAt(std::source_location loc)
Definition logging.cpp:14
detail::EitherAwaiter< L, R, std::identity > GetAwaiter(const Either< L, R > &either, AwaiterCPO)
Definition either.h:119
detail::EitherAwaiter< L, R, F > WithHandler(const Either< L, R > &either, F &&errorHandler)
Definition either.h:83
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:45
R await_resume() const noexcept
Definition either.h:74
decltype(Handler_(Either_.GetLeft())) HandlerReturn_t
Definition either.h:43
auto await_suspend(auto handle)
Definition either.h:61