mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
130 lines
4.2 KiB
Plaintext
130 lines
4.2 KiB
Plaintext
/*
|
|
Copyright(c) 2015 - 2018 Denis Blank <denis.blank at outlook dot com>
|
|
|
|
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<int>([](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<int, int> 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<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:
|
|
|
|
\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<int> 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<int, int, int> resolve_async_multiple() {
|
|
co_await http_request("github.com");
|
|
// ...
|
|
co_return std::make_tuple(0, 1, 2);
|
|
}
|
|
\endcode
|
|
|
|
*/
|
|
}
|