blob: 6cdf8d1e529e5c7b22c4d157f1955ab06bf9eab3 [file] [log] [blame]
#ifdef __clang__
#include <experimental/coroutine>
namespace std {
using namespace std::experimental;
}
#else
#include <coroutine>
#endif
#include <cstdio>
#include <typeinfo>
#include <cxxabi.h> // needed for abi::__cxa_demangle
#include <memory>
std::shared_ptr<char> cppDemangle(const char *abiName)
{
int status;
char *ret = abi::__cxa_demangle(abiName, 0, 0, &status);
/* NOTE: must free() the returned char when done with it! */
std::shared_ptr<char> retval;
retval.reset( (char *)ret, [](char *mem) { if (mem) free((void*)mem); } );
return retval;
}
template <typename T>
struct Id{};
struct Task
{
struct promise_type
{
void return_void() const noexcept {}
static void is_int (std::string x) {
if (x != "Id<int>")
abort() ;
}
template <typename ... Args>
void* operator new(std::size_t len, Args ...args) noexcept
{
(is_int (cppDemangle(typeid(Id<Args>).name()).get()), ...);
(std::puts (cppDemangle(typeid(Id<Args>).name()).get()), ...);
return nullptr;
}
static Task get_return_object_on_allocation_failure() noexcept
{
return {};
}
Task get_return_object() noexcept
{
return Task{ *this };
}
std::suspend_always initial_suspend() noexcept
{
return {};
}
std::suspend_always final_suspend() noexcept
{
return {};
}
void unhandled_exception() noexcept {}
};
using promise_handle = std::coroutine_handle<promise_type>;
Task() = default;
Task(promise_type & promise) noexcept
: m_handle{ promise_handle::from_promise(promise) }
{}
~Task()
{
if (m_handle.address()) { m_handle.destroy(); }
}
promise_handle m_handle{};
};
Task Foo(auto && ... args) noexcept
{
co_return;
}
int main()
{
int v;
Foo(v, 2134);
}