LeechCraft 0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
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
15namespace 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
77namespace 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}
auto MetaMethod(Ctx &ctx, F &&method, Args &&... args)
Definition metamethod.h:80
static constexpr bool IsVoid
Definition metamethod.h:25
bool await_ready() const noexcept
Definition metamethod.h:33
std::invoke_result_t< std::decay_t< F >, Ctx &, std::decay_t< Args >... > R
Definition metamethod.h:24
void await_suspend(std::coroutine_handle<> handle) noexcept
Definition metamethod.h:38
std::tuple< Ctx &, std::decay_t< Args >... > Args_
Definition metamethod.h:22
std::conditional_t< IsVoid, Void, std::optional< R > > Result_
Definition metamethod.h:27
std::exception_ptr Exception_
Definition metamethod.h:29