LeechCraft 0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
eithercoro.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 <coroutine>
12#include <util/sll/either.h>
13#include "either.h"
14
15namespace LC::Util::detail
16{
18}
19
20template<typename L, typename R, typename... Args>
21struct std::coroutine_traits<LC::Util::Either<L, R>, Args...>
22{
24
25 struct State
26 {
27 std::optional<EitherType> Ret_ {};
28 std::exception_ptr Exc_ {};
29 };
30
31 struct promise_type;
32
33 struct Wrapper
34 {
37
38 explicit Wrapper (promise_type& promise)
39 : Promise_ { promise }
40 {
41 promise.Wrapper_ = this;
42 }
43
44 Wrapper (Wrapper&& other) noexcept
45 : State_ { std::move (other.State_) }
46 , Promise_ { other.Promise_ }
47 {
48 Promise_.Wrapper_ = this;
49 }
50
51 Wrapper (const Wrapper&) = delete;
52 Wrapper& operator= (const Wrapper&) = delete;
53 Wrapper& operator= (Wrapper&&) = delete;
54
55 explicit (false) operator EitherType ()
56 {
57 if (State_.Exc_)
58 {
59 try
60 {
61 std::rethrow_exception (State_.Exc_);
62 }
64 }
65 return std::move (*State_.Ret_);
66 }
67 };
68
70 {
71 constexpr std::suspend_never initial_suspend () const noexcept { return {}; }
72 constexpr std::suspend_never final_suspend () const noexcept { return {}; }
73
74 constexpr static bool IsVoid = false;
75
76 Wrapper *Wrapper_ = nullptr;
77
78 template<typename U = R>
79 void return_value (U&& val)
80 {
81 Wrapper_->State_.Ret_.emplace (std::forward<U> (val));
82 }
83
85 {
86 Wrapper_->State_.Ret_.emplace (std::move (val));
87 }
88
90 {
91 Wrapper_->State_.Exc_ = std::current_exception ();
92 }
93
95 {
96 return Wrapper { *this };
97 }
98
99 template<typename T>
100 auto await_transform (T&& either) const
101 {
102 return SimpleAwaiter<T> { std::forward<T> (either) };
103 }
104
105 template<typename T>
107 {
109
110 constexpr static auto IsOwning = !std::is_lvalue_reference_v<T>;
111 using R_t = std::decay_t<T>::R_t;
112
113 bool await_ready () const noexcept
114 {
115 return Either_.IsRight ();
116 }
117
118 [[noreturn]]
119 void await_suspend (std::coroutine_handle<promise_type> handle)
120 {
121 handle.promise ().Wrapper_->State_.Ret_.emplace (std::forward_like<T> (Either_.GetLeft ()));
123 }
124
125 std::conditional_t<IsOwning, R_t, const R_t&> await_resume ()
126 {
127 return std::forward_like<T> (Either_.GetRight ());
128 }
129 };
130 };
131};
Definition constants.h:15
constexpr std::suspend_never final_suspend() const noexcept
Definition eithercoro.h:72
constexpr std::suspend_never initial_suspend() const noexcept
Definition eithercoro.h:71