LeechCraft  0.6.70-16373-g319c272718
Modular cross-platform feature rich live environment.
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 <util/sll/either.h>
12 #include "task.h"
13 
14 namespace LC::Util
15 {
16  template<typename L, std::default_initializable R>
17  struct IgnoreLeft
18  {
20 
21  bool await_ready () const noexcept
22  {
23  return true;
24  }
25 
26  void await_suspend (auto) const noexcept
27  {
28  }
29 
31  {
32  return RightOr (Result_, R {});
33  }
34  };
35 
36  template<typename L, typename R>
37  IgnoreLeft (Either<L, R>) -> IgnoreLeft<L, R>;
38 
39  namespace detail
40  {
41  template<typename ErrorHandler>
43  {
44  ErrorHandler Handler_;
45 
46  template<typename L>
47  void HandleError (L&& left)
48  {
49  Handler_ (std::forward<L> (left));
50  }
51  };
52 
53  template<>
55  {
56  void HandleError (auto&&)
57  {
58  }
59  };
60 
61  template<typename L, typename R, typename ErrorHandler = void>
63  {
66 
67  bool await_ready () const noexcept
68  {
69  return Either_.IsRight ();
70  }
71 
72  template<typename Promise>
73  void await_suspend (std::coroutine_handle<Promise> handle)
74  {
75  Handler_.HandleError (Either_.GetLeft ());
76 
77  auto& promise = handle.promise ();
78  if constexpr (Promise::IsVoid)
79  promise.return_void ();
80  else
81  promise.return_value (Promise::ReturnType_t::Left (Either_.GetLeft ()));
82 
83  throw EitherFailureAbort {};
84  }
85 
87  {
88  return Either_.GetRight ();
89  }
90  };
91  }
92 
93  template<typename L, typename R, typename F>
94  requires std::invocable<F, const L&>
96  {
97  return { either, { std::forward<F> (errorHandler) } };
98  }
99 }
100 
101 namespace LC
102 {
103  template<typename L, typename R>
104  Util::detail::EitherAwaiter<L, R> operator co_await (const Util::Either<L, R>& either)
105  {
106  return { either };
107  }
108 }
requires std::invocable< F, const L & > Util::detail::EitherAwaiter< L, R, F > WithHandler(const Util::Either< L, R > &either, F &&errorHandler)
Definition: either.h:95
Either< L, R > Either_
Definition: either.h:64
Either< L, R > Result_
Definition: either.h:19
void await_suspend(std::coroutine_handle< Promise > handle)
Definition: either.h:73
void await_suspend(auto) const noexcept
Definition: either.h:26
R await_resume() const noexcept
Definition: either.h:30
requires(Tup1Size==Tup2Size) const expr auto ZipWith(Tup1 &&tup1
EitherAwaiterErrorHandler< ErrorHandler > Handler_
Definition: either.h:65
bool await_ready() const noexcept
Definition: either.h:21
auto Tup2 &&tup2 noexcept
Definition: ctstringutils.h:41
IgnoreLeft(Either< L, R >) -> IgnoreLeft< L, R >
bool await_ready() const noexcept
Definition: either.h:67
R await_resume() const noexcept
Definition: either.h:86
R RightOr(const Either< L, R > &either, F &&f)
Definition: either.h:186