Tutorial » Awaiting continuables

Explains how to use the continuable_base together with co_await.

Using co_await on continuables

Coroutines (co_await) are supported by continuables when the underlying toolchain supports the TS. Currently this works in MSVC 2017 and Clang 5.0.

It is possible to await for any continuable_base as shown below:

int i = co_await cti::make_continuable<int>([](auto&& promise) {
  promise.set_value(0);
});

As described in continuable_base::operator co_await() a continuable with multiple arguments as result will wrap its result into a std::tuple:

std::tuple<int, int> i = co_await cti::make_ready_continuable(0, 1);

Using co_await with exceptions

When a continuable_base was resolved through an exception the exception is rethrown from the co_await expression:

try {
  auto response = co_await http_request("github.com");
} catch(std::exception const& e) {
  // Handle the exception
}

Using co_await with disabled exceptions

In case the library is configured to use error codes or a custom error type the return type of the co_await expression is changed.

The result is returned through an internal proxy object which may be queried for the error object:

Continuation typeco_await returns
continuable_base with <>unspecified<void>
continuable_base with <Arg>unspecified<Arg>
continuable_base with <Args...>unspecified<std::tuple<Args...>>

The interface of the proxy object is similar to the one proposed in the std::expected proposal:

if (auto&& result = co_await http_request("github.com")) {
  auto value = *result;
} else {
  cti::error_type error = result.get_exception();
}

auto result = co_await http_request("github.com");

bool(result);
result.is_value();
result.is_exception();
*result; // Same as result.get_value()
result.get_value();
result.get_exception();

Using continuables as return type from coroutines

It is possible to use a continuable_base as return type from coroutines.

cti::continuable<> resolve_async_void() {
  co_await http_request("github.com");
  // ...
  co_return;
}

cti::continuable<int> resolve_async() {
  co_await http_request("github.com");
  // ...
  co_return 0;
}

Additionally it's possible to return multiple return values from coroutines by wrapping those in a tuple like type:

cti::continuable<int, int, int> resolve_async_multiple() {
  co_await http_request("github.com");
  // ...
  co_return std::make_tuple(0, 1, 2);
}