mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Edit the readme
This commit is contained in:
parent
7ab7c726b6
commit
ccd77dee29
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2015-2017 Denis Blank
|
Copyright (c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
227
Readme.md
227
Readme.md
@ -1,6 +1,8 @@
|
|||||||
# continuable->then(make_things_simple());
|

|
||||||
|
|
||||||
[](https://travis-ci.org/Naios/continuable) [](https://ci.appveyor.com/project/Naios/continuable)  [](http://melpon.org/wandbox/permlink/gRWxSNHtARvRcmSY)
|
 [](https://travis-ci.org/Naios/continuable) [](https://ci.appveyor.com/project/Naios/continuable)  [](https://naios.github.io/continuable/) [](http://melpon.org/wandbox/permlink/xVM2szjDLEge3YLV)
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
> Async C++14 platform independent continuation chainer providing light and allocation aware futures
|
> Async C++14 platform independent continuation chainer providing light and allocation aware futures
|
||||||
|
|
||||||
@ -9,9 +11,30 @@ This library provides full feature support of:
|
|||||||
* async continuation chaining using **callbacks** (*then*).
|
* async continuation chaining using **callbacks** (*then*).
|
||||||
* **no enforced type-erasure** which means we need **extremely fewer heap allocations** .
|
* **no enforced type-erasure** which means we need **extremely fewer heap allocations** .
|
||||||
* support for **finite logical connections** between continuables through an **all, any or sequence** strategy.
|
* support for **finite logical connections** between continuables through an **all, any or sequence** strategy.
|
||||||
* **syntactic sugar** for attaching callbacks to a continuation like partial invocation.
|
* **syntactic sugar** for attaching callbacks to a continuation like partial invocation or tuple unpacking.
|
||||||
|
|
||||||
|
|
||||||
|
> **Note:** This library only provides the facility for building asynchronous functions. Thus functions shown in the examples and the documentation like `http_request`, `mysql_query` or `read_file` aren't provided by this library.
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
- [The library design](#the-library-design)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [How-to use](#how-to-use)
|
||||||
|
- [Building the unit-tests](#building-the-unit-tests)
|
||||||
|
- [Stability and version](#stability-and-version)
|
||||||
|
- [Quick reference](#quick-reference)
|
||||||
|
- [Creating Continuables](#creating-continuables)
|
||||||
|
- [Chaining Continuables](#chaining-continuables)
|
||||||
|
- [Providing helper functions](#providing-helper-functions)
|
||||||
|
- [Connecting Continuables {all, any or sequential}](#connecting-continuables-all-any-or-sequential)
|
||||||
|
- [Partial argument application](#partial-argument-application)
|
||||||
|
- [Dispatching callbacks through a specific executor](#dispatching-callbacks-through-a-specific-executor)
|
||||||
|
- [Type erasure](#type-erasure)
|
||||||
|
- [Future conversion](#future-conversion)
|
||||||
|
- [Compatibility](#compatibility)
|
||||||
|
- [Similar implementations and alternatives](#similar-implementations-and-alternatives)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
|
||||||
## The library design
|
## The library design
|
||||||
@ -29,7 +52,7 @@ The continuable library was designed in order to provide you as much as flexibil
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Inclusion
|
### How-to use
|
||||||
|
|
||||||
As mentioned earlier the library is header-only. There is a cmake project provided for simple setup:
|
As mentioned earlier the library is header-only. There is a cmake project provided for simple setup:
|
||||||
|
|
||||||
@ -46,7 +69,7 @@ add_subdirectory(continuable)
|
|||||||
target_link_libraries(my_project continuable)
|
target_link_libraries(my_project continuable)
|
||||||
```
|
```
|
||||||
|
|
||||||
On POSIX 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.
|
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.
|
||||||
|
|
||||||
### Building the unit-tests
|
### Building the unit-tests
|
||||||
|
|
||||||
@ -58,14 +81,14 @@ git clone --recursive https://github.com/Naios/continuable.git
|
|||||||
```
|
```
|
||||||
## Stability and version
|
## Stability and version
|
||||||
|
|
||||||
Currently, the library is in the incubation state, it provides a stable functionality as the CI unit tests indicate.
|
The library follows the rules of [semantic versioning](http://semver.org/), the API is kept stable across minor versions.
|
||||||
|
|
||||||
The API isn't fixed right now and will be eventually changed into the future.
|
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).
|
||||||
|
|
||||||
Also, the unit-test is observed with the Clang sanitizers (asan, ubsan and lsan - when compiling with Clang) or Valgrind (when compiling with GCC).
|
|
||||||
|
|
||||||
## Quick reference
|
## Quick reference
|
||||||
|
|
||||||
|
This chapter only overflies the functionality of the continuable library, the full documentation is located at https://naios.github.io/continuable/.
|
||||||
|
|
||||||
### Creating Continuables
|
### Creating Continuables
|
||||||
|
|
||||||
Create a continuable from a callback taking function:
|
Create a continuable from a callback taking function:
|
||||||
@ -115,6 +138,7 @@ mysql_query("SELECT `id`, `name` FROM `users`")
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note:** The continuation chain is invoked when the object is destructed or the `done()` method is called.
|
||||||
|
|
||||||
### Providing helper functions
|
### Providing helper functions
|
||||||
|
|
||||||
@ -144,12 +168,14 @@ mysql_query("SELECT `id`, `name` FROM users")
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Connecting Continuables {all or any}
|
|
||||||
|
### Connecting Continuables {all, any or sequential}
|
||||||
|
|
||||||
Continuables provide the operators **&&** and **||** for logical connection:
|
Continuables provide the operators **&&** and **||** for logical connection:
|
||||||
|
|
||||||
* **&&** invokes the final callback with the compound result of all connected continuables.
|
* **&&** invokes the final callback with the compound result of all connected continuables, the continuables were invoked in parallel.
|
||||||
* **||** invokes the final callback once with the first result available.
|
* **||** invokes the final callback once with the first result which becomes available.
|
||||||
|
* **>\>** invokes the final callback with the compound result of all connected continuables but the continuations were invokes sequentially.
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
auto http_request(std::string url) {
|
auto http_request(std::string url) {
|
||||||
@ -170,6 +196,12 @@ auto http_request(std::string url) {
|
|||||||
// The callback is called with the first response of either github, travis or atom.
|
// The callback is called with the first response of either github, travis or atom.
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// `sequence` of connections:
|
||||||
|
(http_request("github.com") >> http_request("travis-ci.org") >> http_request("atom.io"))
|
||||||
|
.then([](std::string github, std::string travis, std::string atom) {
|
||||||
|
// The requests are invoked sequentially
|
||||||
|
});
|
||||||
|
|
||||||
// mixed logical connections:
|
// mixed logical connections:
|
||||||
(http_request("github.com") && (http_request("travis-ci.org") || http_request("atom.io")))
|
(http_request("github.com") && (http_request("travis-ci.org") || http_request("atom.io")))
|
||||||
.then([](std::string github, std::string travis_or_atom) {
|
.then([](std::string github, std::string travis_or_atom) {
|
||||||
@ -180,9 +212,40 @@ auto http_request(std::string url) {
|
|||||||
// There are helper functions for connecting continuables:
|
// There are helper functions for connecting continuables:
|
||||||
auto all = cti::all_of(http_request("github.com"), http_request("travis-ci.org"));
|
auto all = cti::all_of(http_request("github.com"), http_request("travis-ci.org"));
|
||||||
auto any = cti::any_of(http_request("github.com"), http_request("travis-ci.org"));
|
auto any = cti::any_of(http_request("github.com"), http_request("travis-ci.org"));
|
||||||
|
auto seq = cti::seq_of(http_request("github.com"), http_request("travis-ci.org"));
|
||||||
```
|
```
|
||||||
|
|
||||||
Logical connections are ensured to be **thread-safe** and **wait-free** by library design (when assuming that *std::call_once* is wait-free - which depends on the toolchain).
|
> **Note:** Logical connections are ensured to be **thread-safe** and **wait-free** by library design (when assuming that *std::call_once* is wait-free - which depends on the toolchain).
|
||||||
|
|
||||||
|
### Partial argument application
|
||||||
|
|
||||||
|
The callback is called only with the arguments it's accepting:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
(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.
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dispatching callbacks through a specific executor
|
||||||
|
|
||||||
|
Dispatching a callback through a specific executor is supported through through the second argument of `then()`:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
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);
|
||||||
|
// ^^^^^^^^
|
||||||
|
```
|
||||||
|
|
||||||
### Type erasure
|
### Type erasure
|
||||||
|
|
||||||
@ -211,13 +274,13 @@ However you may still define your own continuation wrapper with the backend of y
|
|||||||
|
|
||||||
```c++
|
```c++
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
using mycontinuation = cti::continuable_of_t<
|
using my_continuation = typename cti::continuable_trait<
|
||||||
cti::continuable_erasure_of_t<std::function, std::function, Args...>,
|
std::function, std::function, Args...
|
||||||
Args...>;
|
>::continuable;
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
mycontinuation<int> myc = cti::make_continuable([](auto&& callback) {
|
my_continuation<int> myc = cti::make_continuable([](auto&& callback) {
|
||||||
// ^^^^^
|
// ^^^^^
|
||||||
// Signatures may be omitted for continuables which are type erased
|
// Signatures may be omitted for continuables which are type erased
|
||||||
callback(0);
|
callback(0);
|
||||||
@ -228,7 +291,7 @@ We could also think about using `std::future` as backend but this is even worse
|
|||||||
|
|
||||||
### Future conversion
|
### Future conversion
|
||||||
|
|
||||||
The library is capable of converting (*futurizing*) every continuable into a fitting **std::future** through the `continuable<...>::futurize()` method.
|
The library is capable of converting (*futurizing*) every continuable into a fitting **std::future** through the `continuable<...>::futurize()` method.:
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
std::future<std::string> future = http_request("github.com")
|
std::future<std::string> future = http_request("github.com")
|
||||||
@ -243,87 +306,7 @@ std::future<std::tuple<std::string, std::string>> future =
|
|||||||
(http_request("travis-ci.org") && http_request("atom.io")).futurize();
|
(http_request("travis-ci.org") && http_request("atom.io")).futurize();
|
||||||
```
|
```
|
||||||
|
|
||||||
Continuables returning nothing will evaluate to: `std::future<void>`.
|
> **Note:** See the [doxygen documentation](https://naios.github.io/continuable/) for detailed information about the return type of `futurize()`.
|
||||||
|
|
||||||
Continuables returning only one value will evaluate the corresponding future: `std::future<type>`.
|
|
||||||
|
|
||||||
Continuables returning more then one value will evaluate to a future providing a tuple carrying the values : `std::future<std::tuple<...>>`.
|
|
||||||
|
|
||||||
### In Progress (ToDo-List)
|
|
||||||
|
|
||||||
Although the library has progressed very far there are still some candies missing:
|
|
||||||
|
|
||||||
- [x] **Partial application**:
|
|
||||||
|
|
||||||
We could allow callbacks to be invoked with fewer arguments than expected:
|
|
||||||
|
|
||||||
```C++
|
|
||||||
http_request("github.com")
|
|
||||||
.then([]() { // ERROR: Because we expect an object accepting a std::string
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
- [x] The **sequential operator** which invokes continuables sequentially and calls the callback with all results:
|
|
||||||
|
|
||||||
```c++
|
|
||||||
(http_request("github.com") >> http_request("travis-ci.org") >> http_request("atom.io"))
|
|
||||||
.then([](std::string github, std::string travis, std::string atom) {
|
|
||||||
// The requests are done sequentially and the callback is called
|
|
||||||
// with the response of github, travis and atom as soon as atom has responded.
|
|
||||||
// The responses of github and travis are stored meanwhile.
|
|
||||||
});
|
|
||||||
|
|
||||||
auto seq = cti::seq_of(http_request("github.com"), http_request("travis-ci.org"));
|
|
||||||
```
|
|
||||||
|
|
||||||
This differs from the `all` connection in the way that the continuables are invoked sequentially instead of parallel.
|
|
||||||
|
|
||||||
|
|
||||||
- [ ] **Inplace resolution** (makes it possible to keep the nesting level flat):
|
|
||||||
|
|
||||||
```c++
|
|
||||||
http_request("github.com")
|
|
||||||
.then([](std::string response) {
|
|
||||||
// Do something with the response
|
|
||||||
int response_code = get_code(response);
|
|
||||||
|
|
||||||
return std::make_tuple(http_request("atom.io"), response_code);
|
|
||||||
// ^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
})
|
|
||||||
.then([](std::string atom, int response_code) {
|
|
||||||
// - `std::string atom` was resolved from `http_request("atom.io")`
|
|
||||||
// - `response_code` was passed through the tuple directly
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] Library support of **infinite logical connections**:
|
|
||||||
|
|
||||||
```c++
|
|
||||||
std::vector<cti::continuable<int, int>> some;
|
|
||||||
|
|
||||||
cti::all(std::move(some))
|
|
||||||
.then([](std::vector<int, int> result) {
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
This library mainly aims to support un-erased continuations, however, sometimes it's required to work with a compile-time unknown amount of continuables.
|
|
||||||
|
|
||||||
- [ ] Maybe **Un-erasured fail/rejection handlers** and (possible exception support):
|
|
||||||
|
|
||||||
```c++
|
|
||||||
http_request("github.com")
|
|
||||||
.rejected([](std::error_code) {
|
|
||||||
// Is called when the request fails
|
|
||||||
|
|
||||||
// Potential difficult to implement with less type erasure
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
@ -335,11 +318,9 @@ Tested & compatible with:
|
|||||||
|
|
||||||
Every compiler with modern C++14 support should work.
|
Every compiler with modern C++14 support should work.
|
||||||
|
|
||||||
The library only depends on the standard library when using the `continuable/continuable-base.hpp` header only which provides the full un-erasured support.
|
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)`.
|
||||||
|
|
||||||
On Posix: don't forget to **link a corresponding thread library** into your application otherwise `std::future's` won't work `(-pthread)`.
|
|
||||||
|
|
||||||
## Similar implementations and alternatives
|
## Similar implementations and alternatives
|
||||||
|
|
||||||
@ -351,16 +332,46 @@ There are some existing solutions with similar design thoughts already, which I
|
|||||||
|
|
||||||
Is designed in a similar way, however, it orientates itself more on the corresponding JavaScript libraries which leaves some benefits behind we could reach with modern C++ meta-programming. Like previous approaches, the library uses type erasure excessively (and thus isn't memory allocation aware). What differentiates **q** from the continuable library is that it supports infinite logical connections and ships with built-in exception support as well as it's own executors (thread pools) - thus the library isn't header-only anymore (but the library is still proclaimed to work with other executors). My personal opinion is that a continuation library shouldn't include any other stuff then the continuation logic itself.
|
Is designed in a similar way, however, it orientates itself more on the corresponding JavaScript libraries which leaves some benefits behind we could reach with modern C++ meta-programming. Like previous approaches, the library uses type erasure excessively (and thus isn't memory allocation aware). What differentiates **q** from the continuable library is that it supports infinite logical connections and ships with built-in exception support as well as it's own executors (thread pools) - thus the library isn't header-only anymore (but the library is still proclaimed to work with other executors). My personal opinion is that a continuation library shouldn't include any other stuff then the continuation logic itself.
|
||||||
|
|
||||||
### [cpprestsdk](https://github.com/Microsoft/cpprestsdk)
|
#### [cpprestsdk](https://github.com/Microsoft/cpprestsdk)
|
||||||
|
|
||||||
Basically, the same arguments as explained in the q section apply to the cpprestsdk as well, it's major drawbacks is the overwhelming use of type-erasure. Probably you will benefit a lot from the library if you intend to use it's provided asynchronously *http*, *websocket* and *filesystem* functionalities. The *continuable* library was designed with different thoughts in mind - it basically provides the continuation logic without any support methods so you can embed it into your application without depending on a heavy framework. This makes it possible to apply continuation chaning to esoteric domains such as C++ AI scripts with fast or immediately response times. Who knows - maybe someone will provide *continuable* wrappers for open-source libraries like *asio*, libuv or *uWebSockets* in the future too.
|
Basically, the same arguments as explained in the q section apply to the cpprestsdk as well, it's major drawbacks is the overwhelming use of type-erasure. Probably you will benefit a lot from the library if you intend to use it's provided asynchronously *http*, *websocket* and *filesystem* functionalities. The *continuable* library was designed with different thoughts in mind - it basically provides the continuation logic without any support methods so you can embed it into your application without depending on a heavy framework. This makes it possible to apply continuation chaning to esoteric domains such as C++ AI scripts with fast or immediately response times. Who knows - maybe someone will provide *continuable* wrappers for open-source libraries like *asio*, libuv or *uWebSockets* in the future too.
|
||||||
|
|
||||||
### Others
|
|
||||||
|
|
||||||
If I forget to mention a library here let me know, so we can add the alternatives.
|
|
||||||
|
|
||||||
|
> **Note:** If I forget to mention a library here let me know, so we can add the alternatives.
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
The continuable library is licensed under the MIT License
|
The continuable library is licensed under the MIT License:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
/**
|
||||||
|
|
||||||
|
/~` _ _ _|_. _ _ |_ | _
|
||||||
|
\_,(_)| | | || ||_|(_||_)|(/_
|
||||||
|
|
||||||
|
https://github.com/Naios/continuable
|
||||||
|
v0.8.0
|
||||||
|
|
||||||
|
Copyright(c) 2015 - 2017 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.
|
||||||
|
**/
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@ -31,13 +31,11 @@ struct ResultSet {};
|
|||||||
struct Buffer {};
|
struct Buffer {};
|
||||||
|
|
||||||
cti::continuable<ResultSet> mysql_query(std::string /*url*/) {
|
cti::continuable<ResultSet> mysql_query(std::string /*url*/) {
|
||||||
return cti::make_continuable<std::string>(
|
return cti::make_continuable([](auto&& callback) { callback(ResultSet{}); });
|
||||||
[](auto&& callback) { callback("<html>...</html>"); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cti::continuable<Buffer> read_file(std::string /*url*/) {
|
cti::continuable<Buffer> read_file(std::string /*url*/) {
|
||||||
return cti::make_continuable<std::string>(
|
return cti::make_continuable([](auto&& callback) { callback(Buffer{}); });
|
||||||
[](auto&& callback) { callback("<html>...</html>"); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct a {
|
struct a {
|
||||||
@ -55,34 +53,38 @@ int main(int, char**) {
|
|||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
(http_request("github.com") && http_request("atom.io"))
|
(http_request("github.com") && http_request("atom.io"))
|
||||||
.then([] (std::string github, std::string atom) {
|
.then([] (std::string /*github*/, std::string /*atom*/) {
|
||||||
// ...
|
// ...
|
||||||
return mysql_query("select * from `users`");
|
return mysql_query("select * from `users`");
|
||||||
})
|
})
|
||||||
.then([] (ResultSet result) {
|
.then([] (ResultSet /*result*/) {
|
||||||
// ...
|
// ...
|
||||||
}, executor->post());
|
}, executor->post());
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
auto cq = http_request("github.com") && http_request("atom.io") ;
|
auto c1 = http_request("github.com") && http_request("atom.io") ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto cq = http_request("github.com") || http_request("atom.io") ;
|
auto c2 = http_request("github.com") || http_request("atom.io") ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto cq = http_request("github.com") >> http_request("atom.io") ;
|
auto c3 = http_request("github.com") >> http_request("atom.io") ;
|
||||||
|
|
||||||
|
(void)c1;
|
||||||
|
(void)c2;
|
||||||
|
(void)c3;
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
||||||
read_file("entries.csv")
|
read_file("entries.csv")
|
||||||
.then([] (Buffer buffer) {
|
.then([] (Buffer /*buffer*/) {
|
||||||
// ...
|
// ...
|
||||||
return std::make_tuple("hey", true, 0);
|
return std::make_tuple("hey", true, 0);
|
||||||
})
|
})
|
||||||
.then([] (std::string msg) {
|
.then([] (std::string /*msg*/) {
|
||||||
// ...
|
// ...
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,4 @@
|
|||||||
|
|
||||||
#include "continuable/continuable.hpp"
|
#include "continuable/continuable.hpp"
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) { return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user