Now yields a tuple<when_all_task<T>...> when awaited which allows
the caller to retrieve individual results by calling .result()
without needing to co_await again. This should allow usage of the
result in non-coroutine contexts.
Add generic implementation for use under Clang.
Use std::forward<> rather than static_cast<> to avoid warnings
about cast from lvalue to rvalue under MSVC in some cases.
- Change fmap, schedule_on, resume_on, make_shared_task work with
arbitrary awaitables.
- Add make_task to wrap an arbitrary awaitable in a task<T>.
- Remove specialisation of fmap() for task<T>, shared_task<T> as
the generalised version obsoletes it.
I was relying on coroutine_handle() default constructor initialising
the handle to nullptr in when_all_awaitable_counter constructor.
But this is not the case with the current MSVC implementation.
Now explicitly initialise handle to nullptr.
Now return prvalue rather than xvalue when co_awaiting a task<T>
rvalue when T is
This works around an issue with sync_wait() implementation under
MSVC that breaks for task<int>.
Clang was complaining about return-type of await_suspend()
when return-type is 'auto' and deduced to be 'bool',
saying that it must be 'bool' or 'void'.
- Added documentation to README
- Implemented fmap() for generator<T>, recursive_generator<T>,
shared_task<T>.
- Centralised operator| overloads for fmap() in fmap.hpp.
- Now provide two-argument fmap() overloads as the type-specific
implementations: fmap(func, value)
This replaces the need for detail::apply_fmap() functions.
The await_suspend() method of operator co_await() now returns bool
instead of void, to allow it to resume execution without suspending
if the task completes synchronously. However, this unfortunately
requires use of std::atomic operations to decide a potential race
between the awaiter suspending and the coroutine running to
completion.
This avoids a stack-overflow error when a coroutine awaits a
long sequence of task<T> values that complete synchronously.
eg. in a loop.
This typedef just makes available the template parameter of the
task type. This can be useful when writing generic functions that
need to operate on any of the task-types.
This allows registering continuations that are not coroutine
handles which can be useful for building some operators.
This comes at the expense of storage of an extra pointer per
coroutine and/or awaiter.
Adds the cppcoro::detail::resumer to wrap something that can
either be a callback + state or a coroutine_handle.
The promise_type::get_return_object() method was returning a reference
to the promise object, expecting that reference to be passed to the
constructor of recursive_generator<T>.
However, under Clang the result of get_return_object() is assigned to
an 'auto' variable, which ends up taking a copy of the promise object
on the stack and passing that copy into the recursive_generator<T>
constructor.
Modified get_return_object() to return the already-constructed
recursive_generator<T> object.
The io_service now launches a background thread on-demand for
keeping track of active timers. Background thread uses a waitable
timer event for performing timed waits and an auto-reset event
for signalling addition of new timers, timer cancellation and
thread shutdown.