From 8d6a9b6b2425ea1c8bba576de36684a671a757dc Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sat, 10 Mar 2018 10:30:03 +0100 Subject: [PATCH] Started the new tutorial section --- doc/index.dox | 21 +++-- doc/tutorial-chaining-continuables.dox | 61 ++++++++++++ doc/tutorial-creating-continuables.dox | 94 +++++++++++++++++++ doc/tutorial.dox | 38 ++++++++ .../continuable/continuable-promise-base.hpp | 6 ++ 5 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 doc/tutorial-chaining-continuables.dox create mode 100644 doc/tutorial-creating-continuables.dox create mode 100644 doc/tutorial.dox diff --git a/doc/index.dox b/doc/index.dox index dda5873..9e0ebef 100644 --- a/doc/index.dox +++ b/doc/index.dox @@ -26,11 +26,20 @@ namespace cti { \section mainpage-overview Overview Continuable is a C++14 library that provides full support for: - - lazy async continuation chaining based on **callbacks** (*then*) and expression templates, callbacks are wrapped nicely as promises. - - **no enforced type-erasure** which means we need less heap allocations than comparable libraries, strictly following the "don't pay for what you don't use" principle. - - support for **connections** between continuables through an **all, any or sequential** strategy through expressive operator overloads **&&**, || and >>. - - asynchronous **error handling** through exceptions, error coded or user defined types. - - **syntactic sugar** for instance: **partial invocation**, **tuple unpacking** and **executors**. + - lazy async continuation chaining based on **callbacks** (`then`) and + expression templates, callbacks are wrapped nicely as promises. + - **no enforced type-erasure** which means we need less heap + allocations than comparable libraries, strictly following the "don't + pay for what you don't use" principle. + - support for **connections** between continuables through an **all, any or + sequential** strategy through expressive operator overloads **&&**, + || and >>. + - asynchronous **error handling** through exceptions, error coded or + user defined types. + - **syntactic sugar** for instance: **partial invocation**, **tuple unpacking** + and **executors**. + - **encapsuled from any runtime**, larger framework or executor making + it possible to use continuable even in smaller or esoteric usage scenarios. \section mainpage-getting-started Getting started @@ -49,7 +58,7 @@ your personal experience in using the library to improve it. \note If you like the library I would be glad if you star it on Github, - since this helps other users to find the library. + because it helps other users to find this library. \section mainpage-license License diff --git a/doc/tutorial-chaining-continuables.dox b/doc/tutorial-chaining-continuables.dox new file mode 100644 index 0000000..08db14a --- /dev/null +++ b/doc/tutorial-chaining-continuables.dox @@ -0,0 +1,61 @@ +/* + Copyright(c) 2015 - 2018 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-chaining-continuables Chaining continuables +\brief Explains how to chain multiple \ref continuable_base objects together. + +\tableofcontents + +The \ref cti::continuable_base \ref cti::when_any \ref cti::promisify + +- Supply a continuable which is invoked lazily upon request: + + +- Continue the continuation using `.then(...)` and `.fail(...)`, exceptions are passed to the first available handler: + \code{.cpp} + http_request("github.com") + .then([] (std::string result) { + // Do something... + return http_request("travis-ci.org") + }) + .then([] (std::string result) { + // Handle the response from 'travis-ci.org' + }) + .fail([] (std::exception_ptr ptr) { + try { + std::rethrow_exception(ptr); + } catch(std::exception const& e) { + // Handle the exception or error code here + } + }); + \endcode + +- Create connections between the continuables and use its compound result: + \code{.cpp} + (http_request("github.com") && (http_request("travis-ci.org") || http_request("atom.io"))) + .then([](std::string github, std::string travis_or_atom) { + // The promise is called with the response of github and travis or atom. + }); + \endcode +*/ +} diff --git a/doc/tutorial-creating-continuables.dox b/doc/tutorial-creating-continuables.dox new file mode 100644 index 0000000..6ecb935 --- /dev/null +++ b/doc/tutorial-creating-continuables.dox @@ -0,0 +1,94 @@ +/* + Copyright(c) 2015 - 2018 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-creating-continuables Creating continuables +\brief Explains how to create a \ref continuable_base. + +\tableofcontents + +A \ref continuable is an arbitrary instantiation of a \ref continuable_base, +it represents the main class of the library and makes it possible to build up +an asynchronous call hierarchy. When dealing with continuables we usually don't +know its exact type for avoiding expensive type erasure. + +The \ref continuable_base is convertible to a \ref continuable which represents +a specified type of the \ref continuable_base on the cost of a type erasure. + +An asynchronous call hierarchy that is stored inside the \ref continuable_base +is executed when its result is requested (lazy evaluation) in contrast to +other commonly used abstractions such as `std::future` which execute the +asynchronous call hierarchy instantly on creation (eager evaluation). + +\section tutorial-creating-continuables-ready From a value or exception type + +The library provides \ref make_ready_continuable which may be used to create a +\ref continuable_base from an arbitrary amount of values: + +\code{.cpp} +cti::continuable c = cti::make_ready_continuable(0); +\endcode + +\note In most situations you will never use \ref make_ready_continuable + because the library is capable of working with plain values + directly and thus this burdens unnecessary overhead. + +Additionally a \ref continuable_base which resolves with an exception may be +created through \ref make_exceptional_continuable. + +\code{.cpp} +cti::continuable c = cti::make_exceptional_continuable(std::exception{}); +\endcode + +\section tutorial-creating-continuables-promises From a promise taking callable + +The main function for creating a \ref continuable_base is \ref make_continuable +which must be invoked with the types of arguments it resolves to. +It accepts a callable object which accepts an arbitrary object +(the \ref promise_base). The \ref promise_base is created by the library and +then passed to the given callback. This is in contrast to the usage of the +standard `std::promise` which is created by the user. + +The \ref promise_base exposes methods to resolve it through result values or +through an exception. Below we implement pseudo `http_request` function +which resolves the request asynchronously trough a `std::string`. + +\code{.cpp} +auto http_request(std::string url) { + return cti::make_continuable( + [url = std::move(url)](auto&& promise) { + // Resolve the promise upon completion of the task. + promise.set_value(" ... "); + + // Or promise.set_exception(...); + }); +} +\endcode + +\attention After resolving a \ref promise_base it should not be used any more, + because the class is only usable once. + +A \ref promise_base always exposes a call operator for resolving it as +like when using \ref promise_base::set_value or +\ref promise_base::set_exception. See \ref promise_base for details. +*/ +} diff --git a/doc/tutorial.dox b/doc/tutorial.dox new file mode 100644 index 0000000..40ada94 --- /dev/null +++ b/doc/tutorial.dox @@ -0,0 +1,38 @@ +/* + Copyright(c) 2015 - 2018 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 Tutorial +\brief An introduction for using the continuable library. + +\tableofcontents + +This tutorial will give a short overview about using the library. +We assume that the library is available in your current environment, +if not, follow the \ref installation section in order to get it to work. + +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 +*/ +} diff --git a/include/continuable/continuable-promise-base.hpp b/include/continuable/continuable-promise-base.hpp index 9d1eb5a..a007fbc 100644 --- a/include/continuable/continuable-promise-base.hpp +++ b/include/continuable/continuable-promise-base.hpp @@ -49,6 +49,12 @@ namespace cti { /// Use the promise type defined in `continuable/continuable_types.hpp`, /// in order to use this class. /// +/// If we want to resolve the promise_base trough the call operator, +/// and we want to resolve it through an exception, we must call it with a +/// dispatch_error_tag as first and the exception as second argument. +/// Additionally the promise is resolveable only through its call +/// operator when invoked as an r-value. +/// /// \since 2.0.0 // clang-format off template