/* Copyright(c) 2015 - 2019 Denis Blank Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ namespace cti { /** \page tutorial-awaiting-continuables Awaiting continuables \brief Explains how to use the \ref continuable_base together with `co_await`. \tableofcontents \section tutorial-awaiting-continuables-usage 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. \attention You have to enable this feature through defining the `CONTINUABLE_WITH_EXPERIMENTAL_COROUTINE` preprocessor definition. It is possible to await for any \ref continuable_base as shown below: \code{.cpp} int i = co_await cti::make_continuable([](auto&& promise) { promise.set_value(0); }); \endcode As described in \ref continuable_base::operator co_await() a continuable with multiple arguments as result will wrap its result into a `std::tuple`: \code{.cpp} std::tuple i = co_await cti::make_ready_continuable(0, 1); \endcode \section tutorial-awaiting-continuables-await Using co_await with exceptions When a \ref continuable_base was resolved through an exception the exception is rethrown from the `co_await` expression: \code{.cpp} try { auto response = co_await http_request("github.com"); } catch(std::exception const& e) { // Handle the exception } \endcode \section tutorial-awaiting-continuables-noexcept 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 type | co_await returns | | : ------------------------------- | : -------------------------------- | | `continuable_base with <>` | `unspecified` | | `continuable_base with ` | `unspecified` | | `continuable_base with ` | `unspecified>` | The interface of the proxy object is similar to the one proposed in the `std::expected` proposal: \code{.cpp} 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(); \endcode \section tutorial-awaiting-continuables-return Using continuables as return type from coroutines It is possible to use a \ref continuable_base as return type from coroutines. \code{.cpp} cti::continuable<> resolve_async_void() { co_await http_request("github.com"); // ... co_return; } cti::continuable resolve_async() { co_await http_request("github.com"); // ... co_return 0; } \endcode Additionally it's possible to return multiple return values from coroutines by wrapping those in a tuple like type: \code{.cpp} cti::continuable resolve_async_multiple() { co_await http_request("github.com"); // ... co_return std::make_tuple(0, 1, 2); } \endcode */ }