LeechCraft  0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
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 
15 namespace LC::Util::detail
16 {
18 }
19 
20 template<typename L, typename R, typename... Args>
21 struct 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  {
35  State State_;
36  promise_type& Promise_;
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 
69  struct promise_type
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 
94  Wrapper get_return_object ()
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>
106  struct SimpleAwaiter
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 };
auto Tup2 &&tup2 noexcept
Definition: ctstringutils.h:68
constexpr std::suspend_never final_suspend() const noexcept
Definition: eithercoro.h:72
constexpr std::suspend_never initial_suspend() const noexcept
Definition: eithercoro.h:71