Changelog
A description of the changes made to continuable.
Versions
Following versions were released:
4.0.0
Various issues have been resolved:
- #27: First class, zero-overhead ASIO integration
- #23: VS 16.2: parameter pack must be expanded in this context
- #21: Infinite recursion during compilation
- #16: Add AppleClang compiler to cmake
- #13: unit-test/test-continuable-single fails on gcc 8.2
- #11: Forward declarations are no longer allowed in type-erased continuables
Following methods and functions have been added:
Various improvements to continuable_
- continuable_base::
as for casting to a continuable_ base with different arguments - continuable_base::
finish for 'materializing' an intermediate chained continuable_ base
An asychronous initiation function comparable to std::async:
The asynchronous facilities make it possible now to start with a handler instead of a continuation:
async([] { // ... }).then(...);
- async Makes it possible to start with a handler instead of a continuation, comparable to
std::async
- async_
on allows to specify an additional executor parameter
The result class and modifying the asynchronous control flow
Every continuation handler used in continuable_base::
This allows recovering from failures or throwing of exception types from handlers when exceptions are disabled.
Result handling and
- result
- rethrow Throws an exception or error code from a result or failure handler
- cancel Throws a default constructed exception type or error code from a result or failure handler to signal cancellation.
- stop Can be used to stop an asynchronous continuation chain, no handler which comes after stop was received won't be called.
- make_
result Creates a present result from the given values.
Special result types
- empty_
result A class which is convertible to any result and that definitely holds no value so the real result gets invalidated when this object is passed to it. - cancellation_
result A class which is convertible to any result and that definitely holds a default constructed exception which signals the cancellation of the asynchronous control flow. - exceptional_
result A class which is convertible to any result and that holds an exception which is then passed to the converted result object.
Optimize 'ready' continuables:
Continuables which are 'ready' and side effect free can now be unpacked synchronously. Mainly such continuables are created through make_
- continuable_base::
is_ready Returns true when the continuable can provide its result immediately, and its lazy invocation would be side-effect free. - continuable_base::
unpack Invalidates the continuable and returns its immediate invocation result. - make_
cancelling_ continuable Returns a continuable_ base with the parameterized result which never resolves its promise and thus cancels the asynchronous continuation chain through throwing a default constructed exception_t.
Including various helper tags for the underlying changed continuation object structure:
asio asynchronous initiate token:
The use_
- use_
continuable Type used as an ASIO completion token to specify an asynchronous operation that should return a continuable_ base.
#include <continuable/continuable.hpp> #include <continuable/external/asio.hpp> #include <asio.hpp> // ... asio::tcp::resolver resolver(...); resolver.async_resolve("127.0.0.1", "daytime", cti::use_continuable) .then([](asio::udp::resolver::iterator iterator) { // ... });
Iterating over an asynchronous control flow:
The loop function was added which makes is possible to emulate an asynchronous loop, that is comparable to a co_await
with for
.
- loop
- loop_
result Can be used to indicate a specific result inside an asynchronous loop. - loop_
break Can be used to create a loop_result which causes the loop to be cancelled and resolved with the given arguments. - loop_
continue Can be used to create a loop_result which causes the loop to be repeated. - range_
loop Can be used to create an asynchronous loop over a specific range. - range_
loop Can be used to create an asynchronous loop over a specific range. - plain_
t Represents the type that is used to disable the special meaning of types which are returned by a asynchronous result handler. See cti::plain for details. - make_
plain Can be used to disable the special meaning for a returned value in asynchronous handler functions.
Synchronous wait transforms:
The wait transforms allows to block the current thread until a continuable_
- transforms::
wait Returns a transform that if applied to a continuable, it will start the continuation chain and returns the result synchronously. The current thread is blocked until the continuation chain is finished. - transforms::
wait_for Same as transforms:: wait wich waits for a given duration - transforms::
wait_until Same as transforms:: wait wich waits until a given timepoint
Various changes:
Many more unlisted changes including:
- work Defines a non-copyable type erasure which is capable of carrying callable objects passed to executors.
- continuation_
capacity - promisify::
with - void_
arg_ t
Additional various bugfixes have been made.
3.0.0
New helper functions
New helper functions were added to create ready continuables:
- make_
ready_ continuable Returns a continuable_ base with no result which instantly resolves the promise with no values. - make_
exceptional_ continuable Returns a continuable_ base with the parameterized result which instantly resolves the promise with the given error type.
Improvements to connections
The implementation of connections were rewritten entirely. It is possible now to connect runtime sized containers as well as deeply nested sequences. See Connecting continuables for details.
Additionally connection overloads were added that accept two iterators in order to come closer to the interface of the standard library.
Also populate was added which makes it possible to populate a dynamic container from continuable_
Disabled copies for promises and continuables entirely
The promise_
Traversal API
A new traversal API for synchronous and asynchronous pack traversal was added which makes it easy to specify new connection types.
2.0.0
Error handling
Usually it is inconvenient to handle error codes and exceptions in an asynchronous context, as we all know std::future
supports error handling through exceptions already. We now introduce this capability to the continuable library while allowing error codes to be used as well.
Consider the function cti::
which always resolves through an error, then you may handle the error code or exception as following:
get_bad_continuable() .then([] { // ... never invoked }) .then([] { // ... never invoked as well }) .fail([] (std::exception_ptr e) { try { std::rethrow_exception(e); } catch(std::exception const& e) { // Handle the exception here } });
Abstracting callbacks as promises
Since a callback may be called through an error or result the cri::promise class was added in order ro provide a similar interface to std::promise:
auto http_request(std::string url) { return cti::make_continuable<std::string>( [url = std::move(url)](cti::promise<std::string> promise) { // Perform the actual request through a different library, // resolve the promise upon completion of the task. promise.set_value("<html> ... </html>"); // ...or promise.set_exception(...); }); }
co_await
support
Experimental coroutine (co_await
and co_return
) support was added, this is available on MSVC 2017 and Clang 5.0.
int i = co_await cti::make_continuable<int>([](auto&& promise) { promise.set_value(0); });
Minor improvements
The library was improved in other ways:
constexpr
andnoexcept
improvements- Compile-time improvements
- Documentation improvements
Header split
Since the overall library size was increased the headers were split into smaller chunks.
1.0.0
- Documentation and readme changes
- Change the assertion type of some GTest macros from expected to assertion.
0.8.0 (unstable)
- Fixes a major issue with handling the ownership for consumed continuables which led to unintended invocations.
Adds partial application support which makes it possible to chain callbacks which accept less arguments then the curret signature.
http_request("github.com") .then([] { // ... });
Adds Support for sequential invocation:
http_request("github.com") >> http_request("atom.io") .then([] (std::string github, std::string atom) { // ... });
0.7.0 (unstable)
- Continuation syntactic sugar
- Executor support
- Connection support
Semantic versioning and stability
Continuable strictly follows the rules of semantic versioning, the API is kept stable across minor versions.
The CI driven unit-tests are observed through the Clang sanitizers (asan, ubsan and lsan - when compiling with Clang) or Valgrind (when compiling with GCC) in order to prevent regressions.