Created
November 18, 2021 16:51
-
-
Save sylveon/8e5c56c12c83f490884430bccc9fd23c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Module; | |
#include <coroutine> | |
#include <iostream> | |
struct fire_and_forget {}; | |
template <typename... Args> | |
struct std::coroutine_traits<fire_and_forget, Args...> | |
{ | |
struct promise_type | |
{ | |
fire_and_forget get_return_object() const noexcept | |
{ | |
return{}; | |
} | |
void return_void() const noexcept | |
{ | |
} | |
suspend_never initial_suspend() const noexcept | |
{ | |
return{}; | |
} | |
suspend_never final_suspend() const noexcept | |
{ | |
return{}; | |
} | |
void unhandled_exception() const noexcept | |
{ | |
std::terminate(); | |
} | |
}; | |
}; | |
fire_and_forget test() | |
{ | |
winrt::Windows::Foundation::IAsyncAction a; | |
co_await a; | |
} | |
int main() | |
{ | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module; | |
#include <atomic> | |
#include <coroutine> | |
#include <utility> | |
export module Module; | |
namespace winrt::impl | |
{ | |
inline std::pair<int32_t, int32_t> get_apartment_type() noexcept | |
{ | |
return { 1 /* APTTYPE_MTA */, 1 /* APTTYPEQUALIFIER_IMPLICIT_MTA */ }; | |
} | |
template<typename Awaiter> | |
struct disconnect_aware_handler | |
{ | |
disconnect_aware_handler(Awaiter* awaiter, std::coroutine_handle<> handle) noexcept | |
: m_awaiter(awaiter), m_handle(handle) { } | |
private: | |
int32_t m_context_type = get_apartment_type().first; | |
Awaiter* m_awaiter; | |
std::coroutine_handle<> m_handle; | |
}; | |
template <typename Async> | |
struct await_adapter | |
{ | |
await_adapter(Async const& async) : async(async) { } | |
Async const& async; | |
int32_t failure = 0; | |
std::atomic<bool> suspending{ true }; | |
bool await_ready() const noexcept | |
{ | |
return false; | |
} | |
auto await_suspend(std::coroutine_handle<> handle) | |
{ | |
auto extend_lifetime = async; | |
async.Completed(disconnect_aware_handler(this, handle)); | |
return suspending.exchange(false, std::memory_order_acquire); | |
} | |
auto await_resume() const | |
{ | |
return async.GetResults(); | |
} | |
}; | |
} | |
export namespace winrt::Windows::Foundation | |
{ | |
struct IAsyncAction | |
{ | |
template <typename T> void Completed(T foo) const {} | |
int GetResults() const { return 10; } | |
}; | |
inline impl::await_adapter<IAsyncAction> operator co_await(IAsyncAction const& async) | |
{ | |
return{ async }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment