mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
More work on the documentation
This commit is contained in:
parent
60f40415c3
commit
d7c305ad33
@ -49,7 +49,7 @@ namespace cti {
|
||||
\section mainpage-getting-started Getting started
|
||||
|
||||
Continuable is a header-only library with zero compilation dependencies.
|
||||
The \ref installation is explained in its own chapter.
|
||||
The \ref installation and \ref configuration are explained in its own chapter.
|
||||
|
||||
The \ref tutorial is everything you need in order to get to know the libraries
|
||||
API. Beside of this, there is a detailed in-source documentation provided.
|
||||
@ -87,7 +87,7 @@ Continuable is licensed under the MIT license:
|
||||
>
|
||||
> 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
|
||||
> 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
|
||||
|
||||
@ -26,5 +26,76 @@ namespace cti {
|
||||
|
||||
\tableofcontents
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### How-to use
|
||||
|
||||
As mentioned earlier the library is header-only. There is a cmake project provided for simple setup:
|
||||
|
||||
#### As git submodule
|
||||
|
||||
\endcodesh
|
||||
# Shell:
|
||||
git submodule add https://github.com/Naios/continuable.git
|
||||
\endcode
|
||||
|
||||
\endcodecmake
|
||||
# CMake file:
|
||||
add_subdirectory(continuable)
|
||||
# continuable provides an interface target which makes it's
|
||||
# headers available to all projects using the continuable library.
|
||||
target_link_libraries(my_project continuable)
|
||||
\endcode
|
||||
|
||||
On POSIX platforms you are required to link your application against a corresponding thread library, otherwise `std::future's` won't work properly, this is done automatically by the provided CMake project.
|
||||
|
||||
#### As CMake library
|
||||
|
||||
Additionally the project exports a `continuable` target which is importable through CMake when installed:
|
||||
|
||||
\endcodesh
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --target INSTALL --config Release
|
||||
\endcode
|
||||
|
||||
`CMakeLists.txt`:
|
||||
|
||||
\endcodecmake
|
||||
find_package(continuable REQUIRED)
|
||||
\endcode
|
||||
|
||||
### Building the unit-tests
|
||||
|
||||
In order to build the unit tests clone the repository recursively with all submodules:
|
||||
|
||||
\endcodesh
|
||||
# Shell:
|
||||
git clone --recursive https://github.com/Naios/continuable.git
|
||||
\endcode
|
||||
## Stability and version
|
||||
|
||||
The library follows the rules of [semantic versioning](http://semver.org/), 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).
|
||||
|
||||
|
||||
## Compatibility
|
||||
|
||||
Tested & compatible with:
|
||||
|
||||
- Visual Studio 2017+ Update 2
|
||||
- Clang 5.0+
|
||||
- GCC 6.0+
|
||||
|
||||
Although the build is observed with the latest toolchains earlier ones might work.
|
||||
|
||||
The library only depends on the standard library when using the `continuable/continuable-base.hpp` header, which provides the basic continuation logic.
|
||||
|
||||
> **Note:** On Posix: don't forget to **link a corresponding thread library** into your application otherwise `std::future's` won't work `(-pthread)` when using future based transforms.
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
41
doc/tutorial-awaiting-continuables.dox
Normal file
41
doc/tutorial-awaiting-continuables.dox
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
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
|
||||
|
||||
### Coroutines
|
||||
|
||||
Since version 2.0.0 coroutines (`co_await` and `co_return`) are supported by continuables when the underlying toolchain supports the TS. Currently this works in MSVC 2017 and Clang 5.0.
|
||||
You have to enable this capability through the `CTI_CONTINUABLE_WITH_AWAIT` define in CMake.
|
||||
|
||||
\endcodec++
|
||||
int i = co_await cti::make_continuable<int>([](auto&& promise) {
|
||||
promise.set_value(0);
|
||||
});
|
||||
\endcode
|
||||
|
||||
*/
|
||||
}
|
||||
@ -69,6 +69,59 @@ mysql_query("SELECT `id`, `name` FROM `users`")
|
||||
});
|
||||
\endcode
|
||||
|
||||
\subsection tutorial-chaining-continuables-then-partial Making use of partial argument application
|
||||
|
||||
Callbacks passed to \link continuable_base::then then \endlink are only called
|
||||
with the amount of arguments that are accepted.
|
||||
|
||||
\code{.cpp}
|
||||
(http_request("github.com") && read_file("entries.csv"))
|
||||
.then([] {
|
||||
// ^^^^^^ The original signature was <std::string, Buffer>,
|
||||
// however, the callback is only invoked with the amount of
|
||||
// arguments it's accepting.
|
||||
});
|
||||
\endcode
|
||||
|
||||
This makes it possible to attach a callback accepting nothing to every
|
||||
\ref continuable_base.
|
||||
|
||||
\subsection tutorial-chaining-continuables-then-executors Assigning a specific executor to then
|
||||
|
||||
Dispatching a callback through a specific executor is a common usage scenario and supported through the second argument of \link continuable_base::then then\endlink:
|
||||
|
||||
\code{.cpp}
|
||||
auto executor = [](auto&& work) {
|
||||
// Dispatch the work here, store it for later
|
||||
// invocation or move it to another thread.
|
||||
std::forward<decltype(work)>(work)();
|
||||
};
|
||||
|
||||
read_file("entries.csv")
|
||||
.then([](Buffer buffer) {
|
||||
// ...
|
||||
}, executor);
|
||||
// ^^^^^^^^
|
||||
\endcode
|
||||
|
||||
The supplied `work` callable may be stored and moved for later usage
|
||||
on a possible different thread or execution context.
|
||||
|
||||
\note If you are intending to change the context the asynchronous task is
|
||||
running, you need to specify this inside the function that
|
||||
supplies the \ref continuable_base through moving the \ref promise_base.
|
||||
\code{.cpp}
|
||||
auto http_request(std::string url) {
|
||||
return cti::make_continuable<std::string>(
|
||||
[url = std::move(url)](auto&& promise) {
|
||||
std::async([promise = std::forward<decltype(promise)>(promise)]
|
||||
() mutable {
|
||||
promise.set_value("<html> ... </html>");
|
||||
});
|
||||
});
|
||||
}
|
||||
\endcode
|
||||
|
||||
\section tutorial-chaining-continuables-fail Using fail and exceptions
|
||||
|
||||
Asynchronous exceptions are supported too. Exceptions that were set through
|
||||
|
||||
74
doc/tutorial-promisify-continuables.dox
Normal file
74
doc/tutorial-promisify-continuables.dox
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
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-promisify-continuables Promisify functions
|
||||
\brief Explains how to promisify callback taking functions into a \ref continuable_base.
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\section tutorial-promisify-continuables-promisify Promisification and continuables
|
||||
|
||||
The promisification has a longer history in the JavaScript world where
|
||||
the legacy way of asynchronous programming was the usage of callbacks of the
|
||||
form \code{.js}function(error, result...)\endcode. The ideal way of dealing
|
||||
with such an asynchronous result is to return a promise and soon utility
|
||||
helpers were provided to do so.
|
||||
|
||||
The usage of callbacks to represent an asynchronous result is still a popular
|
||||
way nowadays. Thus the library provides the \ref promisify helper class
|
||||
which makes it possible to convert callback taking functions of various styles
|
||||
into one that returns a \ref continuable_base instead.
|
||||
|
||||
\note Providing promisified APIs for other popular libraries is out of
|
||||
scope for this library. However contributions are highly welcome to
|
||||
add more conversion helpers for other commonly used callback styles.
|
||||
|
||||
\section tutorial-promisify-continuables-boost Promisify boost::asio
|
||||
|
||||
The default callback style is something like
|
||||
\code{.js}function(error, result...)\endcode as described above.
|
||||
Continuable offers the \ref promisify::from method for such callback styles.
|
||||
|
||||
See an example of how to promisify boost asio's `async_resolve` below:
|
||||
|
||||
\code{.cpp}
|
||||
auto async_resolve(std::string host, std::string service) {
|
||||
return cti::promisify<asio::ip::udp::resolver::iterator>::from(
|
||||
[&](auto&&... args) {
|
||||
resolver_.async_resolve(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
std::move(host), std::move(service));
|
||||
}
|
||||
\endcode
|
||||
|
||||
Then it should be possible to use `asio::async_resolve` like this:
|
||||
|
||||
\code{.cpp}
|
||||
async_resolve("127.0.0.1", "daytime")
|
||||
.then([](udp::resolver::iterator iterator) {
|
||||
// ...
|
||||
});
|
||||
\endcode
|
||||
|
||||
*/
|
||||
}
|
||||
75
doc/tutorial-transforming-continuables.dox
Normal file
75
doc/tutorial-transforming-continuables.dox
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
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-transforming-continuables Transforming continuables
|
||||
\brief Explains the conversion into other types such as `std::future`.
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\section tutorial-transforming-continuables-transforms Transforms in general
|
||||
|
||||
Sometimes it's required to change a \ref continuable_base object by its whole.
|
||||
Thus the library offers the ability to apply a transformation to any
|
||||
\ref continuable_base through using \link continuable_base::apply apply \endlink
|
||||
or \link continuable_base::operator | its operator | \endlink.
|
||||
|
||||
A transformation accepts a \ref continuable_base and returns
|
||||
an arbitrary object.
|
||||
|
||||
To create a transformation use the \ref make_transform function:
|
||||
|
||||
\code{.cpp}
|
||||
auto transform = cti::make_transform([] (auto&& continuable) {
|
||||
// Change the continuable
|
||||
return std::forward<decltype(continuable)>(continuable);
|
||||
});
|
||||
\endcode
|
||||
|
||||
The library provides several transforms already as part of the
|
||||
\ref cti::transforms namespace.
|
||||
|
||||
\section tutorial-transforming-continuables-future Conversion into std::future
|
||||
|
||||
The library is capable of converting (*futurizing*) every continuable into a
|
||||
fitting `std::future` through the \ref transforms::futurize transform:
|
||||
|
||||
\code{.cpp}
|
||||
std::future<std::string> future = http_request("github.com")
|
||||
.then([](std::string response) {
|
||||
// Do sth...
|
||||
return http_request("travis-ci.org") || http_request("atom.io");
|
||||
})
|
||||
.apply(cti::transforms::futurize());
|
||||
// ^^^^^^^^
|
||||
\endcode
|
||||
|
||||
Multiple arguments which can't be handled by `std::future` itself are
|
||||
converted into `std::tuple`, see \ref transforms::futurize for details.
|
||||
|
||||
\code{.cpp}
|
||||
std::future<std::tuple<std::string, std::string>> future =
|
||||
(http_request("travis-ci.org") && http_request("atom.io"))
|
||||
.apply(cti::transforms::futurize());
|
||||
\endcode
|
||||
*/
|
||||
}
|
||||
@ -33,5 +33,9 @@ This tutorial is split across multiple chapters which should be read in order:
|
||||
- \subpage tutorial-creating-continuables --- \copybrief tutorial-creating-continuables
|
||||
- \subpage tutorial-chaining-continuables --- \copybrief tutorial-chaining-continuables
|
||||
- \subpage tutorial-connecting-continuables --- \copybrief tutorial-connecting-continuables
|
||||
- \subpage tutorial-transforming-continuables --- \copybrief tutorial-transforming-continuables
|
||||
- \subpage tutorial-awaiting-continuables --- \copybrief tutorial-awaiting-continuables
|
||||
- \subpage tutorial-promisify-continuables --- \copybrief tutorial-promisify-continuables
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
@ -44,9 +44,9 @@ namespace cti {
|
||||
|
||||
/// Helper class for converting callback taking callable types into a
|
||||
/// a continuable. Various styles are supported.
|
||||
/// - `from_asio`: Converts callback taking callable types into continuables
|
||||
/// which pass an error code as first parameter and the rest of
|
||||
/// the result afterwards.
|
||||
/// - `from`: Converts callback taking callable types into continuables
|
||||
/// which pass an error code as first parameter and the rest of
|
||||
/// the result afterwards.
|
||||
///
|
||||
/// \tparam Result The result of the converted continuable, this should align
|
||||
/// with the arguments that are passed to the callback.
|
||||
@ -64,7 +64,7 @@ public:
|
||||
/// See an example of how to promisify boost asio's async_resolve below:
|
||||
/// ```cpp
|
||||
/// auto async_resolve(std::string host, std::string service) {
|
||||
/// return cti::promisify<asio::ip::udp::resolver::iterator>::from_asio(
|
||||
/// return cti::promisify<asio::ip::udp::resolver::iterator>::from(
|
||||
/// [&](auto&&... args) {
|
||||
/// resolver_.async_resolve(std::forward<decltype(args)>(args)...);
|
||||
/// },
|
||||
@ -81,8 +81,8 @@ public:
|
||||
///
|
||||
/// \since 3.0.0
|
||||
template <typename Callable, typename... Args>
|
||||
static auto from_asio(Callable&& callable, Args&&... args) {
|
||||
return helper::template from<detail::convert::promisify_asio>(
|
||||
static auto from(Callable&& callable, Args&&... args) {
|
||||
return helper::template from<detail::convert::promisify_default>(
|
||||
std::forward<Callable>(callable), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user