LeechCraft  0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
metamethod.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 <QMetaObject>
13 #include <util/sll/void.h>
14 
15 namespace LC::Util::detail
16 {
17  template<typename Ctx, typename F, typename... Args>
19  {
20  Ctx& Ctx_;
21  std::decay_t<F> Method_;
22  std::tuple<Ctx&, std::decay_t<Args>...> Args_;
23 
24  using R = std::invoke_result_t<std::decay_t<F>, Ctx&, std::decay_t<Args>...>;
25  constexpr static bool IsVoid = std::is_same_v<R, void>;
26 
27  std::conditional_t<IsVoid, Void, std::optional<R>> Result_ {};
28 
29  std::exception_ptr Exception_ {};
30 
31  std::atomic_bool Ready_ { false };
32 
33  bool await_ready () const noexcept
34  {
35  return false;
36  }
37 
38  void await_suspend (std::coroutine_handle<> handle) noexcept
39  {
40  const auto thread = QThread::currentThread ();
41  QMetaObject::invokeMethod (&Ctx_,
42  [=, this]
43  {
44  try
45  {
46  if constexpr (IsVoid)
47  std::apply (Method_, Args_);
48  else
49  Result_ = std::apply (Method_, Args_);
50  }
51  catch (...)
52  {
53  Exception_ = std::current_exception ();
54  }
55 
56  Ready_.store (true, std::memory_order_release);
57 
58  QMetaObject::invokeMethod (thread, handle, Qt::QueuedConnection);
59  },
60  Qt::QueuedConnection);
61  }
62 
63  R await_resume () const
64  {
65  while (!Ready_.load (std::memory_order_acquire))
66  ;
67 
68  if (Exception_)
69  std::rethrow_exception (Exception_);
70 
71  if constexpr (!IsVoid)
72  return *Result_;
73  }
74  };
75 }
76 
77 namespace LC::Util
78 {
79  template<typename Ctx, typename F, typename... Args>
80  auto MetaMethod (Ctx& ctx, F&& method, Args&&... args)
81  {
82  return detail::MethodAwaiter<Ctx, F, Args...> { ctx, std::forward<F> (method), { ctx, std::forward<Args> (args)... } };
83  }
84 }
std::decay_t< F > Method_
Definition: metamethod.h:21
auto MetaMethod(Ctx &ctx, F &&method, Args &&... args)
Definition: metamethod.h:80
void await_suspend(std::coroutine_handle<> handle) noexcept
Definition: metamethod.h:38
std::invoke_result_t< std::decay_t< F >, Ctx &, std::decay_t< Args >... > R
Definition: metamethod.h:24
std::conditional_t< IsVoid, Void, std::optional< R > > Result_
Definition: metamethod.h:27
std::exception_ptr Exception_
Definition: metamethod.h:29
auto Tup2 &&tup2 noexcept
Definition: ctstringutils.h:68
bool await_ready() const noexcept
Definition: metamethod.h:33
std::tuple< Ctx &, std::decay_t< Args >... > Args_
Definition: metamethod.h:22
static constexpr bool IsVoid
Definition: metamethod.h:25