Skip to content

Instantly share code, notes, and snippets.

@sylveon
Created November 18, 2021 16:51
Show Gist options
  • Save sylveon/8e5c56c12c83f490884430bccc9fd23c to your computer and use it in GitHub Desktop.
Save sylveon/8e5c56c12c83f490884430bccc9fd23c to your computer and use it in GitHub Desktop.
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()
{
}
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