Enhance the documentation and add markdown lint

- Add npm package.json to make easier maintaining dependencies.
- Make markdown files consistent using remark.
- Wrap markdown lines to 100 characters.
- Better README.md layout and visual.
- Enable VuePress landing/home page.
- Upgrade to latest VuePress version.
- Add link to the new Qt Marketplace.
This commit is contained in:
Simon Brunel 2019-12-21 10:27:26 +01:00
parent 815dc443b9
commit 3c1461b8d0
44 changed files with 12109 additions and 212 deletions

5
.gitignore vendored
View File

@ -1,8 +1,8 @@
_book
dist
node_modules
*.gcno
*.gcda
*.info
*.moc
*.o
*.obj
@ -11,6 +11,3 @@ node_modules
Makefile*
moc_*.cpp
moc_*.h
coverage.info
package-lock.json
target_wrapper.bat

5
.remarkrc.yml Normal file
View File

@ -0,0 +1,5 @@
plugins:
- frontmatter
- preset-lint-recommended
- preset-lint-markdown-style-guide
- [lint-maximum-line-length, 100]

View File

@ -1,8 +1,15 @@
<a href="https://promisesaplus.com/" title="Promises/A+ 1.1"><img src="https://promisesaplus.com/assets/logo-small.png" alt="Promises/A+" align="right"/></a>
<p align="center">
<img width="256" src="docs/.vuepress/public/hero.svg?sanitize=true">
</p>
# QtPromise
<p align="center">
<a href="https://www.qpm.io/packages/com.github.simonbrunel.qtpromise/index.html"><img src="https://img.shields.io/github/release/simonbrunel/qtpromise.svg?style=flat-square&label=qpm&colorB=4CAF50&maxAge=600" alt="Install"></a>
<a href="https://travis-ci.org/simonbrunel/qtpromise"><img src="https://img.shields.io/travis/simonbrunel/qtpromise/master.svg?style=flat-square&maxAge=600" alt="Builds"></a>
<a href="https://codecov.io/gh/simonbrunel/qtpromise"><img src="https://img.shields.io/codecov/c/github/simonbrunel/qtpromise.svg?style=flat-square&maxAge=600" alt="Coverage"></a>
<a href="https://marketplace.qt.io/products/qtpromise"><img src="https://img.shields.io/static/v1?style=flat-square&label=Qt&message=Marketplace&colorB=40cd52&maxAge=600" alt="Marketplace"></a>
</p>
[![qpm](https://img.shields.io/github/release/simonbrunel/qtpromise.svg?style=flat-square&label=qpm&colorB=4CAF50)](https://www.qpm.io/packages/com.github.simonbrunel.qtpromise/index.html) [![Travis](https://img.shields.io/travis/simonbrunel/qtpromise/master.svg?style=flat-square)](https://travis-ci.org/simonbrunel/qtpromise) [![coverage](https://img.shields.io/codecov/c/github/simonbrunel/qtpromise.svg?style=flat-square)](https://codecov.io/gh/simonbrunel/qtpromise)
## Overview
[Promises/A+](https://promisesaplus.com/) implementation for [Qt/C++](https://www.qt.io/).
@ -10,11 +17,11 @@ Requires [Qt 5.6](https://www.qt.io/download/) (or later) with [C++11 support en
## Documentation
* [Getting Started](https://qtpromise.netlify.com/qtpromise/getting-started.html)
* [Qt Concurrent](https://qtpromise.netlify.com/qtpromise/qtconcurrent.html)
* [Qt Signals](https://qtpromise.netlify.com/qtpromise/qtsignals.html)
* [Thread-Safety](https://qtpromise.netlify.com/qtpromise/thread-safety.html)
* [API Reference](https://qtpromise.netlify.com/qtpromise/api-reference.html)
- [Getting Started](https://qtpromise.netlify.com/qtpromise/getting-started.html)
- [Qt Concurrent](https://qtpromise.netlify.com/qtpromise/qtconcurrent.html)
- [Qt Signals](https://qtpromise.netlify.com/qtpromise/qtsignals.html)
- [Thread-Safety](https://qtpromise.netlify.com/qtpromise/thread-safety.html)
- [API Reference](https://qtpromise.netlify.com/qtpromise/api-reference.html)
## License

View File

@ -1,6 +1,7 @@
module.exports = {
title: 'QtPromise',
description: 'Promises/A+ implementation for Qt/C++',
dest: 'dist/docs',
ga: 'UA-113899811-1',
head: [
['link', { rel: 'icon', href: `/favicon.png` }],
@ -8,61 +9,67 @@ module.exports = {
themeConfig: {
repo: 'simonbrunel/qtpromise',
lastUpdated: 'Last Updated',
smoothScroll: true,
editLinks: true,
docsDir: 'docs',
algolia: {
apiKey: '0e6e9cccb8c2c360a5543e28c4e31cb8',
indexName: 'qtpromise'
},
nav: [
{ text: 'Home', link: '/' },
{ text: 'Guide', link: '/qtpromise/getting-started' },
{ text: 'API Reference', link: '/qtpromise/api-reference' },
],
sidebar: [
'qtpromise/getting-started',
'qtpromise/qtconcurrent',
'qtpromise/qtsignals',
'qtpromise/thread-safety',
'qtpromise/api-reference',
'/qtpromise/getting-started',
'/qtpromise/qtconcurrent',
'/qtpromise/qtsignals',
'/qtpromise/thread-safety',
'/qtpromise/api-reference',
{
title: 'QPromise',
children: [
'qtpromise/qpromise/constructor',
'qtpromise/qpromise/delay',
'qtpromise/qpromise/each',
'qtpromise/qpromise/fail',
'qtpromise/qpromise/filter',
'qtpromise/qpromise/finally',
'qtpromise/qpromise/isfulfilled',
'qtpromise/qpromise/ispending',
'qtpromise/qpromise/isrejected',
'qtpromise/qpromise/map',
'qtpromise/qpromise/reduce',
'qtpromise/qpromise/tap',
'qtpromise/qpromise/tapfail',
'qtpromise/qpromise/then',
'qtpromise/qpromise/timeout',
'qtpromise/qpromise/wait',
'qtpromise/qpromise/reject.md',
'qtpromise/qpromise/resolve.md'
'/qtpromise/qpromise/constructor',
'/qtpromise/qpromise/delay',
'/qtpromise/qpromise/each',
'/qtpromise/qpromise/fail',
'/qtpromise/qpromise/filter',
'/qtpromise/qpromise/finally',
'/qtpromise/qpromise/isfulfilled',
'/qtpromise/qpromise/ispending',
'/qtpromise/qpromise/isrejected',
'/qtpromise/qpromise/map',
'/qtpromise/qpromise/reduce',
'/qtpromise/qpromise/tap',
'/qtpromise/qpromise/tapfail',
'/qtpromise/qpromise/then',
'/qtpromise/qpromise/timeout',
'/qtpromise/qpromise/wait',
'/qtpromise/qpromise/reject.md',
'/qtpromise/qpromise/resolve.md'
]
},
{
title: 'Helpers',
children: [
'qtpromise/helpers/all',
'qtpromise/helpers/attempt',
'qtpromise/helpers/connect',
'qtpromise/helpers/each',
'qtpromise/helpers/filter',
'qtpromise/helpers/map',
'qtpromise/helpers/reduce',
'qtpromise/helpers/resolve'
'/qtpromise/helpers/all',
'/qtpromise/helpers/attempt',
'/qtpromise/helpers/connect',
'/qtpromise/helpers/each',
'/qtpromise/helpers/filter',
'/qtpromise/helpers/map',
'/qtpromise/helpers/reduce',
'/qtpromise/helpers/resolve'
]
},
{
title: 'Exceptions',
children: [
'qtpromise/exceptions/canceled',
'qtpromise/exceptions/context',
'qtpromise/exceptions/timeout',
'qtpromise/exceptions/undefined'
'/qtpromise/exceptions/canceled',
'/qtpromise/exceptions/context',
'/qtpromise/exceptions/timeout',
'/qtpromise/exceptions/undefined'
]
}
]

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<polygon fill="#F7E02F" points="440.999,446 0,446 0,135.382 69,66 511.999,66 511.999,374.906 "/>
<g>
<path d="M209.116,301.104c-27.241,0-46.231-7.334-56.971-22.002c-10.739-14.669-16.109-37.85-16.109-69.544
c0-31.694,5.456-55.223,16.371-70.591c10.911-15.364,29.816-23.05,56.709-23.05c26.889,0,45.749,7.641,56.578,22.919
c10.825,15.282,16.24,38.812,16.24,70.591c0,20.955-2.227,37.895-6.68,50.816c-4.452,12.925-11.746,22.788-21.871,29.599
l22.002,35.361l-26.979,12.572l-23.312-38.242C221.775,300.581,216.45,301.104,209.116,301.104z M175.065,260.374
c5.934,10.216,17.288,15.323,34.051,15.323s28.068-5.018,33.92-15.062c5.849-10.04,8.775-27.021,8.775-50.947
c0-23.922-3.012-41.295-9.037-52.125c-6.024-10.825-17.247-16.24-33.659-16.24c-16.416,0-27.679,5.415-33.79,16.24
c-6.115,10.83-9.167,28.117-9.167,51.863C166.159,233.177,169.126,250.158,175.065,260.374z"/>
<path d="M382.776,191.616h-36.146v57.625c0,10.654,0.785,17.727,2.357,21.218c1.571,3.495,5.586,5.238,12.049,5.238l21.479-0.786
l1.31,22.789c-11.701,2.267-20.606,3.404-26.718,3.404c-14.844,0-25.015-3.404-30.515-10.215
c-5.501-6.811-8.251-19.646-8.251-38.505v-60.769h-16.764v-24.36h16.764v-37.98h28.289v37.98h36.146V191.616z"/>
<path d="M152.877,382.938H142.83v15.285h-7.965v-49.157h18.012c11.147,0,16.721,5.502,16.721,16.505
c0,5.646-1.399,9.952-4.198,12.918C162.601,381.456,158.426,382.938,152.877,382.938z M142.83,376.049h9.975
c5.741,0,8.612-3.491,8.612-10.478c0-3.348-0.694-5.788-2.081-7.319c-1.388-1.531-3.565-2.297-6.531-2.297h-9.975V376.049z"/>
<path d="M176.343,398.224v-35.882h7.75v4.306c4.066-2.63,8.133-4.329,12.2-5.095v7.822c-4.115,0.814-7.632,1.866-10.549,3.157
l-1.579,0.646v25.045H176.343z"/>
<path d="M203.936,366.218c2.463-3.109,6.566-4.665,12.307-4.665c5.741,0,9.843,1.556,12.308,4.665
c2.463,3.11,3.696,7.774,3.696,13.993c0,6.22-1.197,10.908-3.588,14.065c-2.393,3.158-6.53,4.736-12.415,4.736
c-5.884,0-10.023-1.578-12.415-4.736c-2.393-3.157-3.588-7.846-3.588-14.065C200.24,373.992,201.471,369.328,203.936,366.218z
M209.784,389.54c1.1,1.914,3.253,2.871,6.458,2.871c3.205,0,5.357-0.957,6.459-2.871c1.1-1.913,1.65-5.047,1.65-9.4
s-0.586-7.438-1.758-9.258c-1.173-1.817-3.29-2.727-6.351-2.727c-3.062,0-5.179,0.909-6.351,2.727
c-1.173,1.819-1.758,4.904-1.758,9.258S208.683,387.627,209.784,389.54z"/>
<path d="M247.818,398.224h-7.822v-35.882h7.75v2.225c3.396-2.009,6.506-3.014,9.329-3.014c4.162,0,7.199,1.173,9.113,3.517
c4.354-2.344,8.684-3.517,12.99-3.517c4.305,0,7.344,1.328,9.113,3.982c1.77,2.655,2.656,7.141,2.656,13.456v19.232h-7.752v-19.018
c0-3.875-0.395-6.625-1.184-8.252c-0.789-1.626-2.428-2.44-4.916-2.44c-2.152,0-4.473,0.479-6.961,1.436l-1.219,0.502
c0.381,0.958,0.572,4.019,0.572,9.186v18.587h-7.75V379.78c0-4.257-0.383-7.199-1.148-8.826c-0.765-1.626-2.438-2.44-5.022-2.44
c-2.393,0-4.618,0.479-6.674,1.436l-1.076,0.431V398.224z"/>
<path d="M300.133,356.242v-8.253h7.822v8.253H300.133z M300.133,398.224v-35.882h7.822v35.882H300.133z"/>
<path d="M342.33,369.733c-5.646-0.765-9.735-1.147-12.271-1.147s-4.294,0.299-5.274,0.896c-0.98,0.599-1.471,1.543-1.471,2.835
s0.538,2.201,1.614,2.727c1.077,0.527,3.612,1.138,7.607,1.83c3.994,0.694,6.828,1.783,8.504,3.266
c1.674,1.483,2.512,4.115,2.512,7.894c0,3.78-1.209,6.556-3.624,8.324c-2.417,1.771-5.945,2.655-10.585,2.655
c-2.919,0-6.603-0.406-11.052-1.22l-2.225-0.358l0.287-6.53c5.741,0.766,9.878,1.147,12.415,1.147c2.535,0,4.342-0.311,5.418-0.933
c1.076-0.621,1.614-1.65,1.614-3.086s-0.515-2.428-1.543-2.979c-1.029-0.549-3.492-1.147-7.392-1.794
c-3.899-0.646-6.758-1.661-8.575-3.05c-1.819-1.387-2.728-3.922-2.728-7.606c0-3.684,1.256-6.435,3.768-8.253
c2.512-1.817,5.729-2.727,9.652-2.727c3.062,0,6.817,0.383,11.267,1.147l2.225,0.431L342.33,369.733z"/>
<path d="M376.632,391.765l2.009-0.215l0.144,5.813c-5.454,1.101-10.286,1.65-14.496,1.65c-5.311,0-9.126-1.458-11.446-4.377
c-2.32-2.918-3.48-7.582-3.48-13.994c0-12.726,5.19-19.089,15.573-19.089c10.047,0,15.07,5.479,15.07,16.434l-0.503,5.598h-22.246
c0.047,2.967,0.692,5.144,1.938,6.53c1.243,1.389,3.563,2.081,6.961,2.081C369.551,392.195,373.044,392.052,376.632,391.765z
M372.327,377.556c0-3.54-0.563-6.016-1.687-7.427c-1.125-1.411-3.026-2.117-5.705-2.117c-2.681,0-4.629,0.742-5.849,2.225
c-1.221,1.483-1.855,3.923-1.902,7.319H372.327z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,4 +0,0 @@
@import 'override.styl'
.content a code
color: $accentColor

View File

@ -0,0 +1,37 @@
@import 'palette.styl'
a
svg.icon.outbound
margin-bottom -2px
margin-left 2px
img + svg.icon.outbound
display none
sup
font-size 0.75em !important
.home .hero
img
margin 1.5rem auto !important
.description
display none !important
#main-title
display none !important
.content a code
color $accentColor
.navbar
-webkit-box-shadow 0 4px 4px -4px rgba(0,0,0,0.1)
-moz-box-shadow 0 4px 4px -4px rgba(0,0,0,0.1)
box-shadow 0 4px 4px -4px rgba(0,0,0,0.1)
.logo
margin-right: 0.5rem;
.site-name
font-size 1.25rem
.repo-link
margin-left 1rem

View File

@ -1,9 +1,31 @@
<a href="https://promisesaplus.com/" title="Promises/A+ 1.1"><img src="https://promisesaplus.com/assets/logo-small.png" alt="Promises/A+" align="right"/></a>
---
home: true
heroImage: /hero.svg
actionLink: /qtpromise/getting-started.md
footer: MIT Licensed | Copyright © 2019 Simon Brunel
---
<p align="center">
<a href="https://www.qpm.io/packages/com.github.simonbrunel.qtpromise/index.html"><img src="https://img.shields.io/github/release/simonbrunel/qtpromise.svg?style=flat-square&label=qpm&colorB=4CAF50&maxAge=600" alt="Install"></a>
<a href="https://travis-ci.org/simonbrunel/qtpromise"><img src="https://img.shields.io/travis/simonbrunel/qtpromise/master.svg?style=flat-square&maxAge=600" alt="Builds"></a>
<a href="https://codecov.io/gh/simonbrunel/qtpromise"><img src="https://img.shields.io/codecov/c/github/simonbrunel/qtpromise.svg?style=flat-square&maxAge=600" alt="Coverage"></a>
<a href="https://marketplace.qt.io/products/qtpromise"><img src="https://img.shields.io/static/v1?style=flat-square&label=Qt&message=Marketplace&colorB=40cd52&maxAge=600" alt="Marketplace"></a>
</p>
## Overview
# QtPromise
[Promises/A+](https://promisesaplus.com/) implementation for [Qt/C++](https://www.qt.io/).
Requires [Qt 5.6](https://www.qt.io/download/) (or later) with [C++11 support enabled](https://wiki.qt.io/How_to_use_C++11_in_your_Qt_Projects).
## Documentation
- [Getting Started](/qtpromise/getting-started.md)
- [Qt Concurrent](/qtpromise/qtconcurrent.md)
- [Qt Signals](/qtpromise/qtsignals.md)
- [Thread-Safety](/qtpromise/thread-safety.md)
- [API Reference](/qtpromise/api-reference.md)
## License
QtPromise is available under the [MIT license](https://github.com/simonbrunel/qtpromise/blob/master/LICENSE).

View File

@ -2,48 +2,48 @@
## Functions
* [`QPromise<T>::QPromise`](qpromise/constructor.md)
* [`QPromise<T>::delay`](qpromise/delay.md)
* [`QPromise<T>::each`](qpromise/each.md)
* [`QPromise<T>::fail`](qpromise/fail.md)
* [`QPromise<T>::filter`](qpromise/filter.md)
* [`QPromise<T>::finally`](qpromise/finally.md)
* [`QPromise<T>::isFulfilled`](qpromise/isfulfilled.md)
* [`QPromise<T>::isPending`](qpromise/ispending.md)
* [`QPromise<T>::isRejected`](qpromise/isrejected.md)
* [`QPromise<T>::map`](qpromise/map.md)
* [`QPromise<T>::reduce`](qpromise/reduce.md)
* [`QPromise<T>::tap`](qpromise/tap.md)
* [`QPromise<T>::tapFail`](qpromise/tapfail.md)
* [`QPromise<T>::then`](qpromise/then.md)
* [`QPromise<T>::timeout`](qpromise/timeout.md)
* [`QPromise<T>::wait`](qpromise/wait.md)
- [`QPromise<T>::QPromise`](qpromise/constructor.md)
- [`QPromise<T>::delay`](qpromise/delay.md)
- [`QPromise<T>::each`](qpromise/each.md)
- [`QPromise<T>::fail`](qpromise/fail.md)
- [`QPromise<T>::filter`](qpromise/filter.md)
- [`QPromise<T>::finally`](qpromise/finally.md)
- [`QPromise<T>::isFulfilled`](qpromise/isfulfilled.md)
- [`QPromise<T>::isPending`](qpromise/ispending.md)
- [`QPromise<T>::isRejected`](qpromise/isrejected.md)
- [`QPromise<T>::map`](qpromise/map.md)
- [`QPromise<T>::reduce`](qpromise/reduce.md)
- [`QPromise<T>::tap`](qpromise/tap.md)
- [`QPromise<T>::tapFail`](qpromise/tapfail.md)
- [`QPromise<T>::then`](qpromise/then.md)
- [`QPromise<T>::timeout`](qpromise/timeout.md)
- [`QPromise<T>::wait`](qpromise/wait.md)
## Static Functions
* [`[static] QPromise<T>::reject`](qpromise/reject.md)
* [`[static] QPromise<T>::resolve`](qpromise/resolve.md)
- [`(static) QPromise<T>::reject`](qpromise/reject.md)
- [`(static) QPromise<T>::resolve`](qpromise/resolve.md)
## Helpers
* [`QtPromise::all`](helpers/all.md)
* [`QtPromise::attempt`](helpers/attempt.md)
* [`QtPromise::connect`](helpers/connect.md)
* [`QtPromise::each`](helpers/each.md)
* [`QtPromise::filter`](helpers/filter.md)
* [`QtPromise::map`](helpers/map.md)
* [`QtPromise::reduce`](helpers/reduce.md)
* [`QtPromise::resolve`](helpers/resolve.md)
- [`QtPromise::all`](helpers/all.md)
- [`QtPromise::attempt`](helpers/attempt.md)
- [`QtPromise::connect`](helpers/connect.md)
- [`QtPromise::each`](helpers/each.md)
- [`QtPromise::filter`](helpers/filter.md)
- [`QtPromise::map`](helpers/map.md)
- [`QtPromise::reduce`](helpers/reduce.md)
- [`QtPromise::resolve`](helpers/resolve.md)
## Exceptions
* [`QPromiseCanceledException`](exceptions/canceled.md)
* [`QPromiseContextException`](exceptions/context.md)
* [`QPromiseTimeoutException`](exceptions/timeout.md)
* [`QPromiseUndefinedException`](exceptions/undefined.md)
- [`QPromiseCanceledException`](exceptions/canceled.md)
- [`QPromiseContextException`](exceptions/context.md)
- [`QPromiseTimeoutException`](exceptions/timeout.md)
- [`QPromiseUndefinedException`](exceptions/undefined.md)
## Deprecations
* `[static] QPromise<T>::all`: use [`QtPromise::all`](helpers/all.md) instead (since 0.5.0)
* `QtPromise::qPromise`: use [`QtPromise::resolve`](helpers/resolve.md) instead (since 0.5.0)
* `QtPromise::qPromiseAll`: use [`QtPromise::all`](helpers/all.md) instead (since 0.5.0)
- `(static) QPromise<T>::all`: use [`QtPromise::all`](helpers/all.md) instead (since 0.5.0)
- `QtPromise::qPromise`: use [`QtPromise::resolve`](helpers/resolve.md) instead (since 0.5.0)
- `QtPromise::qPromiseAll`: use [`QtPromise::all`](helpers/all.md) instead (since 0.5.0)

View File

@ -1,12 +1,9 @@
---
title: QPromiseCanceledException
---
# QPromiseCanceledException
*Since: 0.1.0*
This exception is thrown for promise created from a [`QFuture`](../qtconcurrent.md) which has been canceled (e.g. using [`QFuture::cancel()`](http://doc.qt.io/qt-5/qfuture.html#cancel)), for example:
This exception is thrown for promise created from a [`QFuture`](../qtconcurrent.md) which has been
canceled (e.g. using [`QFuture::cancel()`](http://doc.qt.io/qt-5/qfuture.html#cancel)), for example:
```cpp
auto output = QtPromise::resolve(future)

View File

@ -1,12 +1,9 @@
---
title: QPromiseContextException
---
# QPromiseContextException
*Since: 0.5.0*
When a promise is created using [`QtPromise::connect()`](../helpers/connect.md), this exception is thrown when the `sender` object is destroyed, for example:
When a promise is created using [`QtPromise::connect()`](../helpers/connect.md), this exception is
thrown when the `sender` object is destroyed, for example:
```cpp
auto promise = QtPromise::connect(sender, &Object::finished, &Object::error);

View File

@ -1,12 +1,9 @@
---
title: QPromiseTimeoutException
---
# QPromiseTimeoutException
*Since: 0.2.0*
This is the default exception thrown when reaching the time limit when using the [`QPromise::timeout()`](../qpromise/timeout.md) method, for example:
This is the default exception thrown when reaching the time limit when using the
[`QPromise::timeout()`](../qpromise/timeout.md) method, for example:
```cpp
QPromise<int> input = {...}

View File

@ -1,7 +1,3 @@
---
title: QPromiseUndefinedException
---
# QPromiseUndefinedException
*Since: 0.5.0*

View File

@ -2,11 +2,14 @@
## Installation
QtPromise is a [header-only](https://en.wikipedia.org/wiki/Header-only) library, simply download the [latest release](https://github.com/simonbrunel/qtpromise/releases/latest) (or [`git submodule`](https://git-scm.com/docs/git-submodule)) and include `qtpromise.pri` from your project `.pro`.
QtPromise is a [header-only](https://en.wikipedia.org/wiki/Header-only) library, simply download the
[latest release](https://github.com/simonbrunel/qtpromise/releases/latest) (or [`git submodule`](https://git-scm.com/docs/git-submodule))
and include `qtpromise.pri` from your project `.pro`.
### qpm
Alternatively and **only** if your project relies on [qpm](https://www.qpm.io/), you can install QtPromise as follow:
Alternatively and **only** if your project relies on [qpm](https://www.qpm.io/), you can install
QtPromise as follow:
```bash
qpm install com.github.simonbrunel.qtpromise
@ -28,7 +31,8 @@ Let's first make the code more readable by using the library namespace:
using namespace QtPromise;
```
This `download` function creates a [promise from callbacks](qpromise/constructor.md) which will be resolved when the network request is finished:
This `download` function creates a [promise from callbacks](qpromise/constructor.md) which will be
resolved when the network request is finished:
```cpp
QPromise<QByteArray> download(const QUrl& url)
@ -71,6 +75,7 @@ QPromise<Entries> uncompress(const QByteArray& data)
```
It's then easy to chain the whole asynchronous process using promises:
- initiate the promise chain by downloading a specific URL,
- [`then`](qpromise/then.md) *and only if download succeeded*, uncompress received data,
- [`then`](qpromise/then.md) validate and process the uncompressed entries,

View File

@ -6,14 +6,18 @@ title: all
*Since: 0.5.0*
```
```cpp
QtPromise::all(Sequence<QPromise<T>> promises) -> QPromise<QVector<T>>
QtPromise::all(Sequence<QPromise<void>> promises) -> QPromise<void>
```
Returns a `QPromise<QVector<T>>` (or `QPromise<void>`) that fulfills when **all** `promises` of (the same) type `T` have been fulfilled. The `output` value is a vector containing all the values of `promises`, in the same order, i.e., at the respective positions to the original sequence, regardless of completion order.
Returns a `QPromise<QVector<T>>` (or `QPromise<void>`) that fulfills when **all** `promises` of
(the same) type `T` have been fulfilled. The `output` value is a vector containing all the values
of `promises`, in the same order, i.e., at the respective positions to the original sequence,
regardless of completion order.
If any of the given `promises` fail, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If any of the given `promises` fail, `output` immediately rejects with the error of the promise that
rejected, whether or not the other promises are resolved.
`Sequence` is any STL compatible container (eg. `QVector`, `QList`, `std::vector`, etc.)

View File

@ -13,9 +13,14 @@ QtPromise::attempt(Functor functor, Args...) -> QPromise<R>
// - Functor: Function(Args...) -> R | QPromise<R>
```
Calls `functor` immediately and returns a promise fulfilled with the value returned by `functor`. Any synchronous exceptions will be turned into rejections on the returned promise. This is a convenient method that can be used instead of handling both synchronous and asynchronous exception flows.
Calls `functor` immediately and returns a promise fulfilled with the value returned by `functor`.
Any synchronous exceptions will be turned into rejections on the returned promise. This is a
convenient method that can be used instead of handling both synchronous and asynchronous exception
flows.
The type `R` of the `output` promise depends on the type returned by the `functor` function. If `functor` returns a promise (or `QFuture`), the `output` promise is delayed and will be resolved by the returned promise.
The type `R` of the `output` promise depends on the type returned by the `functor` function. If
`functor` returns a promise (or `QFuture`), the `output` promise is delayed and will be resolved
by the returned promise.
```cpp
QPromise<QByteArray> download(const QUrl& url);

View File

@ -12,11 +12,16 @@ title: connect
(3) QtPromise::connect(QObject* sender, Signal(T) resolver, QObject* sender2, Signal(R) rejecter) -> QPromise<T>
```
Creates a `QPromise<T>` that will be fulfilled with the `resolver` signal's first argument, or a `QPromise<void>` if `resolver` doesn't provide any argument.
Creates a `QPromise<T>` that will be fulfilled with the `resolver` signal's first argument, or a
`QPromise<void>` if `resolver` doesn't provide any argument.
The second `(2)` and third `(3)` variants of this method will reject the `output` promise when the `rejecter` signal is emitted. The rejection reason is the value of the `rejecter` signal's first argument or [`QPromiseUndefinedException`](../exceptions/undefined) if `rejected` doesn't provide any argument.
The second `(2)` and third `(3)` variants of this method will reject the `output` promise when the
`rejecter` signal is emitted. The rejection reason is the value of the `rejecter` signal's first
argument or [`QPromiseUndefinedException`](../exceptions/undefined) if `rejected` doesn't provide
any argument.
Additionally, the `output` promise will be automatically rejected with [`QPromiseContextException`](../exceptions/context.md) if `sender` is destroyed before the promise is resolved (that doesn't apply to `sender2`).
Additionally, the `output` promise will be automatically rejected with [`QPromiseContextException`](../exceptions/context.md)
if `sender` is destroyed before the promise is resolved (that doesn't apply to `sender2`).
```cpp
class Sender : public QObject

View File

@ -14,9 +14,12 @@ QtPromise::each(Sequence<T> values, Functor functor) -> QPromise<Sequence<T>>
// - Functor: Function(T value, int index) -> void | QPromise<void>
```
Calls the given `functor` on each element in `values` then resolves to the original sequence unmodified. If `functor` throws, `output` is rejected with the new exception.
Calls the given `functor` on each element in `values` then resolves to the original sequence
unmodified. If `functor` throws, `output` is rejected with the new exception.
If `functor` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises are resolved. If any of the promises fail, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If `functor` returns a promise (or `QFuture`), the `output` promise is delayed until all the
promises are resolved. If any of the promises fail, `output` immediately rejects with the error
of the promise that rejected, whether or not the other promises are resolved.
```cpp
auto output = QtPromise::each(QVector<QUrl>{

View File

@ -14,9 +14,14 @@ QtPromise::filter(Sequence<T> values, Filterer filterer) -> QPromise<Sequence<T>
// - Filterer: Function(T value, int index) -> bool
```
Iterates over `values` and [filters the sequence](https://en.wikipedia.org/wiki/Filter_%28higher-order_function%29) to another using the given `filterer` function. If `filterer` returns `true`, a copy of the item is put in the `output` sequence, otherwise, the item will not appear in `output`. If `filterer` throws, `output` is rejected with the new exception.
Iterates over `values` and [filters the sequence](https://en.wikipedia.org/wiki/Filter_%28higher-order_function%29)
to another using the given `filterer` function. If `filterer` returns `true`, a copy of the item
is put in the `output` sequence, otherwise, the item will not appear in `output`. If `filterer`
throws, `output` is rejected with the new exception.
If `filterer` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises are resolved. If any of the promises fail, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If `filterer` returns a promise (or `QFuture`), the `output` promise is delayed until all the
promises are resolved. If any of the promises fail, `output` immediately rejects with the error
of the promise that rejected, whether or not the other promises are resolved.
```cpp
auto output = QtPromise::filter(QVector{
@ -40,7 +45,8 @@ output.then([](const QVector<QUrl>& res) {
```
::: tip NOTE
The order of the output sequence values is guarantee to be the same as the original sequence, regardless of completion order of the promises returned by `filterer`.
The order of the output sequence values is guarantee to be the same as the original sequence,
regardless of completion order of the promises returned by `filterer`.
:::
See also: [`QPromise<T>::filter`](../qpromise/filter.md)

View File

@ -14,9 +14,13 @@ QtPromise::map(Sequence<T> values, Mapper mapper) -> QPromise<QVector<R>>
// - Mapper: Function(T value, int index) -> R | QPromise<R>
```
Iterates over `values` and [maps the sequence](https://en.wikipedia.org/wiki/Map_%28higher-order_function%29) to another using the given `mapper` function. The type returned by `mapper` determines the type of the `output` promise. If `mapper` throws, `output` is rejected with the new exception.
Iterates over `values` and [maps the sequence](https://en.wikipedia.org/wiki/Map_%28higher-order_function%29)
to another using the given `mapper` function. The type returned by `mapper` determines the type of
the `output` promise. If `mapper` throws, `output` is rejected with the new exception.
If `mapper` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises are resolved. If any of the promises fails, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If `mapper` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises
are resolved. If any of the promises fails, `output` immediately rejects with the error of the
promise that rejected, whether or not the other promises are resolved.
```cpp
auto output = QtPromise::map(QVector{
@ -40,7 +44,8 @@ output.then([](const QVector<QByteArray>& res) {
```
::: tip NOTE
The order of the output sequence values is guarantee to be the same as the original sequence, regardless of completion order of the promises returned by `mapper`.
The order of the output sequence values is guarantee to be the same as the original sequence,
regardless of completion order of the promises returned by `mapper`.
:::
See also: [`QPromise<T>::map`](../qpromise/map.md)

View File

@ -15,9 +15,15 @@ QPromise::reduce(Sequence<T|QPromise<T>> values, Reducer reducer, R|QPromise<R>
// - Reducer: Function(T|R accumulator, T item, int index) -> R|QPromise<R>
```
Iterates over `values` and [reduces the sequence to a single value](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29) using the given `reducer` function and an optional `initialValue`. The type returned by `reducer` determines the type of the `output` promise. If `reducer` throws, `output` is rejected with the new exception.
Iterates over `values` and [reduces the sequence to a single value](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29)
using the given `reducer` function and an optional `initialValue`. The type returned by `reducer`
determines the type of the `output` promise. If `reducer` throws, `output` is rejected with the
new exception.
If `reducer` returns a promise (or `QFuture`), then the result of the promise is awaited, before continuing with next iteration. If any promise in the `values` sequence is rejected or a promise returned by the `reducer` function is rejected, `output` immediately rejects with the error of the promise that rejected.
If `reducer` returns a promise (or `QFuture`), then the result of the promise is awaited, before
continuing with next iteration. If any promise in the `values` sequence is rejected or a promise
returned by the `reducer` function is rejected, `output` immediately rejects with the error of
the promise that rejected.
```cpp
// Concatenate the content of the given files, read asynchronously
@ -42,7 +48,8 @@ output.then([](const QString& res) {
```
::: warning IMPORTANT
The first time `reducer` is called, if no `initialValue` is provided, `accumulator` will be equal to the first value in the sequence, and `currentValue` to the second one (thus index will be `1`).
The first time `reducer` is called, if no `initialValue` is provided, `accumulator` will be equal
to the first value in the sequence, and `currentValue` to the second one (thus index will be `1`).
:::
See also: [`QPromise<T>::reduce`](../qpromise/reduce.md)

View File

@ -6,11 +6,12 @@ title: resolve
*Since: 0.5.0*
```
```cpp
QtPromise::resolve(T value) -> QPromise<R>
```
Similar to the [`QPromise<T>::resolve`](../qpromise/resolve.md) static method, creates a promise resolved from a given `value` but without the extra typing:
Similar to the [`QPromise<T>::resolve`](../qpromise/resolve.md) static method, creates a promise
resolved from a given `value` but without the extra typing:
```cpp
auto promise = QtPromise::resolve(); // QPromise<void>
@ -18,4 +19,5 @@ auto promise = QtPromise::resolve(42); // QPromise<int>
auto promise = QtPromise::resolve(QString("foo")); // QPromise<QString>
```
This method also allows to convert `QFuture<T>` to `QPromise<T>`, delayed until the `QFuture` is finished ([read more](../qtconcurrent.md#convert)).
This method also allows to convert `QFuture<T>` to `QPromise<T>`, delayed until the `QFuture` is
finished ([read more](../qtconcurrent.md#convert)).

View File

@ -1,34 +0,0 @@
---
title: ::all [static]
---
# QPromise::all [static]
*Since: 0.1.0*
```
[static] QPromise<T>::all(Sequence<QPromise<T>> promises) -> QPromise<QVector<T>>
```
Returns a `QPromise<QVector<T>>` that fulfills when **all** `promises` of (the same) type `T` have been fulfilled. The `output` value is a vector containing all the values of `promises`, in the same order, i.e., at the respective positions to the original sequence, regardless of completion order.
If any of the given `promises` fail, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
`Sequence` is any STL compatible container (eg. `QVector`, `QList`, `std::vector`, etc.)
```cpp
QVector<QPromise<QByteArray> > promises{
download(QUrl("http://a...")),
download(QUrl("http://b...")),
download(QUrl("http://c..."))
};
auto output = QPromise<QByteArray>::all(promises);
// output type: QPromise<QVector<QByteArray>>
output.then([](const QVector<QByteArray>& res) {
// {...}
});
```
See also: [`QtPromise::all`](../helpers/all.md)

View File

@ -25,10 +25,11 @@ QPromise<int> promise([](const QPromiseResolve<int>& resolve, const QPromiseReje
```
::: tip NOTE
`QPromise<void>` is specialized to not contain any value, meaning that the `resolve` callback takes no argument.
`QPromise<void>` is specialized to not contain any value, meaning that the `resolve` callback takes
no argument.
:::
**C++14**
C++14 alternative:
```cpp
QPromise<int> promise([](const auto& resolve, const auto& reject) {
@ -36,11 +37,13 @@ QPromise<int> promise([](const auto& resolve, const auto& reject) {
});
```
**Undefined rejection reason**
## Undefined rejection reason
*Since: 0.5.0*
While not recommended because it makes tracking errors more difficult, it's also possible to reject a promise without explicit reason, in which case, a built-in [`QPromiseUndefinedException`](../exceptions/undefined.md) is thrown:
While not recommended because it makes tracking errors more difficult, it's also possible to reject
a promise without explicit reason, in which case, a built-in [`QPromiseUndefinedException`](../exceptions/undefined.md)
is thrown:
```cpp
QPromise<int> promise([](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {

View File

@ -10,7 +10,9 @@ title: .delay
QPromise<T>::delay(int msec) -> QPromise<T>
```
This method returns a promise that will be fulfilled with the same value as the `input` promise and after at least `msec` milliseconds. If the `input` promise is rejected, the `output` promise is immediately rejected with the same reason.
This method returns a promise that will be fulfilled with the same value as the `input` promise
and after at least `msec` milliseconds. If the `input` promise is rejected, the `output` promise
is immediately rejected with the same reason.
```cpp
QPromise<int> input = {...}

View File

@ -18,7 +18,9 @@ QPromise<Sequence<T>>::each(Functor functor) -> QPromise<Sequence<T>>
This method only applies to promise with sequence value.
:::
Calls the given `functor` on each element in the promise value (i.e. `Sequence<T>`), then resolves to the original sequence unmodified. If `functor` throws, `output` is rejected with the new exception.
Calls the given `functor` on each element in the promise value (i.e. `Sequence<T>`), then resolves
to the original sequence unmodified. If `functor` throws, `output` is rejected with the new
exception.
```cpp
QPromise<QList<QByteArray>> input = {...}
@ -33,7 +35,9 @@ output.then([](const QList<QByteArray>& res) {
});
```
If `functor` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises are resolved. If any of the promises fail, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If `functor` returns a promise (or `QFuture`), the `output` promise is delayed until all the
promises are resolved. If any of the promises fail, `output` immediately rejects with the error
of the promise that rejected, whether or not the other promises are resolved.
```cpp
QPromise<QList<QUrl>> input = {...}

View File

@ -18,9 +18,14 @@ QPromise<Sequence<T>>::filter(Filter filterer) -> QPromise<Sequence<T>>
This method only applies to promise with sequence value.
:::
Iterates over all the promise values (i.e. `Sequence<T>`) and [filters the sequence](https://en.wikipedia.org/wiki/Filter_%28higher-order_function%29) to another using the given `filterer` function. If `filterer` returns `true`, a copy of the item is put in the `output` sequence, otherwise, the item will not appear in `output`. If `filterer` throws, `output` is rejected with the new exception.
Iterates over all the promise values (i.e. `Sequence<T>`) and [filters the sequence](https://en.wikipedia.org/wiki/Filter_%28higher-order_function%29)
to another using the given `filterer` function. If `filterer` returns `true`, a copy of the item
is put in the `output` sequence, otherwise, the item will not appear in `output`. If `filterer`
throws, `output` is rejected with the new exception.
If `filterer` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises are resolved. If any of the promises fail, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If `filterer` returns a promise (or `QFuture`), the `output` promise is delayed until all the
promises are resolved. If any of the promises fail, `output` immediately rejects with the error
of the promise that rejected, whether or not the other promises are resolved.
```cpp
QPromise<QList<QUrl>> input = {...}
@ -43,7 +48,8 @@ output.then([](const QList<QUrl>& res) {
```
::: tip NOTE
The order of the output sequence values is guarantee to be the same as the original sequence, regardless of completion order of the promises returned by `filterer`.
The order of the output sequence values is guarantee to be the same as the original sequence,
regardless of completion order of the promises returned by `filterer`.
:::
See also: [`QtPromise::filter`](../helpers/filter.md)

View File

@ -10,7 +10,10 @@ title: .finally
QPromise<T>::finally(Function handler) -> QPromise<T>
```
This `handler` is **always** called, without any argument and whatever the `input` promise state (fulfilled or rejected). The `output` promise has the same type as the `input` one but also the same value or error. The finally `handler` **can not modify the fulfilled value** (the returned value is ignored), however, if `handler` throws, `output` is rejected with the new exception.
This `handler` is **always** called, without any argument and whatever the `input` promise state
(fulfilled or rejected). The `output` promise has the same type as the `input` one but also the
same value or error. The finally `handler` **can not modify the fulfilled value** (the returned
value is ignored), however, if `handler` throws, `output` is rejected with the new exception.
```cpp
auto output = input.finally([]() {
@ -18,4 +21,6 @@ auto output = input.finally([]() {
});
```
If `handler` returns a promise (or QFuture), the `output` promise is delayed until the returned promise is resolved and under the same conditions: the delayed value is ignored, the error transmitted to the `output` promise.
If `handler` returns a promise (or QFuture), the `output` promise is delayed until the returned
promise is resolved and under the same conditions: the delayed value is ignored, the error
transmitted to the `output` promise.

View File

@ -11,4 +11,3 @@ QPromise<T>::isRejected() -> bool
```
Returns `true` if the promise is rejected, otherwise returns `false`.

View File

@ -18,9 +18,13 @@ QPromise<Sequence<T>>::map(Mapper mapper) -> QPromise<QVector<R>>
This method only applies to promise with sequence value.
:::
Iterates over all the promise values (i.e. `Sequence<T>`) and [maps the sequence](https://en.wikipedia.org/wiki/Map_%28higher-order_function%29) to another using the given `mapper` function. The type returned by `mapper` determines the type of the `output` promise. If `mapper` throws, `output` is rejected with the new exception.
Iterates over all the promise values (i.e. `Sequence<T>`) and [maps the sequence](https://en.wikipedia.org/wiki/Map_%28higher-order_function%29)
to another using the given `mapper` function. The type returned by `mapper` determines the type of
the `output` promise. If `mapper` throws, `output` is rejected with the new exception.
If `mapper` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises are resolved. If any of the promises fails, `output` immediately rejects with the error of the promise that rejected, whether or not the other promises are resolved.
If `mapper` returns a promise (or `QFuture`), the `output` promise is delayed until all the promises
are resolved. If any of the promises fails, `output` immediately rejects with the error of the
promise that rejected, whether or not the other promises are resolved.
```cpp
QPromise<QList<QUrl>> input = {...}
@ -46,7 +50,8 @@ output.then([](const QVector<DownloadResult>& res) {
```
::: tip NOTE
The order of the output sequence values is guarantee to be the same as the original sequence, regardless of completion order of the promises returned by `mapper`.
The order of the output sequence values is guarantee to be the same as the original sequence,
regardless of completion order of the promises returned by `mapper`.
:::
This function is provided for convenience and is similar to:

View File

@ -19,9 +19,12 @@ QPromise<Sequence<T>>::reduce(Reducer reducer, R|QPromise<R> initialValue) -> QP
This method only applies to promise with sequence value.
:::
Iterates over all the promise values (i.e. `Sequence<T>`) and [reduces the sequence to a single value](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29) using the given `reducer` function and an optional `initialValue`. The type returned by `reducer` determines the type of the `output` promise.
Iterates over all the promise values (i.e. `Sequence<T>`) and [reduces the sequence](https://en.wikipedia.org/wiki/Fold_%28higher-order_function%29)
to a single value using the given `reducer` function and an optional `initialValue`. The type
returned by `reducer` determines the type of the `output` promise.
See [`QtPromise::reduce`](../helpers/reduce.md) for details, this method is provided for convenience and is similar to:
See [`QtPromise::reduce`](../helpers/reduce.md) for details, this method is provided for convenience
and is similar to:
```cpp
promise.then([](const T& values) {

View File

@ -1,13 +1,13 @@
---
title: ::reject [static]
title: ::reject (static)
---
# QPromise::reject [static]
# QPromise::reject (static)
*Since: 0.1.0*
```cpp
[static] QPromise<T>::reject(any reason) -> QPromise<T>
(static) QPromise<T>::reject(any reason) -> QPromise<T>
```
Creates a `QPromise<T>` that is rejected with the given `reason` of *whatever type*:

View File

@ -1,13 +1,13 @@
---
title: ::resolve [static]
title: ::resolve (static)
---
# QPromise::resolve [static]
# QPromise::resolve (static)
*Since: 0.1.0*
```
[static] QPromise<T>::resolve(T value) -> QPromise<T>
```cpp
(static) QPromise<T>::resolve(T value) -> QPromise<T>
```
Creates a `QPromise<T>` that is fulfilled with the given `value` of type `T`:

View File

@ -10,7 +10,10 @@ title: .tap
QPromise<T>::tap(Function handler) -> QPromise<T>
```
This `handler` allows to observe the value of the `input` promise, without changing the propagated value. The `output` promise will be resolved with the same value as the `input` promise (the `handler` returned value will be ignored). However, if `handler` throws, `output` is rejected with the new exception. Unlike [`finally`](finally.md), this handler is **not** called for rejections.
This `handler` allows to observe the value of the `input` promise, without changing the propagated
value. The `output` promise will be resolved with the same value as the `input` promise (the `handler`
returned value will be ignored). However, if `handler` throws, `output` is rejected with the new
exception. Unlike [`finally`](finally.md), this handler is **not** called for rejections.
```cpp
QPromise<int> input = {...}
@ -21,4 +24,6 @@ auto output = input.tap([](int res) {
});
```
If `handler` returns a promise (or QFuture), the `output` promise is delayed until the returned promise is resolved and under the same conditions: the delayed value is ignored, the error transmitted to the `output` promise.
If `handler` returns a promise (or QFuture), the `output` promise is delayed until the returned
promise is resolved and under the same conditions: the delayed value is ignored, the error
transmitted to the `output` promise.

View File

@ -10,7 +10,10 @@ title: .tapFail
QPromise<T>::tapFail(Function handler) -> QPromise<T>
```
This `handler` allows to observe errors of the `input` promise without handling them - similar to [`finally`](finally.md) but **only** called on rejections. The `output` promise has the same type as the `input` one but also the same value or error. However, if `handler` throws, `output` is rejected with the new exception.
This `handler` allows to observe errors of the `input` promise without handling them - similar to
[`finally`](finally.md) but **only** called on rejections. The `output` promise has the same type
as the `input` one but also the same value or error. However, if `handler` throws, `output` is
rejected with the new exception.
```cpp
QPromise<int> input = {...}
@ -24,4 +27,6 @@ auto output = input.tapFail([](Error err) {
});
```
If `handler` returns a promise (or QFuture), the `output` promise is delayed until the returned promise is resolved and under the same conditions: the delayed value is ignored, the error transmitted to the `output` promise.
If `handler` returns a promise (or QFuture), the `output` promise is delayed until the returned
promise is resolved and under the same conditions: the delayed value is ignored, the error
transmitted to the `output` promise.

View File

@ -24,7 +24,8 @@ auto output = input.then([](int res) {
```
::: tip NOTE
`onRejected` handler is optional, in which case `output` will be rejected with the same reason as `input`. Also note that it's recommended to use the [`fail`](fail.md) shorthand to handle errors.
`onRejected` handler is optional, in which case `output` will be rejected with the same reason as
`input`. Also note that it's recommended to use the [`fail`](fail.md) shorthand to handle errors.
:::
The type `<R>` of the `output` promise depends on the return type of the `onFulfilled` handler:
@ -42,7 +43,9 @@ output.then([](const QString& res) {
```
::: tip NOTE
Only `onFulfilled` can change the promise type, `onRejected` **must** return the same type as `onFulfilled`. That also means if `onFulfilled` is `nullptr`, `onRejected` must return the same type as the `input` promise.
Only `onFulfilled` can change the promise type, `onRejected` **must** return the same type as
`onFulfilled`. That also means if `onFulfilled` is `nullptr`, `onRejected` must return the same
type as the `input` promise.
:::
```cpp
@ -92,4 +95,5 @@ auto output = input.then([](int res) {
// output.isRejected() is true
```
If an handler returns a promise (or QFuture), the `output` promise is delayed and will be resolved by the returned promise.
If an handler returns a promise (or QFuture), the `output` promise is delayed and will be resolved
by the returned promise.

View File

@ -10,7 +10,10 @@ title: .timeout
QPromise<T>::timeout(int msec, any error = QPromiseTimeoutException) -> QPromise<T>
```
This method returns a promise that will be resolved with the `input` promise's fulfillment value or rejection reason. However, if the `input` promise is not fulfilled or rejected within `msec` milliseconds, the `output` promise is rejected with `error` as the reason ([`QPromiseTimeoutException`](../exceptions/timeout.md) by default).
This method returns a promise that will be resolved with the `input` promise's fulfillment value
or rejection reason. However, if the `input` promise is not fulfilled or rejected within `msec`
milliseconds, the `output` promise is rejected with `error` as the reason ([`QPromiseTimeoutException`](../exceptions/timeout.md)
by default).
```cpp
QPromise<int> input = {...}

View File

@ -10,7 +10,8 @@ title: .wait
QPromise<T>::wait() -> QPromise<T>
```
This method holds the execution of the remaining code until the `input` promise is resolved (either fulfilled or rejected), **without** blocking the event loop of the current thread:
This method holds the execution of the remaining code until the `input` promise is resolved (either
fulfilled or rejected), **without** blocking the event loop of the current thread:
```cpp
int result = -1;

View File

@ -1,10 +1,12 @@
# Qt Concurrent
QtPromise integrates with [QtConcurrent](https://doc.qt.io/qt-5/qtconcurrent-index.html) to make easy chaining QFuture with QPromise.
QtPromise integrates with [QtConcurrent](https://doc.qt.io/qt-5/qtconcurrent-index.html) to simplify
chaining QFuture with QPromise.
## <a name="qtconcurrent-convert"></a> Convert
## Convert
Converting `QFuture<T>` to `QPromise<T>` is done using the [`QtPromise::resolve`](helpers/resolve.md) helper:
Converting `QFuture<T>` to `QPromise<T>` is done using the [`QtPromise::resolve`](helpers/resolve.md)
helper:
```cpp
QFuture<int> future = QtConcurrent::run([]() {
@ -25,7 +27,8 @@ auto promise = QtPromise::resolve(QtConcurrent::run([]() {
## Chain
Returning a `QFuture<T>` in [`then`](qpromise/then.md) or [`fail`](qpromise/fail.md) automatically translate to `QPromise<T>`:
Returning a `QFuture<T>` in [`then`](qpromise/then.md) or [`fail`](qpromise/fail.md) automatically
translate to `QPromise<T>`:
```cpp
QPromise<int> input = ...
@ -46,7 +49,11 @@ The `output` promise is resolved when the `QFuture` is [finished](https://doc.qt
## Error
Exceptions thrown from a QtConcurrent thread reject the associated promise with the exception as the reason. Note that if you throw an exception that is not a subclass of `QException`, the promise will be rejected with [`QUnhandledException`](https://doc.qt.io/qt-5/qunhandledexception.html#details) (this restriction only applies to exceptions thrown from a QtConcurrent thread, [read more](https://doc.qt.io/qt-5/qexception.html#details)).
Exceptions thrown from a QtConcurrent thread reject the associated promise with the exception as the
reason. Note that if you throw an exception that is not a subclass of `QException`, the promise will
be rejected with [`QUnhandledException`](https://doc.qt.io/qt-5/qunhandledexception.html#details)
(this restriction only applies to exceptions thrown from a QtConcurrent thread,
[read more](https://doc.qt.io/qt-5/qexception.html#details)).
```cpp
QPromise<int> promise = ...

View File

@ -3,12 +3,15 @@
QtPromise supports creating promises that are resolved or rejected by regular [Qt signals](https://doc.qt.io/qt-5/signalsandslots.html).
::: warning IMPORTANT
A promise connected to a signal will be resolved (fulfilled or rejected) **only one time**, no matter if the signals are emitted multiple times. Internally, the promise is disconnected from all signals as soon as one signal is emitted.
A promise connected to a signal will be resolved (fulfilled or rejected) **only one time**, no
matter if the signals are emitted multiple times. Internally, the promise is disconnected from
all signals as soon as one signal is emitted.
:::
## Resolve Signal
The [`QtPromise::connect()`](helpers/connect.md) helper allows to create a promise resolved from a single signal:
The [`QtPromise::connect()`](helpers/connect.md) helper allows to create a promise resolved from
a single signal:
```cpp
// [signal] Object::finished(const QByteArray&)
@ -33,12 +36,14 @@ output.then([]() {
```
::: tip NOTE
QtPromise currently only supports single argument signals, which means that only the first argument is used to fulfill or reject the connected promise, other arguments being ignored.
QtPromise currently only supports single argument signals, which means that only the first argument
is used to fulfill or reject the connected promise, other arguments being ignored.
:::
## Reject Signal
The [`QtPromise::connect()`](helpers/connect.md) helper also allows to reject the promise from another signal:
The [`QtPromise::connect()`](helpers/connect.md) helper also allows to reject the promise from
another signal:
```cpp
// [signal] Object::finished(const QByteArray& data)
@ -53,8 +58,8 @@ output.then([](const QByteArray& data) {
});
```
If the rejection signal doesn't provide any argument, the promise will be rejected
with [`QPromiseUndefinedException`](../exceptions/undefined), for example:
If the rejection signal doesn't provide any argument, the promise will be rejected with
[`QPromiseUndefinedException`](../exceptions/undefined), for example:
```cpp
// [signal] Object::finished()
@ -84,6 +89,8 @@ output.then([](const QByteArray& data) {
});
```
Additionally to the rejection signal, promises created using [`QtPromise::connect()`](helpers/connect.md) are automatically rejected with [`QPromiseContextException`](exceptions/context.md) if the sender is destroyed before fulfilling the promise.
Additionally to the rejection signal, promises created using [`QtPromise::connect()`](helpers/connect.md)
are automatically rejected with [`QPromiseContextException`](exceptions/context.md) if the sender is
destroyed before fulfilling the promise.
See [`QtPromise::connect()`](helpers/connect.md) for more details.

View File

@ -1,7 +1,12 @@
# Thread-Safety
QPromise is thread-safe and can be copied and accessed across different threads. QPromise relies on [explicitly data sharing](https://doc.qt.io/qt-5/qexplicitlyshareddatapointer.html#details) and thus `auto p2 = p1` represents the same promise: when `p1` resolves, handlers registered on `p1` and `p2` are called, the fulfilled value being shared between both instances.
QPromise is thread-safe and can be copied and accessed across different threads. QPromise relies on
[explicitly data sharing](https://doc.qt.io/qt-5/qexplicitlyshareddatapointer.html#details) and thus
`auto p2 = p1` represents the same promise: when `p1` resolves, handlers registered on `p1` and `p2`
are called, the fulfilled value being shared between both instances.
::: warning IMPORTANT
While it's safe to access the resolved value from different threads using [`then`](qpromise/then.md), QPromise provides no guarantee about the object being pointed to. Thread-safety and reentrancy rules for that object still apply.
While it's safe to access the resolved value from different threads using [`then`](qpromise/then.md),
QPromise provides no guarantee about the object being pointed to. Thread-safety and reentrancy rules
for that object still apply.
:::

11703
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
package.json Normal file
View File

@ -0,0 +1,17 @@
{
"description": "qtpromise",
"private": true,
"scripts": {
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs",
"docs:lint": "remark --quiet --frail ."
},
"devDependencies": {
"@vuepress/plugin-google-analytics": "^1.2.0",
"remark-cli": "^7.0.1",
"remark-frontmatter": "^1.3.2",
"remark-preset-lint-markdown-style-guide": "^2.1.3",
"remark-preset-lint-recommended": "^3.0.3",
"vuepress": "^1.2.0"
}
}