mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2024-10-30 15:57:39 +08:00
Use clang-format for code style consistency
Based on the WebKit preset and following 'most' of the Qt guidelines, except a few rules that work better for promise continuation lambdas. Requires clang-format 11.
This commit is contained in:
parent
b99e468c84
commit
d43657fbd5
66
.clang-format
Normal file
66
.clang-format
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
Standard: Cpp11
|
||||||
|
BasedOnStyle: WebKit
|
||||||
|
AlignAfterOpenBracket: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
ColumnLimit: 100
|
||||||
|
CommentPragmas: "^!|^:"
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- BOOST_FOREACH
|
||||||
|
- foreach
|
||||||
|
- forever
|
||||||
|
- Q_FOREACH
|
||||||
|
- Q_FOREVER
|
||||||
|
- QBENCHMARK
|
||||||
|
- QBENCHMARK_ONCE
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<Q.*>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^<.*\.h>'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^<.*>'
|
||||||
|
Priority: 4
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
NamespaceIndentation: None
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 10
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
...
|
@ -19,27 +19,36 @@
|
|||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class QPromiseBase
|
class QPromiseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Type = T;
|
using Type = T;
|
||||||
|
|
||||||
template <typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 1, int>::type = 0>
|
template<typename F,
|
||||||
|
typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 1, int>::type = 0>
|
||||||
inline QPromiseBase(F resolver);
|
inline QPromiseBase(F resolver);
|
||||||
|
|
||||||
template <typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 2, int>::type = 0>
|
template<typename F,
|
||||||
|
typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 2, int>::type = 0>
|
||||||
inline QPromiseBase(F resolver);
|
inline QPromiseBase(F resolver);
|
||||||
|
|
||||||
QPromiseBase(const QPromiseBase<T>& other): m_d{other.m_d} {}
|
QPromiseBase(const QPromiseBase<T>& other) : m_d{other.m_d} { }
|
||||||
QPromiseBase(const QPromise<T>& other): m_d{other.m_d} {}
|
QPromiseBase(const QPromise<T>& other) : m_d{other.m_d} { }
|
||||||
QPromiseBase(QPromiseBase<T>&& other) Q_DECL_NOEXCEPT { swap(other); }
|
QPromiseBase(QPromiseBase<T>&& other) Q_DECL_NOEXCEPT { swap(other); }
|
||||||
|
|
||||||
virtual ~QPromiseBase() { }
|
virtual ~QPromiseBase() { }
|
||||||
|
|
||||||
QPromiseBase<T>& operator=(const QPromiseBase<T>& other) { m_d = other.m_d; return *this;}
|
QPromiseBase<T>& operator=(const QPromiseBase<T>& other)
|
||||||
|
{
|
||||||
|
m_d = other.m_d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
QPromiseBase<T>& operator=(QPromiseBase<T>&& other) Q_DECL_NOEXCEPT
|
QPromiseBase<T>& operator=(QPromiseBase<T>&& other) Q_DECL_NOEXCEPT
|
||||||
{ QPromiseBase<T>(std::move(other)).swap(*this); return *this; }
|
{
|
||||||
|
QPromiseBase<T>(std::move(other)).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const QPromiseBase<T>& other) const { return (m_d == other.m_d); }
|
bool operator==(const QPromiseBase<T>& other) const { return (m_d == other.m_d); }
|
||||||
bool operator!=(const QPromiseBase<T>& other) const { return (m_d != other.m_d); }
|
bool operator!=(const QPromiseBase<T>& other) const { return (m_d != other.m_d); }
|
||||||
@ -50,31 +59,31 @@ public:
|
|||||||
bool isRejected() const { return m_d->isRejected(); }
|
bool isRejected() const { return m_d->isRejected(); }
|
||||||
bool isPending() const { return m_d->isPending(); }
|
bool isPending() const { return m_d->isPending(); }
|
||||||
|
|
||||||
template <typename TFulfilled, typename TRejected>
|
template<typename TFulfilled, typename TRejected>
|
||||||
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
||||||
then(const TFulfilled& fulfilled, const TRejected& rejected) const;
|
then(const TFulfilled& fulfilled, const TRejected& rejected) const;
|
||||||
|
|
||||||
template <typename TFulfilled>
|
template<typename TFulfilled>
|
||||||
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
||||||
then(TFulfilled&& fulfilled) const;
|
then(TFulfilled&& fulfilled) const;
|
||||||
|
|
||||||
template <typename TRejected>
|
template<typename TRejected>
|
||||||
inline typename QtPromisePrivate::PromiseHandler<T, std::nullptr_t>::Promise
|
inline typename QtPromisePrivate::PromiseHandler<T, std::nullptr_t>::Promise
|
||||||
fail(TRejected&& rejected) const;
|
fail(TRejected&& rejected) const;
|
||||||
|
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
inline QPromise<T> finally(THandler handler) const;
|
inline QPromise<T> finally(THandler handler) const;
|
||||||
|
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
inline QPromise<T> tap(THandler handler) const;
|
inline QPromise<T> tap(THandler handler) const;
|
||||||
|
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
inline QPromise<T> tapFail(THandler handler) const;
|
inline QPromise<T> tapFail(THandler handler) const;
|
||||||
|
|
||||||
template <typename E = QPromiseTimeoutException>
|
template<typename E = QPromiseTimeoutException>
|
||||||
inline QPromise<T> timeout(int msec, E&& error = E{}) const;
|
inline QPromise<T> timeout(int msec, E&& error = E{}) const;
|
||||||
|
|
||||||
template <typename E = QPromiseTimeoutException>
|
template<typename E = QPromiseTimeoutException>
|
||||||
inline QPromise<T> timeout(std::chrono::milliseconds msec, E&& error = E{}) const;
|
inline QPromise<T> timeout(std::chrono::milliseconds msec, E&& error = E{}) const;
|
||||||
|
|
||||||
inline QPromise<T> delay(int msec) const;
|
inline QPromise<T> delay(int msec) const;
|
||||||
@ -83,7 +92,7 @@ public:
|
|||||||
inline QPromise<T> wait() const;
|
inline QPromise<T> wait() const;
|
||||||
|
|
||||||
public: // STATIC
|
public: // STATIC
|
||||||
template <typename E>
|
template<typename E>
|
||||||
inline static QPromise<T> reject(E&& error);
|
inline static QPromise<T> reject(E&& error);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -94,39 +103,35 @@ protected:
|
|||||||
QExplicitlySharedDataPointer<QtPromisePrivate::PromiseData<T>> m_d;
|
QExplicitlySharedDataPointer<QtPromisePrivate::PromiseData<T>> m_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class QPromise : public QPromiseBase<T>
|
class QPromise : public QPromiseBase<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename F>
|
template<typename F>
|
||||||
QPromise(F&& resolver): QPromiseBase<T>(std::forward<F>(resolver)) { }
|
QPromise(F&& resolver) : QPromiseBase<T>(std::forward<F>(resolver))
|
||||||
|
{ }
|
||||||
|
|
||||||
template <typename Functor>
|
template<typename Functor>
|
||||||
inline QPromise<T>
|
inline QPromise<T> each(Functor fn);
|
||||||
each(Functor fn);
|
|
||||||
|
|
||||||
template <typename Functor>
|
template<typename Functor>
|
||||||
inline QPromise<T>
|
inline QPromise<T> filter(Functor fn);
|
||||||
filter(Functor fn);
|
|
||||||
|
|
||||||
template <typename Functor>
|
template<typename Functor>
|
||||||
inline typename QtPromisePrivate::PromiseMapper<T, Functor>::PromiseType
|
inline typename QtPromisePrivate::PromiseMapper<T, Functor>::PromiseType map(Functor fn);
|
||||||
map(Functor fn);
|
|
||||||
|
|
||||||
template <typename Functor, typename Input>
|
template<typename Functor, typename Input>
|
||||||
inline typename QtPromisePrivate::PromiseDeduce<Input>::Type
|
inline typename QtPromisePrivate::PromiseDeduce<Input>::Type reduce(Functor fn, Input initial);
|
||||||
reduce(Functor fn, Input initial);
|
|
||||||
|
|
||||||
template <typename Functor, typename U = T>
|
template<typename Functor, typename U = T>
|
||||||
inline typename QtPromisePrivate::PromiseDeduce<typename U::value_type>::Type
|
inline typename QtPromisePrivate::PromiseDeduce<typename U::value_type>::Type
|
||||||
reduce(Functor fn);
|
reduce(Functor fn);
|
||||||
|
|
||||||
public: // STATIC
|
public: // STATIC
|
||||||
|
|
||||||
// DEPRECATED (remove at version 1)
|
// DEPRECATED (remove at version 1)
|
||||||
template <template <typename, typename...> class Sequence = QVector, typename ...Args>
|
template<template<typename, typename...> class Sequence = QVector, typename... Args>
|
||||||
Q_DECL_DEPRECATED_X("Use QtPromise::all instead") static inline QPromise<QVector<T>>
|
Q_DECL_DEPRECATED_X("Use QtPromise::all instead")
|
||||||
all(const Sequence<QPromise<T>, Args...>& promises);
|
static inline QPromise<QVector<T>> all(const Sequence<QPromise<T>, Args...>& promises);
|
||||||
|
|
||||||
inline static QPromise<T> resolve(const T& value);
|
inline static QPromise<T> resolve(const T& value);
|
||||||
inline static QPromise<T> resolve(T&& value);
|
inline static QPromise<T> resolve(T&& value);
|
||||||
@ -135,19 +140,19 @@ private:
|
|||||||
friend class QPromiseBase<T>;
|
friend class QPromiseBase<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
class QPromise<void> : public QPromiseBase<void>
|
class QPromise<void> : public QPromiseBase<void>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename F>
|
template<typename F>
|
||||||
QPromise(F&& resolver): QPromiseBase<void>(std::forward<F>(resolver)) { }
|
QPromise(F&& resolver) : QPromiseBase<void>(std::forward<F>(resolver))
|
||||||
|
{ }
|
||||||
|
|
||||||
public: // STATIC
|
public: // STATIC
|
||||||
|
|
||||||
// DEPRECATED (remove at version 1)
|
// DEPRECATED (remove at version 1)
|
||||||
template <template <typename, typename...> class Sequence = QVector, typename ...Args>
|
template<template<typename, typename...> class Sequence = QVector, typename... Args>
|
||||||
Q_DECL_DEPRECATED_X("Use QtPromise::all instead") static inline QPromise<void>
|
Q_DECL_DEPRECATED_X("Use QtPromise::all instead")
|
||||||
all(const Sequence<QPromise<void>, Args...>& promises);
|
static inline QPromise<void> all(const Sequence<QPromise<void>, Args...>& promises);
|
||||||
|
|
||||||
inline static QPromise<void> resolve();
|
inline static QPromise<void> resolve();
|
||||||
|
|
||||||
|
@ -14,10 +14,9 @@
|
|||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 1, int>::type>
|
template<typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 1, int>::type>
|
||||||
inline QPromiseBase<T>::QPromiseBase(F callback)
|
inline QPromiseBase<T>::QPromiseBase(F callback) : m_d{new QtPromisePrivate::PromiseData<T>{}}
|
||||||
: m_d{new QtPromisePrivate::PromiseData<T>{}}
|
|
||||||
{
|
{
|
||||||
QtPromisePrivate::PromiseResolver<T> resolver{*this};
|
QtPromisePrivate::PromiseResolver<T> resolver{*this};
|
||||||
|
|
||||||
@ -28,10 +27,9 @@ inline QPromiseBase<T>::QPromiseBase(F callback)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 2, int>::type>
|
template<typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count == 2, int>::type>
|
||||||
inline QPromiseBase<T>::QPromiseBase(F callback)
|
inline QPromiseBase<T>::QPromiseBase(F callback) : m_d{new QtPromisePrivate::PromiseData<T>{}}
|
||||||
: m_d{new QtPromisePrivate::PromiseData<T>{}}
|
|
||||||
{
|
{
|
||||||
QtPromisePrivate::PromiseResolver<T> resolver{*this};
|
QtPromisePrivate::PromiseResolver<T> resolver{*this};
|
||||||
|
|
||||||
@ -42,17 +40,16 @@ inline QPromiseBase<T>::QPromiseBase(F callback)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename TFulfilled, typename TRejected>
|
template<typename TFulfilled, typename TRejected>
|
||||||
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
||||||
QPromiseBase<T>::then(const TFulfilled& fulfilled, const TRejected& rejected) const
|
QPromiseBase<T>::then(const TFulfilled& fulfilled, const TRejected& rejected) const
|
||||||
{
|
{
|
||||||
using namespace QtPromisePrivate;
|
using namespace QtPromisePrivate;
|
||||||
using PromiseType = typename PromiseHandler<T, TFulfilled>::Promise;
|
using PromiseType = typename PromiseHandler<T, TFulfilled>::Promise;
|
||||||
|
|
||||||
PromiseType next([&](
|
PromiseType next([&](const QPromiseResolve<typename PromiseType::Type>& resolve,
|
||||||
const QPromiseResolve<typename PromiseType::Type>& resolve,
|
const QPromiseReject<typename PromiseType::Type>& reject) {
|
||||||
const QPromiseReject<typename PromiseType::Type>& reject) {
|
|
||||||
m_d->addHandler(PromiseHandler<T, TFulfilled>::create(fulfilled, resolve, reject));
|
m_d->addHandler(PromiseHandler<T, TFulfilled>::create(fulfilled, resolve, reject));
|
||||||
m_d->addCatcher(PromiseCatcher<T, TRejected>::create(rejected, resolve, reject));
|
m_d->addCatcher(PromiseCatcher<T, TRejected>::create(rejected, resolve, reject));
|
||||||
});
|
});
|
||||||
@ -64,24 +61,24 @@ QPromiseBase<T>::then(const TFulfilled& fulfilled, const TRejected& rejected) co
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename TFulfilled>
|
template<typename TFulfilled>
|
||||||
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
||||||
QPromiseBase<T>::then(TFulfilled&& fulfilled) const
|
QPromiseBase<T>::then(TFulfilled&& fulfilled) const
|
||||||
{
|
{
|
||||||
return then(std::forward<TFulfilled>(fulfilled), nullptr);
|
return then(std::forward<TFulfilled>(fulfilled), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename TRejected>
|
template<typename TRejected>
|
||||||
inline typename QtPromisePrivate::PromiseHandler<T, std::nullptr_t>::Promise
|
inline typename QtPromisePrivate::PromiseHandler<T, std::nullptr_t>::Promise
|
||||||
QPromiseBase<T>::fail(TRejected&& rejected) const
|
QPromiseBase<T>::fail(TRejected&& rejected) const
|
||||||
{
|
{
|
||||||
return then(nullptr, std::forward<TRejected>(rejected));
|
return then(nullptr, std::forward<TRejected>(rejected));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
inline QPromise<T> QPromiseBase<T>::finally(THandler handler) const
|
inline QPromise<T> QPromiseBase<T>::finally(THandler handler) const
|
||||||
{
|
{
|
||||||
QPromise<T> p = *this;
|
QPromise<T> p = *this;
|
||||||
@ -90,8 +87,8 @@ inline QPromise<T> QPromiseBase<T>::finally(THandler handler) const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
inline QPromise<T> QPromiseBase<T>::tap(THandler handler) const
|
inline QPromise<T> QPromiseBase<T>::tap(THandler handler) const
|
||||||
{
|
{
|
||||||
QPromise<T> p = *this;
|
QPromise<T> p = *this;
|
||||||
@ -100,25 +97,22 @@ inline QPromise<T> QPromiseBase<T>::tap(THandler handler) const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
inline QPromise<T> QPromiseBase<T>::tapFail(THandler handler) const
|
inline QPromise<T> QPromiseBase<T>::tapFail(THandler handler) const
|
||||||
{
|
{
|
||||||
QPromise<T> p = *this;
|
QPromise<T> p = *this;
|
||||||
return p.then([](){}, handler).then([=]() {
|
return p.then([]() {}, handler).then([=]() {
|
||||||
return p;
|
return p;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename E>
|
template<typename E>
|
||||||
inline QPromise<T> QPromiseBase<T>::timeout(int msec, E&& error) const
|
inline QPromise<T> QPromiseBase<T>::timeout(int msec, E&& error) const
|
||||||
{
|
{
|
||||||
QPromise<T> p = *this;
|
QPromise<T> p = *this;
|
||||||
return QPromise<T>{[&](
|
return QPromise<T>{[&](const QPromiseResolve<T>& resolve, const QPromiseReject<T>& reject) {
|
||||||
const QPromiseResolve<T>& resolve,
|
|
||||||
const QPromiseReject<T>& reject) {
|
|
||||||
|
|
||||||
QTimer::singleShot(msec, [=]() {
|
QTimer::singleShot(msec, [=]() {
|
||||||
// we don't need to verify the current promise state, reject()
|
// we don't need to verify the current promise state, reject()
|
||||||
// takes care of checking if the promise is already resolved,
|
// takes care of checking if the promise is already resolved,
|
||||||
@ -130,14 +124,14 @@ inline QPromise<T> QPromiseBase<T>::timeout(int msec, E&& error) const
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename E>
|
template<typename E>
|
||||||
inline QPromise<T> QPromiseBase<T>::timeout(std::chrono::milliseconds msec, E&& error) const
|
inline QPromise<T> QPromiseBase<T>::timeout(std::chrono::milliseconds msec, E&& error) const
|
||||||
{
|
{
|
||||||
return timeout(static_cast<int>(msec.count()), std::forward<E>(error));
|
return timeout(static_cast<int>(msec.count()), std::forward<E>(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline QPromise<T> QPromiseBase<T>::delay(int msec) const
|
inline QPromise<T> QPromiseBase<T>::delay(int msec) const
|
||||||
{
|
{
|
||||||
return tap([=]() {
|
return tap([=]() {
|
||||||
@ -153,7 +147,7 @@ inline QPromise<T> QPromiseBase<T>::delay(std::chrono::milliseconds msec) const
|
|||||||
return delay(static_cast<int>(msec.count()));
|
return delay(static_cast<int>(msec.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline QPromise<T> QPromiseBase<T>::wait() const
|
inline QPromise<T> QPromiseBase<T>::wait() const
|
||||||
{
|
{
|
||||||
// @TODO wait timeout + global timeout
|
// @TODO wait timeout + global timeout
|
||||||
@ -165,8 +159,8 @@ inline QPromise<T> QPromiseBase<T>::wait() const
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename E>
|
template<typename E>
|
||||||
inline QPromise<T> QPromiseBase<T>::reject(E&& error)
|
inline QPromise<T> QPromiseBase<T>::reject(E&& error)
|
||||||
{
|
{
|
||||||
return QPromise<T>{[&](const QPromiseResolve<T>&, const QPromiseReject<T>& reject) {
|
return QPromise<T>{[&](const QPromiseResolve<T>&, const QPromiseReject<T>& reject) {
|
||||||
@ -174,8 +168,8 @@ inline QPromise<T> QPromiseBase<T>::reject(E&& error)
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename Functor>
|
template<typename Functor>
|
||||||
inline QPromise<T> QPromise<T>::each(Functor fn)
|
inline QPromise<T> QPromise<T>::each(Functor fn)
|
||||||
{
|
{
|
||||||
return this->tap([=](const T& values) {
|
return this->tap([=](const T& values) {
|
||||||
@ -183,12 +177,10 @@ inline QPromise<T> QPromise<T>::each(Functor fn)
|
|||||||
|
|
||||||
std::vector<QPromise<void>> promises;
|
std::vector<QPromise<void>> promises;
|
||||||
for (const auto& v : values) {
|
for (const auto& v : values) {
|
||||||
promises.push_back(
|
promises.push_back(QtPromise::attempt(fn, v, i).then([]() {
|
||||||
QtPromise::attempt(fn, v, i)
|
// Cast to void in case fn returns a non promise value.
|
||||||
.then([]() {
|
// TODO remove when implicit cast is implemented.
|
||||||
// Cast to void in case fn returns a non promise value.
|
}));
|
||||||
// TODO remove when implicit cast is implemented.
|
|
||||||
}));
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -197,8 +189,8 @@ inline QPromise<T> QPromise<T>::each(Functor fn)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename Functor>
|
template<typename Functor>
|
||||||
inline QPromise<T> QPromise<T>::filter(Functor fn)
|
inline QPromise<T> QPromise<T>::filter(Functor fn)
|
||||||
{
|
{
|
||||||
return this->then([=](const T& values) {
|
return this->then([=](const T& values) {
|
||||||
@ -206,8 +198,8 @@ inline QPromise<T> QPromise<T>::filter(Functor fn)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename Functor>
|
template<typename Functor>
|
||||||
inline typename QtPromisePrivate::PromiseMapper<T, Functor>::PromiseType
|
inline typename QtPromisePrivate::PromiseMapper<T, Functor>::PromiseType
|
||||||
QPromise<T>::map(Functor fn)
|
QPromise<T>::map(Functor fn)
|
||||||
{
|
{
|
||||||
@ -216,8 +208,8 @@ QPromise<T>::map(Functor fn)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename Functor, typename Input>
|
template<typename Functor, typename Input>
|
||||||
inline typename QtPromisePrivate::PromiseDeduce<Input>::Type
|
inline typename QtPromisePrivate::PromiseDeduce<Input>::Type
|
||||||
QPromise<T>::reduce(Functor fn, Input initial)
|
QPromise<T>::reduce(Functor fn, Input initial)
|
||||||
{
|
{
|
||||||
@ -226,8 +218,8 @@ QPromise<T>::reduce(Functor fn, Input initial)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <typename Functor, typename U>
|
template<typename Functor, typename U>
|
||||||
inline typename QtPromisePrivate::PromiseDeduce<typename U::value_type>::Type
|
inline typename QtPromisePrivate::PromiseDeduce<typename U::value_type>::Type
|
||||||
QPromise<T>::reduce(Functor fn)
|
QPromise<T>::reduce(Functor fn)
|
||||||
{
|
{
|
||||||
@ -236,30 +228,30 @@ QPromise<T>::reduce(Functor fn)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
template <template <typename, typename...> class Sequence, typename ...Args>
|
template<template<typename, typename...> class Sequence, typename... Args>
|
||||||
inline QPromise<QVector<T>> QPromise<T>::all(const Sequence<QPromise<T>, Args...>& promises)
|
inline QPromise<QVector<T>> QPromise<T>::all(const Sequence<QPromise<T>, Args...>& promises)
|
||||||
{
|
{
|
||||||
return QtPromise::all(promises);
|
return QtPromise::all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline QPromise<T> QPromise<T>::resolve(const T& value)
|
inline QPromise<T> QPromise<T>::resolve(const T& value)
|
||||||
{
|
{
|
||||||
return QPromise<T>{[&](const QPromiseResolve<T>& resolve) {
|
return QPromise<T>{[&](const QPromiseResolve<T>& resolve) {
|
||||||
resolve(value);
|
resolve(value);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
inline QPromise<T> QPromise<T>::resolve(T&& value)
|
inline QPromise<T> QPromise<T>::resolve(T&& value)
|
||||||
{
|
{
|
||||||
return QPromise<T>{[&](const QPromiseResolve<T>& resolve) {
|
return QPromise<T>{[&](const QPromiseResolve<T>& resolve) {
|
||||||
resolve(std::forward<T>(value));
|
resolve(std::forward<T>(value));
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename, typename...> class Sequence, typename ...Args>
|
template<template<typename, typename...> class Sequence, typename... Args>
|
||||||
inline QPromise<void> QPromise<void>::all(const Sequence<QPromise<void>, Args...>& promises)
|
inline QPromise<void> QPromise<void>::all(const Sequence<QPromise<void>, Args...>& promises)
|
||||||
{
|
{
|
||||||
return QtPromise::all(promises);
|
return QtPromise::all(promises);
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class QPromise;
|
class QPromise;
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class QPromiseResolve;
|
class QPromiseResolve;
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class QPromiseReject;
|
class QPromiseReject;
|
||||||
|
|
||||||
} // namespace QtPromise
|
} // namespace QtPromise
|
||||||
@ -35,7 +35,7 @@ class QPromiseReject;
|
|||||||
namespace QtPromisePrivate {
|
namespace QtPromisePrivate {
|
||||||
|
|
||||||
// https://stackoverflow.com/a/21653558
|
// https://stackoverflow.com/a/21653558
|
||||||
template <typename F>
|
template<typename F>
|
||||||
static void qtpromise_defer(F&& f, const QPointer<QThread>& thread)
|
static void qtpromise_defer(F&& f, const QPointer<QThread>& thread)
|
||||||
{
|
{
|
||||||
using FType = typename std::decay<F>::type;
|
using FType = typename std::decay<F>::type;
|
||||||
@ -69,14 +69,14 @@ static void qtpromise_defer(F&& f, const QPointer<QThread>& thread)
|
|||||||
QCoreApplication::postEvent(target, new Event{std::forward<F>(f)});
|
QCoreApplication::postEvent(target, new Event{std::forward<F>(f)});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template<typename F>
|
||||||
static void qtpromise_defer(F&& f)
|
static void qtpromise_defer(F&& f)
|
||||||
{
|
{
|
||||||
Q_ASSERT(QThread::currentThread());
|
Q_ASSERT(QThread::currentThread());
|
||||||
qtpromise_defer(std::forward<F>(f), QThread::currentThread());
|
qtpromise_defer(std::forward<F>(f), QThread::currentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class PromiseValue
|
class PromiseValue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -93,7 +93,7 @@ private:
|
|||||||
class PromiseError
|
class PromiseError
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template<typename T>
|
||||||
PromiseError(const T& value)
|
PromiseError(const T& value)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -113,116 +113,110 @@ private:
|
|||||||
std::exception_ptr m_data;
|
std::exception_ptr m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseDeduce
|
struct PromiseDeduce
|
||||||
{
|
{
|
||||||
using Type = QtPromise::QPromise<T>;
|
using Type = QtPromise::QPromise<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseDeduce<T&>
|
struct PromiseDeduce<T&> : public PromiseDeduce<T>
|
||||||
: public PromiseDeduce<T>
|
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseDeduce<const T>
|
struct PromiseDeduce<const T> : public PromiseDeduce<T>
|
||||||
: public PromiseDeduce<T>
|
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseDeduce<const volatile T>
|
struct PromiseDeduce<const volatile T> : public PromiseDeduce<T>
|
||||||
: public PromiseDeduce<T>
|
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseDeduce<QtPromise::QPromise<T>>
|
struct PromiseDeduce<QtPromise::QPromise<T>> : public PromiseDeduce<T>
|
||||||
: public PromiseDeduce<T>
|
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename Functor, typename... Args>
|
template<typename Functor, typename... Args>
|
||||||
struct PromiseFunctor
|
struct PromiseFunctor
|
||||||
{
|
{
|
||||||
using ResultType = typename std::result_of<Functor(Args...)>::type;
|
using ResultType = typename std::result_of<Functor(Args...)>::type;
|
||||||
using PromiseType = typename PromiseDeduce<ResultType>::Type;
|
using PromiseType = typename PromiseDeduce<ResultType>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseFulfill
|
struct PromiseFulfill
|
||||||
{
|
{
|
||||||
template <typename V, typename TResolve, typename TReject>
|
template<typename V, typename TResolve, typename TReject>
|
||||||
static void call(V&& value, const TResolve& resolve, const TReject&)
|
static void call(V&& value, const TResolve& resolve, const TReject&)
|
||||||
{
|
{
|
||||||
resolve(std::forward<V>(value));
|
resolve(std::forward<V>(value));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseFulfill<QtPromise::QPromise<T>>
|
struct PromiseFulfill<QtPromise::QPromise<T>>
|
||||||
{
|
{
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static void call(
|
static void
|
||||||
const QtPromise::QPromise<T>& promise,
|
call(const QtPromise::QPromise<T>& promise, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
if (promise.isFulfilled()) {
|
if (promise.isFulfilled()) {
|
||||||
resolve(promise.m_d->value());
|
resolve(promise.m_d->value());
|
||||||
} else if (promise.isRejected()) {
|
} else if (promise.isRejected()) {
|
||||||
reject(promise.m_d->error());
|
reject(promise.m_d->error());
|
||||||
} else {
|
} else {
|
||||||
promise.then([=]() {
|
promise.then(
|
||||||
resolve(promise.m_d->value());
|
[=]() {
|
||||||
}, [=]() { // catch all
|
resolve(promise.m_d->value());
|
||||||
reject(promise.m_d->error());
|
},
|
||||||
});
|
[=]() { // catch all
|
||||||
|
reject(promise.m_d->error());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
struct PromiseFulfill<QtPromise::QPromise<void>>
|
struct PromiseFulfill<QtPromise::QPromise<void>>
|
||||||
{
|
{
|
||||||
template <typename TPromise, typename TResolve, typename TReject>
|
template<typename TPromise, typename TResolve, typename TReject>
|
||||||
static void call(
|
static void call(const TPromise& promise, const TResolve& resolve, const TReject& reject)
|
||||||
const TPromise& promise,
|
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
if (promise.isFulfilled()) {
|
if (promise.isFulfilled()) {
|
||||||
resolve();
|
resolve();
|
||||||
} else if (promise.isRejected()) {
|
} else if (promise.isRejected()) {
|
||||||
reject(promise.m_d->error());
|
reject(promise.m_d->error());
|
||||||
} else {
|
} else {
|
||||||
promise.then([=]() {
|
promise.then(
|
||||||
resolve();
|
[=]() {
|
||||||
}, [=]() { // catch all
|
resolve();
|
||||||
reject(promise.m_d->error());
|
},
|
||||||
});
|
[=]() { // catch all
|
||||||
|
reject(promise.m_d->error());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Result>
|
template<typename Result>
|
||||||
struct PromiseDispatch
|
struct PromiseDispatch
|
||||||
{
|
{
|
||||||
template <typename Resolve, typename Reject, typename Functor, typename... Args>
|
template<typename Resolve, typename Reject, typename Functor, typename... Args>
|
||||||
static void call(const Resolve& resolve, const Reject& reject, Functor fn, Args&&... args)
|
static void call(const Resolve& resolve, const Reject& reject, Functor fn, Args&&... args)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
PromiseFulfill<Unqualified<Result>>::call(
|
PromiseFulfill<Unqualified<Result>>::call(fn(std::forward<Args>(args)...),
|
||||||
fn(std::forward<Args>(args)...),
|
resolve,
|
||||||
resolve,
|
reject);
|
||||||
reject);
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
reject(std::current_exception());
|
reject(std::current_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
struct PromiseDispatch<void>
|
struct PromiseDispatch<void>
|
||||||
{
|
{
|
||||||
template <typename Resolve, typename Reject, typename Functor, typename... Args>
|
template<typename Resolve, typename Reject, typename Functor, typename... Args>
|
||||||
static void call(const Resolve& resolve, const Reject& reject, Functor fn, Args&&... args)
|
static void call(const Resolve& resolve, const Reject& reject, Functor fn, Args&&... args)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -234,17 +228,15 @@ struct PromiseDispatch<void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename THandler, typename TArg = typename ArgsOf<THandler>::first>
|
template<typename T, typename THandler, typename TArg = typename ArgsOf<THandler>::first>
|
||||||
struct PromiseHandler
|
struct PromiseHandler
|
||||||
{
|
{
|
||||||
using ResType = typename std::result_of<THandler(T)>::type;
|
using ResType = typename std::result_of<THandler(T)>::type;
|
||||||
using Promise = typename PromiseDeduce<ResType>::Type;
|
using Promise = typename PromiseDeduce<ResType>::Type;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void(const T&)> create(
|
static std::function<void(const T&)>
|
||||||
const THandler& handler,
|
create(const THandler& handler, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=](const T& value) {
|
return [=](const T& value) {
|
||||||
PromiseDispatch<ResType>::call(resolve, reject, handler, value);
|
PromiseDispatch<ResType>::call(resolve, reject, handler, value);
|
||||||
@ -252,17 +244,15 @@ struct PromiseHandler
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename THandler>
|
template<typename T, typename THandler>
|
||||||
struct PromiseHandler<T, THandler, void>
|
struct PromiseHandler<T, THandler, void>
|
||||||
{
|
{
|
||||||
using ResType = typename std::result_of<THandler()>::type;
|
using ResType = typename std::result_of<THandler()>::type;
|
||||||
using Promise = typename PromiseDeduce<ResType>::Type;
|
using Promise = typename PromiseDeduce<ResType>::Type;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void(const T&)> create(
|
static std::function<void(const T&)>
|
||||||
const THandler& handler,
|
create(const THandler& handler, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=](const T&) {
|
return [=](const T&) {
|
||||||
PromiseDispatch<ResType>::call(resolve, reject, handler);
|
PromiseDispatch<ResType>::call(resolve, reject, handler);
|
||||||
@ -270,17 +260,15 @@ struct PromiseHandler<T, THandler, void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename THandler>
|
template<typename THandler>
|
||||||
struct PromiseHandler<void, THandler, void>
|
struct PromiseHandler<void, THandler, void>
|
||||||
{
|
{
|
||||||
using ResType = typename std::result_of<THandler()>::type;
|
using ResType = typename std::result_of<THandler()>::type;
|
||||||
using Promise = typename PromiseDeduce<ResType>::Type;
|
using Promise = typename PromiseDeduce<ResType>::Type;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void()> create(
|
static std::function<void()>
|
||||||
const THandler& handler,
|
create(const THandler& handler, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=]() {
|
return [=]() {
|
||||||
PromiseDispatch<ResType>::call(resolve, reject, handler);
|
PromiseDispatch<ResType>::call(resolve, reject, handler);
|
||||||
@ -288,16 +276,14 @@ struct PromiseHandler<void, THandler, void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseHandler<T, std::nullptr_t, void>
|
struct PromiseHandler<T, std::nullptr_t, void>
|
||||||
{
|
{
|
||||||
using Promise = QtPromise::QPromise<T>;
|
using Promise = QtPromise::QPromise<T>;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void(const T&)> create(
|
static std::function<void(const T&)>
|
||||||
std::nullptr_t,
|
create(std::nullptr_t, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=](const T& value) {
|
return [=](const T& value) {
|
||||||
// 2.2.7.3. If onFulfilled is not a function and promise1 is fulfilled,
|
// 2.2.7.3. If onFulfilled is not a function and promise1 is fulfilled,
|
||||||
@ -307,16 +293,13 @@ struct PromiseHandler<T, std::nullptr_t, void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
struct PromiseHandler<void, std::nullptr_t, void>
|
struct PromiseHandler<void, std::nullptr_t, void>
|
||||||
{
|
{
|
||||||
using Promise = QtPromise::QPromise<void>;
|
using Promise = QtPromise::QPromise<void>;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void()> create(
|
static std::function<void()> create(std::nullptr_t, const TResolve& resolve, const TReject&)
|
||||||
std::nullptr_t,
|
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject&)
|
|
||||||
{
|
{
|
||||||
return [=]() {
|
return [=]() {
|
||||||
// 2.2.7.3. If onFulfilled is not a function and promise1 is fulfilled,
|
// 2.2.7.3. If onFulfilled is not a function and promise1 is fulfilled,
|
||||||
@ -326,16 +309,14 @@ struct PromiseHandler<void, std::nullptr_t, void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename THandler, typename TArg = typename ArgsOf<THandler>::first>
|
template<typename T, typename THandler, typename TArg = typename ArgsOf<THandler>::first>
|
||||||
struct PromiseCatcher
|
struct PromiseCatcher
|
||||||
{
|
{
|
||||||
using ResType = typename std::result_of<THandler(TArg)>::type;
|
using ResType = typename std::result_of<THandler(TArg)>::type;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void(const PromiseError&)> create(
|
static std::function<void(const PromiseError&)>
|
||||||
const THandler& handler,
|
create(const THandler& handler, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=](const PromiseError& error) {
|
return [=](const PromiseError& error) {
|
||||||
try {
|
try {
|
||||||
@ -349,16 +330,14 @@ struct PromiseCatcher
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename THandler>
|
template<typename T, typename THandler>
|
||||||
struct PromiseCatcher<T, THandler, void>
|
struct PromiseCatcher<T, THandler, void>
|
||||||
{
|
{
|
||||||
using ResType = typename std::result_of<THandler()>::type;
|
using ResType = typename std::result_of<THandler()>::type;
|
||||||
|
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void(const PromiseError&)> create(
|
static std::function<void(const PromiseError&)>
|
||||||
const THandler& handler,
|
create(const THandler& handler, const TResolve& resolve, const TReject& reject)
|
||||||
const TResolve& resolve,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=](const PromiseError& error) {
|
return [=](const PromiseError& error) {
|
||||||
try {
|
try {
|
||||||
@ -370,14 +349,12 @@ struct PromiseCatcher<T, THandler, void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseCatcher<T, std::nullptr_t, void>
|
struct PromiseCatcher<T, std::nullptr_t, void>
|
||||||
{
|
{
|
||||||
template <typename TResolve, typename TReject>
|
template<typename TResolve, typename TReject>
|
||||||
static std::function<void(const PromiseError&)> create(
|
static std::function<void(const PromiseError&)>
|
||||||
std::nullptr_t,
|
create(std::nullptr_t, const TResolve&, const TReject& reject)
|
||||||
const TResolve&,
|
|
||||||
const TReject& reject)
|
|
||||||
{
|
{
|
||||||
return [=](const PromiseError& error) {
|
return [=](const PromiseError& error) {
|
||||||
// 2.2.7.4. If onRejected is not a function and promise1 is rejected,
|
// 2.2.7.4. If onRejected is not a function and promise1 is rejected,
|
||||||
@ -387,11 +364,11 @@ struct PromiseCatcher<T, std::nullptr_t, void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename F>
|
template<typename T, typename F>
|
||||||
struct PromiseMapper
|
struct PromiseMapper
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename T, typename F, template <typename, typename...> class Sequence, typename ...Args>
|
template<typename T, typename F, template<typename, typename...> class Sequence, typename... Args>
|
||||||
struct PromiseMapper<Sequence<T, Args...>, F>
|
struct PromiseMapper<Sequence<T, Args...>, F>
|
||||||
{
|
{
|
||||||
using ReturnType = typename std::result_of<F(T, int)>::type;
|
using ReturnType = typename std::result_of<F(T, int)>::type;
|
||||||
@ -399,26 +376,20 @@ struct PromiseMapper<Sequence<T, Args...>, F>
|
|||||||
using PromiseType = QtPromise::QPromise<ResultType>;
|
using PromiseType = QtPromise::QPromise<ResultType>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> class PromiseData;
|
template<typename T>
|
||||||
|
class PromiseData;
|
||||||
|
|
||||||
template <typename T, typename F>
|
template<typename T, typename F>
|
||||||
class PromiseDataBase : public QSharedData
|
class PromiseDataBase : public QSharedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Handler = std::pair<QPointer<QThread>, std::function<F>>;
|
using Handler = std::pair<QPointer<QThread>, std::function<F>>;
|
||||||
using Catcher = std::pair<QPointer<QThread>, std::function<void(const PromiseError&)>>;
|
using Catcher = std::pair<QPointer<QThread>, std::function<void(const PromiseError&)>>;
|
||||||
|
|
||||||
virtual ~PromiseDataBase() {}
|
virtual ~PromiseDataBase() { }
|
||||||
|
|
||||||
bool isFulfilled() const
|
bool isFulfilled() const { return !isPending() && m_error.isNull(); }
|
||||||
{
|
bool isRejected() const { return !isPending() && !m_error.isNull(); }
|
||||||
return !isPending() && m_error.isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isRejected() const
|
|
||||||
{
|
|
||||||
return !isPending() && !m_error.isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPending() const
|
bool isPending() const
|
||||||
{
|
{
|
||||||
@ -438,7 +409,7 @@ public:
|
|||||||
m_catchers.append({QThread::currentThread(), std::move(catcher)});
|
m_catchers.append({QThread::currentThread(), std::move(catcher)});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E>
|
template<typename E>
|
||||||
void reject(E&& error)
|
void reject(E&& error)
|
||||||
{
|
{
|
||||||
Q_ASSERT(isPending());
|
Q_ASSERT(isPending());
|
||||||
@ -479,11 +450,13 @@ public:
|
|||||||
PromiseError error = m_error;
|
PromiseError error = m_error;
|
||||||
Q_ASSERT(!error.isNull());
|
Q_ASSERT(!error.isNull());
|
||||||
|
|
||||||
for (const auto& catcher: catchers) {
|
for (const auto& catcher : catchers) {
|
||||||
const auto& fn = catcher.second;
|
const auto& fn = catcher.second;
|
||||||
qtpromise_defer([=]() {
|
qtpromise_defer(
|
||||||
fn(error);
|
[=]() {
|
||||||
}, catcher.first);
|
fn(error);
|
||||||
|
},
|
||||||
|
catcher.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,13 +479,13 @@ private:
|
|||||||
PromiseError m_error;
|
PromiseError m_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class PromiseData : public PromiseDataBase<T, void(const T&)>
|
class PromiseData : public PromiseDataBase<T, void(const T&)>
|
||||||
{
|
{
|
||||||
using Handler = typename PromiseDataBase<T, void(const T&)>::Handler;
|
using Handler = typename PromiseDataBase<T, void(const T&)>::Handler;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename V>
|
template<typename V>
|
||||||
void resolve(V&& value)
|
void resolve(V&& value)
|
||||||
{
|
{
|
||||||
Q_ASSERT(this->isPending());
|
Q_ASSERT(this->isPending());
|
||||||
@ -532,11 +505,13 @@ public:
|
|||||||
PromiseValue<T> value = m_value;
|
PromiseValue<T> value = m_value;
|
||||||
Q_ASSERT(!value.isNull());
|
Q_ASSERT(!value.isNull());
|
||||||
|
|
||||||
for (const auto& handler: handlers) {
|
for (const auto& handler : handlers) {
|
||||||
const auto& fn = handler.second;
|
const auto& fn = handler.second;
|
||||||
qtpromise_defer([=]() {
|
qtpromise_defer(
|
||||||
fn(value.data());
|
[=]() {
|
||||||
}, handler.first);
|
fn(value.data());
|
||||||
|
},
|
||||||
|
handler.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,21 +519,18 @@ private:
|
|||||||
PromiseValue<T> m_value;
|
PromiseValue<T> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
class PromiseData<void> : public PromiseDataBase<void, void()>
|
class PromiseData<void> : public PromiseDataBase<void, void()>
|
||||||
{
|
{
|
||||||
using Handler = PromiseDataBase<void, void()>::Handler;
|
using Handler = PromiseDataBase<void, void()>::Handler;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void resolve()
|
void resolve() { setSettled(); }
|
||||||
{
|
|
||||||
setSettled();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void notify(const QVector<Handler>& handlers) Q_DECL_OVERRIDE
|
void notify(const QVector<Handler>& handlers) Q_DECL_OVERRIDE
|
||||||
{
|
{
|
||||||
for (const auto& handler: handlers) {
|
for (const auto& handler : handlers) {
|
||||||
qtpromise_defer(handler.second, handler.first);
|
qtpromise_defer(handler.second, handler.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,7 +538,7 @@ protected:
|
|||||||
|
|
||||||
struct PromiseInspect
|
struct PromiseInspect
|
||||||
{
|
{
|
||||||
template <typename T>
|
template<typename T>
|
||||||
static inline PromiseData<T>* get(const QtPromise::QPromise<T>& p)
|
static inline PromiseData<T>* get(const QtPromise::QPromise<T>& p)
|
||||||
{
|
{
|
||||||
return p.m_d.data();
|
return p.m_d.data();
|
||||||
|
@ -31,15 +31,17 @@ private:
|
|||||||
{
|
{
|
||||||
QVector<QMetaObject::Connection> connections;
|
QVector<QMetaObject::Connection> connections;
|
||||||
|
|
||||||
~Data() {
|
~Data()
|
||||||
|
{
|
||||||
if (!connections.empty()) {
|
if (!connections.empty()) {
|
||||||
qWarning("QPromiseConnections: destroyed with unhandled connections.");
|
qWarning("QPromiseConnections: destroyed with unhandled connections.");
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disconnect() {
|
void disconnect()
|
||||||
for (const auto& connection: connections) {
|
{
|
||||||
|
for (const auto& connection : connections) {
|
||||||
QObject::disconnect(connection);
|
QObject::disconnect(connection);
|
||||||
}
|
}
|
||||||
connections.clear();
|
connections.clear();
|
||||||
|
@ -15,18 +15,16 @@
|
|||||||
|
|
||||||
namespace QtPromisePrivate {
|
namespace QtPromisePrivate {
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseDeduce<QFuture<T>>
|
struct PromiseDeduce<QFuture<T>> : public PromiseDeduce<T>
|
||||||
: public PromiseDeduce<T>
|
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct PromiseFulfill<QFuture<T>>
|
struct PromiseFulfill<QFuture<T>>
|
||||||
{
|
{
|
||||||
static void call(
|
static void call(const QFuture<T>& future,
|
||||||
const QFuture<T>& future,
|
const QtPromise::QPromiseResolve<T>& resolve,
|
||||||
const QtPromise::QPromiseResolve<T>& resolve,
|
const QtPromise::QPromiseReject<T>& reject)
|
||||||
const QtPromise::QPromiseReject<T>& reject)
|
|
||||||
{
|
{
|
||||||
using Watcher = QFutureWatcher<T>;
|
using Watcher = QFutureWatcher<T>;
|
||||||
|
|
||||||
@ -55,13 +53,12 @@ struct PromiseFulfill<QFuture<T>>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
struct PromiseFulfill<QFuture<void>>
|
struct PromiseFulfill<QFuture<void>>
|
||||||
{
|
{
|
||||||
static void call(
|
static void call(const QFuture<void>& future,
|
||||||
const QFuture<void>& future,
|
const QtPromise::QPromiseResolve<void>& resolve,
|
||||||
const QtPromise::QPromiseResolve<void>& resolve,
|
const QtPromise::QPromiseReject<void>& reject)
|
||||||
const QtPromise::QPromiseReject<void>& reject)
|
|
||||||
{
|
{
|
||||||
using Watcher = QFutureWatcher<void>;
|
using Watcher = QFutureWatcher<void>;
|
||||||
|
|
||||||
|
@ -13,21 +13,25 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace QtPromisePrivate
|
namespace QtPromisePrivate {
|
||||||
{
|
|
||||||
// https://rmf.io/cxx11/even-more-traits#unqualified_types
|
// https://rmf.io/cxx11/even-more-traits#unqualified_types
|
||||||
template <typename T>
|
template<typename T>
|
||||||
using Unqualified = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
using Unqualified = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \struct HasCallOperator
|
* \struct HasCallOperator
|
||||||
* http://stackoverflow.com/a/5117641
|
* http://stackoverflow.com/a/5117641
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct HasCallOperator
|
struct HasCallOperator
|
||||||
{
|
{
|
||||||
template <typename U> static char check(decltype(&U::operator(), char(0)));
|
template<typename U>
|
||||||
template <typename U> static char (&check(...))[2];
|
static char check(decltype(&U::operator(), char(0)));
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
static char (&check(...))[2];
|
||||||
|
|
||||||
static const bool value = (sizeof(check<T>(0)) == 1);
|
static const bool value = (sizeof(check<T>(0)) == 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,7 +40,7 @@ struct HasCallOperator
|
|||||||
* http://stackoverflow.com/a/7943765
|
* http://stackoverflow.com/a/7943765
|
||||||
* http://stackoverflow.com/a/27885283
|
* http://stackoverflow.com/a/27885283
|
||||||
*/
|
*/
|
||||||
template <typename... Args>
|
template<typename... Args>
|
||||||
struct ArgsTraits
|
struct ArgsTraits
|
||||||
{
|
{
|
||||||
using types = std::tuple<Args...>;
|
using types = std::tuple<Args...>;
|
||||||
@ -44,7 +48,7 @@ struct ArgsTraits
|
|||||||
static const size_t count = std::tuple_size<types>::value;
|
static const size_t count = std::tuple_size<types>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
struct ArgsTraits<>
|
struct ArgsTraits<>
|
||||||
{
|
{
|
||||||
using types = std::tuple<>;
|
using types = std::tuple<>;
|
||||||
@ -53,56 +57,56 @@ struct ArgsTraits<>
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Fallback implementation (type not supported).
|
// Fallback implementation (type not supported).
|
||||||
template <typename T, typename Enabled = void>
|
template<typename T, typename Enabled = void>
|
||||||
struct ArgsOf
|
struct ArgsOf
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Partial specialization for null function.
|
// Partial specialization for null function.
|
||||||
template <>
|
template<>
|
||||||
struct ArgsOf<std::nullptr_t> : public ArgsTraits<>
|
struct ArgsOf<std::nullptr_t> : public ArgsTraits<>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Partial specialization for type with a non-overloaded operator().
|
// Partial specialization for type with a non-overloaded operator().
|
||||||
// This applies to lambda, std::function but not to std::bind result.
|
// This applies to lambda, std::function but not to std::bind result.
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct ArgsOf<T, typename std::enable_if<HasCallOperator<T>::value>::type>
|
struct ArgsOf<T, typename std::enable_if<HasCallOperator<T>::value>::type>
|
||||||
: public ArgsOf<decltype(&T::operator())>
|
: public ArgsOf<decltype(&T::operator())>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Partial specialization to remove reference and rvalue (e.g. lambda, std::function, etc.).
|
// Partial specialization to remove reference and rvalue (e.g. lambda, std::function, etc.).
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct ArgsOf<T&> : public ArgsOf<T>
|
struct ArgsOf<T&> : public ArgsOf<T>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
struct ArgsOf<T&&> : public ArgsOf<T>
|
struct ArgsOf<T&&> : public ArgsOf<T>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Partial specialization for function type.
|
// Partial specialization for function type.
|
||||||
template <typename R, typename... Args>
|
template<typename R, typename... Args>
|
||||||
struct ArgsOf<R(Args...)> : public ArgsTraits<Args...>
|
struct ArgsOf<R(Args...)> : public ArgsTraits<Args...>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Partial specialization for function pointer.
|
// Partial specialization for function pointer.
|
||||||
template <typename R, typename... Args>
|
template<typename R, typename... Args>
|
||||||
struct ArgsOf<R(*)(Args...)> : public ArgsTraits<Args...>
|
struct ArgsOf<R (*)(Args...)> : public ArgsTraits<Args...>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
// Partial specialization for pointer-to-member-function (i.e. operator()'s).
|
// Partial specialization for pointer-to-member-function (i.e. operator()'s).
|
||||||
template <typename R, typename T, typename... Args>
|
template<typename R, typename T, typename... Args>
|
||||||
struct ArgsOf<R(T::*)(Args...)> : public ArgsTraits<Args...>
|
struct ArgsOf<R (T::*)(Args...)> : public ArgsTraits<Args...>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename R, typename T, typename... Args>
|
template<typename R, typename T, typename... Args>
|
||||||
struct ArgsOf<R(T::*)(Args...) const> : public ArgsTraits<Args...>
|
struct ArgsOf<R (T::*)(Args...) const> : public ArgsTraits<Args...>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename R, typename T, typename... Args>
|
template<typename R, typename T, typename... Args>
|
||||||
struct ArgsOf<R(T::*)(Args...) volatile> : public ArgsTraits<Args...>
|
struct ArgsOf<R (T::*)(Args...) volatile> : public ArgsTraits<Args...>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template <typename R, typename T, typename... Args>
|
template<typename R, typename T, typename... Args>
|
||||||
struct ArgsOf<R(T::*)(Args...) const volatile> : public ArgsTraits<Args...>
|
struct ArgsOf<R (T::*)(Args...) const volatile> : public ArgsTraits<Args...>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
} // namespace QtPromisePrivate
|
} // namespace QtPromisePrivate
|
||||||
|
@ -13,9 +13,8 @@
|
|||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
static inline typename QtPromisePrivate::PromiseDeduce<T>::Type
|
static inline typename QtPromisePrivate::PromiseDeduce<T>::Type resolve(T&& value)
|
||||||
resolve(T&& value)
|
|
||||||
{
|
{
|
||||||
using namespace QtPromisePrivate;
|
using namespace QtPromisePrivate;
|
||||||
using PromiseType = typename PromiseDeduce<T>::Type;
|
using PromiseType = typename PromiseDeduce<T>::Type;
|
||||||
@ -24,94 +23,89 @@ resolve(T&& value)
|
|||||||
using RejectType = QPromiseReject<ValueType>;
|
using RejectType = QPromiseReject<ValueType>;
|
||||||
|
|
||||||
return PromiseType{[&](ResolveType&& resolve, RejectType&& reject) {
|
return PromiseType{[&](ResolveType&& resolve, RejectType&& reject) {
|
||||||
PromiseFulfill<Unqualified<T>>::call(
|
PromiseFulfill<Unqualified<T>>::call(std::forward<T>(value),
|
||||||
std::forward<T>(value),
|
std::forward<ResolveType>(resolve),
|
||||||
std::forward<ResolveType>(resolve),
|
std::forward<RejectType>(reject));
|
||||||
std::forward<RejectType>(reject));
|
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
static inline QPromise<T>
|
static inline QPromise<T> resolve(QPromise<T> value)
|
||||||
resolve(QPromise<T> value)
|
|
||||||
{
|
{
|
||||||
return std::move(value);
|
return std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QPromise<void>
|
static inline QPromise<void> resolve()
|
||||||
resolve()
|
|
||||||
{
|
{
|
||||||
return QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
return QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
||||||
resolve();
|
resolve();
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, template <typename, typename...> class Sequence = QVector, typename ...Args>
|
template<typename T, template<typename, typename...> class Sequence = QVector, typename... Args>
|
||||||
static inline QPromise<QVector<T>>
|
static inline QPromise<QVector<T>> all(const Sequence<QPromise<T>, Args...>& promises)
|
||||||
all(const Sequence<QPromise<T>, Args...>& promises)
|
|
||||||
{
|
{
|
||||||
const int count = static_cast<int>(promises.size());
|
const int count = static_cast<int>(promises.size());
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return QtPromise::resolve(QVector<T>{});
|
return QtPromise::resolve(QVector<T>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
return QPromise<QVector<T>>{[=](
|
return QPromise<QVector<T>>{
|
||||||
const QPromiseResolve<QVector<T>>& resolve,
|
[=](const QPromiseResolve<QVector<T>>& resolve, const QPromiseReject<QVector<T>>& reject) {
|
||||||
const QPromiseReject<QVector<T>>& reject) {
|
auto remaining = QSharedPointer<int>::create(count);
|
||||||
|
auto results = QSharedPointer<QVector<T>>::create(count);
|
||||||
|
|
||||||
auto remaining = QSharedPointer<int>::create(count);
|
int i = 0;
|
||||||
auto results = QSharedPointer<QVector<T>>::create(count);
|
for (const auto& promise : promises) {
|
||||||
|
promise.then(
|
||||||
|
[=](const T& res) mutable {
|
||||||
|
(*results)[i] = res;
|
||||||
|
if (--(*remaining) == 0) {
|
||||||
|
resolve(*results);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[=]() mutable {
|
||||||
|
if (*remaining != -1) {
|
||||||
|
*remaining = -1;
|
||||||
|
reject(std::current_exception());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
int i = 0;
|
i++;
|
||||||
for (const auto& promise: promises) {
|
}
|
||||||
promise.then([=](const T& res) mutable {
|
}};
|
||||||
(*results)[i] = res;
|
|
||||||
if (--(*remaining) == 0) {
|
|
||||||
resolve(*results);
|
|
||||||
}
|
|
||||||
}, [=]() mutable {
|
|
||||||
if (*remaining != -1) {
|
|
||||||
*remaining = -1;
|
|
||||||
reject(std::current_exception());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename, typename...> class Sequence = QVector, typename ...Args>
|
template<template<typename, typename...> class Sequence = QVector, typename... Args>
|
||||||
static inline QPromise<void>
|
static inline QPromise<void> all(const Sequence<QPromise<void>, Args...>& promises)
|
||||||
all(const Sequence<QPromise<void>, Args...>& promises)
|
|
||||||
{
|
{
|
||||||
const int count = static_cast<int>(promises.size());
|
const int count = static_cast<int>(promises.size());
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return QtPromise::resolve();
|
return QtPromise::resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
return QPromise<void>{[=](
|
return QPromise<void>{
|
||||||
const QPromiseResolve<void>& resolve,
|
[=](const QPromiseResolve<void>& resolve, const QPromiseReject<void>& reject) {
|
||||||
const QPromiseReject<void>& reject) {
|
auto remaining = QSharedPointer<int>::create(count);
|
||||||
|
|
||||||
auto remaining = QSharedPointer<int>::create(count);
|
for (const auto& promise : promises) {
|
||||||
|
promise.then(
|
||||||
for (const auto& promise: promises) {
|
[=]() {
|
||||||
promise.then([=]() {
|
if (--(*remaining) == 0) {
|
||||||
if (--(*remaining) == 0) {
|
resolve();
|
||||||
resolve();
|
}
|
||||||
}
|
},
|
||||||
}, [=]() {
|
[=]() {
|
||||||
if (*remaining != -1) {
|
if (*remaining != -1) {
|
||||||
*remaining = -1;
|
*remaining = -1;
|
||||||
reject(std::current_exception());
|
reject(std::current_exception());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Functor, typename... Args>
|
template<typename Functor, typename... Args>
|
||||||
static inline typename QtPromisePrivate::PromiseFunctor<Functor, Args...>::PromiseType
|
static inline typename QtPromisePrivate::PromiseFunctor<Functor, Args...>::PromiseType
|
||||||
attempt(Functor&& fn, Args&&... args)
|
attempt(Functor&& fn, Args&&... args)
|
||||||
{
|
{
|
||||||
@ -127,62 +121,57 @@ attempt(Functor&& fn, Args&&... args)
|
|||||||
using ResolveType = QPromiseResolve<ValueType>;
|
using ResolveType = QPromiseResolve<ValueType>;
|
||||||
using RejectType = QPromiseReject<ValueType>;
|
using RejectType = QPromiseReject<ValueType>;
|
||||||
|
|
||||||
return PromiseType{
|
return PromiseType{[&](ResolveType&& resolve, RejectType&& reject) {
|
||||||
[&](ResolveType&& resolve, RejectType&& reject) {
|
PromiseDispatch<typename FunctorType::ResultType>::call(std::forward<ResolveType>(resolve),
|
||||||
PromiseDispatch<typename FunctorType::ResultType>::call(
|
std::forward<RejectType>(reject),
|
||||||
std::forward<ResolveType>(resolve),
|
std::forward<Functor>(fn),
|
||||||
std::forward<RejectType>(reject),
|
std::forward<Args>(args)...);
|
||||||
std::forward<Functor>(fn),
|
}};
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sender, typename Signal>
|
template<typename Sender, typename Signal>
|
||||||
static inline typename QtPromisePrivate::PromiseFromSignal<Signal>
|
static inline typename QtPromisePrivate::PromiseFromSignal<Signal>
|
||||||
connect(const Sender* sender, Signal signal)
|
connect(const Sender* sender, Signal signal)
|
||||||
{
|
{
|
||||||
using namespace QtPromisePrivate;
|
using namespace QtPromisePrivate;
|
||||||
using T = typename PromiseFromSignal<Signal>::Type;
|
using T = typename PromiseFromSignal<Signal>::Type;
|
||||||
|
|
||||||
return QPromise<T>{
|
return QPromise<T>{[&](const QPromiseResolve<T>& resolve, const QPromiseReject<T>& reject) {
|
||||||
[&](const QPromiseResolve<T>& resolve, const QPromiseReject<T>& reject) {
|
QPromiseConnections connections;
|
||||||
QPromiseConnections connections;
|
connectSignalToResolver(connections, resolve, sender, signal);
|
||||||
connectSignalToResolver(connections, resolve, sender, signal);
|
connectDestroyedToReject(connections, reject, sender);
|
||||||
connectDestroyedToReject(connections, reject, sender);
|
}};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FSender, typename FSignal, typename RSender, typename RSignal>
|
template<typename FSender, typename FSignal, typename RSender, typename RSignal>
|
||||||
static inline typename QtPromisePrivate::PromiseFromSignal<FSignal>
|
static inline typename QtPromisePrivate::PromiseFromSignal<FSignal>
|
||||||
connect(const FSender* fsender, FSignal fsignal, const RSender* rsender, RSignal rsignal)
|
connect(const FSender* fsender, FSignal fsignal, const RSender* rsender, RSignal rsignal)
|
||||||
{
|
{
|
||||||
using namespace QtPromisePrivate;
|
using namespace QtPromisePrivate;
|
||||||
using T = typename PromiseFromSignal<FSignal>::Type;
|
using T = typename PromiseFromSignal<FSignal>::Type;
|
||||||
|
|
||||||
return QPromise<T>{
|
return QPromise<T>{[&](const QPromiseResolve<T>& resolve, const QPromiseReject<T>& reject) {
|
||||||
[&](const QPromiseResolve<T>& resolve, const QPromiseReject<T>& reject) {
|
QPromiseConnections connections;
|
||||||
QPromiseConnections connections;
|
connectSignalToResolver(connections, resolve, fsender, fsignal);
|
||||||
connectSignalToResolver(connections, resolve, fsender, fsignal);
|
connectSignalToResolver(connections, reject, rsender, rsignal);
|
||||||
connectSignalToResolver(connections, reject, rsender, rsignal);
|
connectDestroyedToReject(connections, reject, fsender);
|
||||||
connectDestroyedToReject(connections, reject, fsender);
|
}};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sender, typename FSignal, typename RSignal>
|
template<typename Sender, typename FSignal, typename RSignal>
|
||||||
static inline typename QtPromisePrivate::PromiseFromSignal<FSignal>
|
static inline typename QtPromisePrivate::PromiseFromSignal<FSignal>
|
||||||
connect(const Sender* sender, FSignal fsignal, RSignal rsignal)
|
connect(const Sender* sender, FSignal fsignal, RSignal rsignal)
|
||||||
{
|
{
|
||||||
return connect(sender, fsignal, sender, rsignal);
|
return connect(sender, fsignal, sender, rsignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sequence, typename Functor>
|
template<typename Sequence, typename Functor>
|
||||||
static inline QPromise<Sequence>
|
static inline QPromise<Sequence> each(const Sequence& values, Functor&& fn)
|
||||||
each(const Sequence& values, Functor&& fn)
|
|
||||||
{
|
{
|
||||||
return QPromise<Sequence>::resolve(values).each(std::forward<Functor>(fn));
|
return QPromise<Sequence>::resolve(values).each(std::forward<Functor>(fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sequence, typename Functor>
|
template<typename Sequence, typename Functor>
|
||||||
static inline typename QtPromisePrivate::PromiseMapper<Sequence, Functor>::PromiseType
|
static inline typename QtPromisePrivate::PromiseMapper<Sequence, Functor>::PromiseType
|
||||||
map(const Sequence& values, Functor fn)
|
map(const Sequence& values, Functor fn)
|
||||||
{
|
{
|
||||||
@ -195,9 +184,8 @@ map(const Sequence& values, Functor fn)
|
|||||||
|
|
||||||
std::vector<QPromise<ResType>> promises;
|
std::vector<QPromise<ResType>> promises;
|
||||||
for (const auto& v : values) {
|
for (const auto& v : values) {
|
||||||
promises.push_back(QPromise<ResType>{[&](
|
promises.push_back(QPromise<ResType>{
|
||||||
const QPromiseResolve<ResType>& resolve,
|
[&](const QPromiseResolve<ResType>& resolve, const QPromiseReject<ResType>& reject) {
|
||||||
const QPromiseReject<ResType>& reject) {
|
|
||||||
PromiseFulfill<RetType>::call(fn(v, i), resolve, reject);
|
PromiseFulfill<RetType>::call(fn(v, i), resolve, reject);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@ -207,28 +195,30 @@ map(const Sequence& values, Functor fn)
|
|||||||
return QtPromise::all(promises);
|
return QtPromise::all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sequence, typename Functor>
|
template<typename Sequence, typename Functor>
|
||||||
static inline QPromise<Sequence>
|
static inline QPromise<Sequence> filter(const Sequence& values, Functor fn)
|
||||||
filter(const Sequence& values, Functor fn)
|
|
||||||
{
|
{
|
||||||
return QtPromise::map(values, fn)
|
return QtPromise::map(values, fn).then([=](const QVector<bool>& filters) {
|
||||||
.then([=](const QVector<bool>& filters) {
|
Sequence filtered;
|
||||||
Sequence filtered;
|
|
||||||
|
|
||||||
auto filter = filters.begin();
|
auto filter = filters.begin();
|
||||||
for (auto& value : values) {
|
for (auto& value : values) {
|
||||||
if (*filter) {
|
if (*filter) {
|
||||||
filtered.push_back(std::move(value));
|
filtered.push_back(std::move(value));
|
||||||
}
|
|
||||||
|
|
||||||
filter++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return filtered;
|
filter++;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, template <typename...> class Sequence = QVector, typename Reducer, typename Input, typename ...Args>
|
template<typename T,
|
||||||
|
template<typename...> class Sequence = QVector,
|
||||||
|
typename Reducer,
|
||||||
|
typename Input,
|
||||||
|
typename... Args>
|
||||||
static inline typename QtPromisePrivate::PromiseDeduce<Input>::Type
|
static inline typename QtPromisePrivate::PromiseDeduce<Input>::Type
|
||||||
reduce(const Sequence<T, Args...>& values, Reducer fn, Input initial)
|
reduce(const Sequence<T, Args...>& values, Reducer fn, Input initial)
|
||||||
{
|
{
|
||||||
@ -253,7 +243,10 @@ reduce(const Sequence<T, Args...>& values, Reducer fn, Input initial)
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, template <typename...> class Sequence = QVector, typename Reducer, typename ...Args>
|
template<typename T,
|
||||||
|
template<typename...> class Sequence = QVector,
|
||||||
|
typename Reducer,
|
||||||
|
typename... Args>
|
||||||
static inline typename QtPromisePrivate::PromiseDeduce<T>::Type
|
static inline typename QtPromisePrivate::PromiseDeduce<T>::Type
|
||||||
reduce(const Sequence<T, Args...>& values, Reducer fn)
|
reduce(const Sequence<T, Args...>& values, Reducer fn)
|
||||||
{
|
{
|
||||||
@ -283,19 +276,17 @@ reduce(const Sequence<T, Args...>& values, Reducer fn)
|
|||||||
|
|
||||||
// DEPRECATIONS (remove at version 1)
|
// DEPRECATIONS (remove at version 1)
|
||||||
|
|
||||||
template <typename... Args>
|
template<typename... Args>
|
||||||
Q_DECL_DEPRECATED_X("Use QtPromise::resolve instead")
|
Q_DECL_DEPRECATED_X("Use QtPromise::resolve instead")
|
||||||
static inline auto
|
static inline auto qPromise(Args&&... args)
|
||||||
qPromise(Args&&... args)
|
|
||||||
-> decltype(QtPromise::resolve(std::forward<Args>(args)...))
|
-> decltype(QtPromise::resolve(std::forward<Args>(args)...))
|
||||||
{
|
{
|
||||||
return QtPromise::resolve(std::forward<Args>(args)...);
|
return QtPromise::resolve(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template<typename... Args>
|
||||||
Q_DECL_DEPRECATED_X("Use QtPromise::all instead")
|
Q_DECL_DEPRECATED_X("Use QtPromise::all instead")
|
||||||
static inline auto
|
static inline auto qPromiseAll(Args&&... args)
|
||||||
qPromiseAll(Args&&... args)
|
|
||||||
-> decltype(QtPromise::all(std::forward<Args>(args)...))
|
-> decltype(QtPromise::all(std::forward<Args>(args)...))
|
||||||
{
|
{
|
||||||
return QtPromise::all(std::forward<Args>(args)...);
|
return QtPromise::all(std::forward<Args>(args)...);
|
||||||
|
@ -16,17 +16,16 @@ namespace QtPromisePrivate {
|
|||||||
// TODO: Suppress QPrivateSignal trailing private signal args
|
// TODO: Suppress QPrivateSignal trailing private signal args
|
||||||
// TODO: Support deducing tuple from args (might require MSVC2017)
|
// TODO: Support deducing tuple from args (might require MSVC2017)
|
||||||
|
|
||||||
template <typename Signal>
|
template<typename Signal>
|
||||||
using PromiseFromSignal = typename QtPromise::QPromise<Unqualified<typename ArgsOf<Signal>::first>>;
|
using PromiseFromSignal = typename QtPromise::QPromise<Unqualified<typename ArgsOf<Signal>::first>>;
|
||||||
|
|
||||||
// Connect signal() to QPromiseResolve
|
// Connect signal() to QPromiseResolve
|
||||||
template <typename Sender, typename Signal>
|
template<typename Sender, typename Signal>
|
||||||
typename std::enable_if<(ArgsOf<Signal>::count == 0)>::type
|
typename std::enable_if<(ArgsOf<Signal>::count == 0)>::type
|
||||||
connectSignalToResolver(
|
connectSignalToResolver(const QtPromise::QPromiseConnections& connections,
|
||||||
const QtPromise::QPromiseConnections& connections,
|
const QtPromise::QPromiseResolve<void>& resolve,
|
||||||
const QtPromise::QPromiseResolve<void>& resolve,
|
const Sender* sender,
|
||||||
const Sender* sender,
|
Signal signal)
|
||||||
Signal signal)
|
|
||||||
{
|
{
|
||||||
connections << QObject::connect(sender, signal, [=]() {
|
connections << QObject::connect(sender, signal, [=]() {
|
||||||
connections.disconnect();
|
connections.disconnect();
|
||||||
@ -35,13 +34,12 @@ connectSignalToResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect signal() to QPromiseReject
|
// Connect signal() to QPromiseReject
|
||||||
template <typename T, typename Sender, typename Signal>
|
template<typename T, typename Sender, typename Signal>
|
||||||
typename std::enable_if<(ArgsOf<Signal>::count == 0)>::type
|
typename std::enable_if<(ArgsOf<Signal>::count == 0)>::type
|
||||||
connectSignalToResolver(
|
connectSignalToResolver(const QtPromise::QPromiseConnections& connections,
|
||||||
const QtPromise::QPromiseConnections& connections,
|
const QtPromise::QPromiseReject<T>& reject,
|
||||||
const QtPromise::QPromiseReject<T>& reject,
|
const Sender* sender,
|
||||||
const Sender* sender,
|
Signal signal)
|
||||||
Signal signal)
|
|
||||||
{
|
{
|
||||||
connections << QObject::connect(sender, signal, [=]() {
|
connections << QObject::connect(sender, signal, [=]() {
|
||||||
connections.disconnect();
|
connections.disconnect();
|
||||||
@ -50,13 +48,12 @@ connectSignalToResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect signal(args...) to QPromiseResolve
|
// Connect signal(args...) to QPromiseResolve
|
||||||
template <typename T, typename Sender, typename Signal>
|
template<typename T, typename Sender, typename Signal>
|
||||||
typename std::enable_if<(ArgsOf<Signal>::count >= 1)>::type
|
typename std::enable_if<(ArgsOf<Signal>::count >= 1)>::type
|
||||||
connectSignalToResolver(
|
connectSignalToResolver(const QtPromise::QPromiseConnections& connections,
|
||||||
const QtPromise::QPromiseConnections& connections,
|
const QtPromise::QPromiseResolve<T>& resolve,
|
||||||
const QtPromise::QPromiseResolve<T>& resolve,
|
const Sender* sender,
|
||||||
const Sender* sender,
|
Signal signal)
|
||||||
Signal signal)
|
|
||||||
{
|
{
|
||||||
connections << QObject::connect(sender, signal, [=](const T& value) {
|
connections << QObject::connect(sender, signal, [=](const T& value) {
|
||||||
connections.disconnect();
|
connections.disconnect();
|
||||||
@ -65,13 +62,12 @@ connectSignalToResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect signal(args...) to QPromiseReject
|
// Connect signal(args...) to QPromiseReject
|
||||||
template <typename T, typename Sender, typename Signal>
|
template<typename T, typename Sender, typename Signal>
|
||||||
typename std::enable_if<(ArgsOf<Signal>::count >= 1)>::type
|
typename std::enable_if<(ArgsOf<Signal>::count >= 1)>::type
|
||||||
connectSignalToResolver(
|
connectSignalToResolver(const QtPromise::QPromiseConnections& connections,
|
||||||
const QtPromise::QPromiseConnections& connections,
|
const QtPromise::QPromiseReject<T>& reject,
|
||||||
const QtPromise::QPromiseReject<T>& reject,
|
const Sender* sender,
|
||||||
const Sender* sender,
|
Signal signal)
|
||||||
Signal signal)
|
|
||||||
{
|
{
|
||||||
using V = Unqualified<typename ArgsOf<Signal>::first>;
|
using V = Unqualified<typename ArgsOf<Signal>::first>;
|
||||||
connections << QObject::connect(sender, signal, [=](const V& value) {
|
connections << QObject::connect(sender, signal, [=](const V& value) {
|
||||||
@ -81,11 +77,10 @@ connectSignalToResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect QObject::destroyed signal to QPromiseReject
|
// Connect QObject::destroyed signal to QPromiseReject
|
||||||
template <typename T, typename Sender>
|
template<typename T, typename Sender>
|
||||||
void connectDestroyedToReject(
|
void connectDestroyedToReject(const QtPromise::QPromiseConnections& connections,
|
||||||
const QtPromise::QPromiseConnections& connections,
|
const QtPromise::QPromiseReject<T>& reject,
|
||||||
const QtPromise::QPromiseReject<T>& reject,
|
const Sender* sender)
|
||||||
const Sender* sender)
|
|
||||||
{
|
{
|
||||||
connections << QObject::connect(sender, &QObject::destroyed, [=]() {
|
connections << QObject::connect(sender, &QObject::destroyed, [=]() {
|
||||||
connections.disconnect();
|
connections.disconnect();
|
||||||
|
@ -14,23 +14,23 @@
|
|||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
template <typename T> class QPromise;
|
template<typename T>
|
||||||
|
class QPromise;
|
||||||
|
|
||||||
} // namespace QtPromise
|
} // namespace QtPromise
|
||||||
|
|
||||||
namespace QtPromisePrivate {
|
namespace QtPromisePrivate {
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
class PromiseResolver
|
class PromiseResolver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PromiseResolver(QtPromise::QPromise<T> promise)
|
PromiseResolver(QtPromise::QPromise<T> promise) : m_d{new Data{}}
|
||||||
: m_d{new Data{}}
|
|
||||||
{
|
{
|
||||||
m_d->promise = new QtPromise::QPromise<T>{std::move(promise)};
|
m_d->promise = new QtPromise::QPromise<T>{std::move(promise)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E>
|
template<typename E>
|
||||||
void reject(E&& error)
|
void reject(E&& error)
|
||||||
{
|
{
|
||||||
auto promise = m_d->promise;
|
auto promise = m_d->promise;
|
||||||
@ -53,7 +53,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V>
|
template<typename V>
|
||||||
void resolve(V&& value)
|
void resolve(V&& value)
|
||||||
{
|
{
|
||||||
auto promise = m_d->promise;
|
auto promise = m_d->promise;
|
||||||
@ -93,51 +93,43 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // QtPromisePrivate
|
} // namespace QtPromisePrivate
|
||||||
|
|
||||||
namespace QtPromise {
|
namespace QtPromise {
|
||||||
|
|
||||||
template <class T>
|
template<class T>
|
||||||
class QPromiseResolve
|
class QPromiseResolve
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPromiseResolve(QtPromisePrivate::PromiseResolver<T> resolver)
|
QPromiseResolve(QtPromisePrivate::PromiseResolver<T> resolver) : m_resolver{std::move(resolver)}
|
||||||
: m_resolver{std::move(resolver)}
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename V>
|
template<typename V>
|
||||||
void operator()(V&& value) const
|
void operator()(V&& value) const
|
||||||
{
|
{
|
||||||
m_resolver.resolve(std::forward<V>(value));
|
m_resolver.resolve(std::forward<V>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const { m_resolver.resolve(); }
|
||||||
{
|
|
||||||
m_resolver.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template<class T>
|
||||||
class QPromiseReject
|
class QPromiseReject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPromiseReject(QtPromisePrivate::PromiseResolver<T> resolver)
|
QPromiseReject(QtPromisePrivate::PromiseResolver<T> resolver) : m_resolver{std::move(resolver)}
|
||||||
: m_resolver{std::move(resolver)}
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename E>
|
template<typename E>
|
||||||
void operator()(E&& error) const
|
void operator()(E&& error) const
|
||||||
{
|
{
|
||||||
m_resolver.reject(std::forward<E>(error));
|
m_resolver.reject(std::forward<E>(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() const
|
void operator()() const { m_resolver.reject(); }
|
||||||
{
|
|
||||||
m_resolver.reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
|
|
||||||
#ifdef Q_CC_MSVC
|
#ifdef Q_CC_MSVC
|
||||||
// MSVC calls the copy constructor on std::current_exception AND std::rethrow_exception
|
// MSVC calls the copy constructor on std::current_exception AND std::rethrow_exception
|
||||||
// https://stackoverflow.com/a/31820854
|
// https://stackoverflow.com/a/31820854
|
||||||
#define EXCEPT_CALL_COPY_CTOR 1
|
# define EXCEPT_CALL_COPY_CTOR 1
|
||||||
#else
|
#else
|
||||||
#define EXCEPT_CALL_COPY_CTOR 0
|
# define EXCEPT_CALL_COPY_CTOR 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace QtPromise;
|
using namespace QtPromise;
|
||||||
@ -41,7 +41,7 @@ QTEST_MAIN(tst_benchmark)
|
|||||||
|
|
||||||
void tst_benchmark::valueResolve()
|
void tst_benchmark::valueResolve()
|
||||||
{
|
{
|
||||||
{ // should move the value when resolved by rvalue
|
{ // should move the value when resolved by rvalue
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>{[&](const QPromiseResolve<Data>& resolve) {
|
QPromise<Data>{[&](const QPromiseResolve<Data>& resolve) {
|
||||||
resolve(Data{42});
|
resolve(Data{42});
|
||||||
@ -49,10 +49,10 @@ void tst_benchmark::valueResolve()
|
|||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
QCOMPARE(Data::logs().move, 1); // move value to the promise data
|
QCOMPARE(Data::logs().move, 1); // move value to the promise data
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
}
|
}
|
||||||
{ // should create one copy of the value when resolved by lvalue
|
{ // should create one copy of the value when resolved by lvalue
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>{[&](const QPromiseResolve<Data>& resolve) {
|
QPromise<Data>{[&](const QPromiseResolve<Data>& resolve) {
|
||||||
Data value{42};
|
Data value{42};
|
||||||
@ -60,7 +60,7 @@ void tst_benchmark::valueResolve()
|
|||||||
}}.wait();
|
}}.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 1); // copy value to the promise data
|
QCOMPARE(Data::logs().copy, 1); // copy value to the promise data
|
||||||
QCOMPARE(Data::logs().move, 0);
|
QCOMPARE(Data::logs().move, 0);
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ void tst_benchmark::valueResolve()
|
|||||||
|
|
||||||
void tst_benchmark::valueReject()
|
void tst_benchmark::valueReject()
|
||||||
{
|
{
|
||||||
{ // should not create any data if rejected
|
{ // should not create any data if rejected
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>{[&](const QPromiseResolve<Data>&, const QPromiseReject<Data>& reject) {
|
QPromise<Data>{[&](const QPromiseResolve<Data>&, const QPromiseReject<Data>& reject) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
@ -83,28 +83,34 @@ void tst_benchmark::valueReject()
|
|||||||
|
|
||||||
void tst_benchmark::valueThen()
|
void tst_benchmark::valueThen()
|
||||||
{
|
{
|
||||||
{ // should not copy value on continutation if fulfilled
|
{ // should not copy value on continutation if fulfilled
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>::resolve(Data{42}).then([&](const Data& res) {
|
QPromise<Data>::resolve(Data{42})
|
||||||
value = res.value();
|
.then([&](const Data& res) {
|
||||||
}).wait();
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
QCOMPARE(Data::logs().move, 1); // move value to the promise data
|
QCOMPARE(Data::logs().move, 1); // move value to the promise data
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
}
|
}
|
||||||
{ // should not create value on continutation if rejected
|
{ // should not create value on continutation if rejected
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QString error;
|
QString error;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>::reject(QString{"foo"}).then([&](const Data& res) {
|
QPromise<Data>::reject(QString{"foo"})
|
||||||
value = res.value();
|
.then(
|
||||||
}, [&](const QString& err) {
|
[&](const Data& res) {
|
||||||
error = err;
|
value = res.value();
|
||||||
}).wait();
|
},
|
||||||
|
[&](const QString& err) {
|
||||||
|
error = err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 0);
|
QCOMPARE(Data::logs().ctor, 0);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
@ -113,27 +119,32 @@ void tst_benchmark::valueThen()
|
|||||||
QCOMPARE(error, QString{"foo"});
|
QCOMPARE(error, QString{"foo"});
|
||||||
QCOMPARE(value, -1);
|
QCOMPARE(value, -1);
|
||||||
}
|
}
|
||||||
{ // should move the returned value when fulfilled
|
{ // should move the returned value when fulfilled
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<int>::resolve(42).then([&](int res) {
|
QPromise<int>::resolve(42)
|
||||||
return Data{res+2};
|
.then([&](int res) {
|
||||||
}).then([&](const Data& res) {
|
return Data{res + 2};
|
||||||
value = res.value();
|
})
|
||||||
}).wait();
|
.then([&](const Data& res) {
|
||||||
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
QCOMPARE(Data::logs().move, 1); // move values to the next promise data
|
QCOMPARE(Data::logs().move, 1); // move values to the next promise data
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 44);
|
QCOMPARE(value, 44);
|
||||||
}
|
}
|
||||||
{ // should not create any data if handler throws
|
{ // should not create any data if handler throws
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<int>::resolve(42).then([&](int res) {
|
QPromise<int>::resolve(42)
|
||||||
throw QString{"foo"};
|
.then([&](int res) {
|
||||||
return Data{res+2};
|
throw QString{"foo"};
|
||||||
}).wait();
|
return Data{res + 2};
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 0);
|
QCOMPARE(Data::logs().ctor, 0);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
@ -144,26 +155,31 @@ void tst_benchmark::valueThen()
|
|||||||
|
|
||||||
void tst_benchmark::valueDelayed()
|
void tst_benchmark::valueDelayed()
|
||||||
{
|
{
|
||||||
{ // should not copy the value on continutation if fulfilled
|
{ // should not copy the value on continutation if fulfilled
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<int>::resolve(42).then([&](int res) {
|
QPromise<int>::resolve(42)
|
||||||
return QPromise<Data>::resolve(Data{res + 1});
|
.then([&](int res) {
|
||||||
}).then([&](const Data& res) {
|
return QPromise<Data>::resolve(Data{res + 1});
|
||||||
value = res.value();
|
})
|
||||||
}).wait();
|
.then([&](const Data& res) {
|
||||||
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
QCOMPARE(Data::logs().move, 1); // move value to the input promise data
|
QCOMPARE(Data::logs().move, 1); // move value to the input promise data
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 43);
|
QCOMPARE(value, 43);
|
||||||
}
|
}
|
||||||
{ // should not create value on continutation if rejected
|
{ // should not create value on continutation if rejected
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<int>::resolve(42).then([&]() {
|
QPromise<int>::resolve(42)
|
||||||
return QPromise<Data>::reject(QString{"foo"});
|
.then([&]() {
|
||||||
}).wait();
|
return QPromise<Data>::reject(QString{"foo"});
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 0);
|
QCOMPARE(Data::logs().ctor, 0);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
@ -174,25 +190,29 @@ void tst_benchmark::valueDelayed()
|
|||||||
|
|
||||||
void tst_benchmark::valueFinally()
|
void tst_benchmark::valueFinally()
|
||||||
{
|
{
|
||||||
{ // should not copy the value on continutation if fulfilled
|
{ // should not copy the value on continutation if fulfilled
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>::resolve(Data{42}).finally([&]() {
|
QPromise<Data>::resolve(Data{42})
|
||||||
value = 42;
|
.finally([&]() {
|
||||||
}).wait();
|
value = 42;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
QCOMPARE(Data::logs().move, 1); // move value to the input and output promise data
|
QCOMPARE(Data::logs().move, 1); // move value to the input and output promise data
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
}
|
}
|
||||||
{ // should not create value on continutation if rejected
|
{ // should not create value on continutation if rejected
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>::reject(QString{"foo"}).finally([&]() {
|
QPromise<Data>::reject(QString{"foo"})
|
||||||
value = 42;
|
.finally([&]() {
|
||||||
}).wait();
|
value = 42;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 0);
|
QCOMPARE(Data::logs().ctor, 0);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
@ -204,25 +224,29 @@ void tst_benchmark::valueFinally()
|
|||||||
|
|
||||||
void tst_benchmark::valueTap()
|
void tst_benchmark::valueTap()
|
||||||
{
|
{
|
||||||
{ // should not copy the value on continutation if fulfilled
|
{ // should not copy the value on continutation if fulfilled
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>::resolve(Data{42}).tap([&](const Data& res) {
|
QPromise<Data>::resolve(Data{42})
|
||||||
value = res.value();
|
.tap([&](const Data& res) {
|
||||||
}).wait();
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
QCOMPARE(Data::logs().move, 1); // move value to the input and output promise data
|
QCOMPARE(Data::logs().move, 1); // move value to the input and output promise data
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
}
|
}
|
||||||
{ // should not create value on continutation if rejected
|
{ // should not create value on continutation if rejected
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<Data>::reject(QString{"foo"}).tap([&](const Data& res) {
|
QPromise<Data>::reject(QString{"foo"})
|
||||||
value = res.value();
|
.tap([&](const Data& res) {
|
||||||
}).wait();
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 0);
|
QCOMPARE(Data::logs().ctor, 0);
|
||||||
QCOMPARE(Data::logs().copy, 0);
|
QCOMPARE(Data::logs().copy, 0);
|
||||||
@ -234,18 +258,18 @@ void tst_benchmark::valueTap()
|
|||||||
|
|
||||||
void tst_benchmark::errorReject()
|
void tst_benchmark::errorReject()
|
||||||
{
|
{
|
||||||
{ // should create one copy of the error when rejected by rvalue
|
{ // should create one copy of the error when rejected by rvalue
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<int>{[&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
QPromise<int>{[&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
reject(Data{42});
|
reject(Data{42});
|
||||||
}}.wait();
|
}}.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 1 + EXCEPT_CALL_COPY_CTOR); // copy value in std::exception_ptr
|
QCOMPARE(Data::logs().copy, 1 + EXCEPT_CALL_COPY_CTOR); // copy value in std::exception_ptr
|
||||||
QCOMPARE(Data::logs().move, 0);
|
QCOMPARE(Data::logs().move, 0);
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
}
|
}
|
||||||
{ // should create one copy of the error when rejected by lvalue (no extra copy)
|
{ // should create one copy of the error when rejected by lvalue (no extra copy)
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<int>{[&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
QPromise<int>{[&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
Data error{42};
|
Data error{42};
|
||||||
@ -253,7 +277,7 @@ void tst_benchmark::errorReject()
|
|||||||
}}.wait();
|
}}.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 1 + EXCEPT_CALL_COPY_CTOR); // copy value to the promise data
|
QCOMPARE(Data::logs().copy, 1 + EXCEPT_CALL_COPY_CTOR); // copy value to the promise data
|
||||||
QCOMPARE(Data::logs().move, 0);
|
QCOMPARE(Data::logs().move, 0);
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
}
|
}
|
||||||
@ -261,30 +285,37 @@ void tst_benchmark::errorReject()
|
|||||||
|
|
||||||
void tst_benchmark::errorThen()
|
void tst_benchmark::errorThen()
|
||||||
{
|
{
|
||||||
{ // should not copy error on continutation if rejected
|
{ // should not copy error on continutation if rejected
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<void>::reject(Data{42}).fail([&](const Data& res) {
|
QPromise<void>::reject(Data{42})
|
||||||
value = res.value();
|
.fail([&](const Data& res) {
|
||||||
}).wait();
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 1 + 2 * EXCEPT_CALL_COPY_CTOR); // (initial) copy value in std::exception_ptr
|
QCOMPARE(Data::logs().copy,
|
||||||
|
1 + 2 * EXCEPT_CALL_COPY_CTOR); // (initial) copy value in std::exception_ptr
|
||||||
QCOMPARE(Data::logs().move, 0);
|
QCOMPARE(Data::logs().move, 0);
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
}
|
}
|
||||||
{ // should not copy error on continutation if rethrown
|
{ // should not copy error on continutation if rethrown
|
||||||
int value = -1;
|
int value = -1;
|
||||||
Data::logs().reset();
|
Data::logs().reset();
|
||||||
QPromise<void>::reject(Data{42}).fail([](const Data&) {
|
QPromise<void>::reject(Data{42})
|
||||||
throw;
|
.fail([](const Data&) {
|
||||||
}).fail([&](const Data& res) {
|
throw;
|
||||||
value = res.value();
|
})
|
||||||
}).wait();
|
.fail([&](const Data& res) {
|
||||||
|
value = res.value();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(Data::logs().ctor, 1);
|
QCOMPARE(Data::logs().ctor, 1);
|
||||||
QCOMPARE(Data::logs().copy, 1 + 4 * EXCEPT_CALL_COPY_CTOR); // (initial) copy value in std::exception_ptr
|
QCOMPARE(Data::logs().copy,
|
||||||
|
1 + 4 * EXCEPT_CALL_COPY_CTOR); // (initial) copy value in std::exception_ptr
|
||||||
QCOMPARE(Data::logs().move, 0);
|
QCOMPARE(Data::logs().move, 0);
|
||||||
QCOMPARE(Data::logs().refs, 0);
|
QCOMPARE(Data::logs().refs, 0);
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
|
@ -175,7 +175,7 @@ void tst_deprecations_helpers_qpromise::stdSharedPtr()
|
|||||||
void tst_deprecations_helpers_qpromise::typedPromise()
|
void tst_deprecations_helpers_qpromise::typedPromise()
|
||||||
{
|
{
|
||||||
auto resolver = [](const QPromiseResolve<int>& resolve) {
|
auto resolver = [](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -202,7 +202,7 @@ void tst_deprecations_helpers_qpromise::typedPromise()
|
|||||||
void tst_deprecations_helpers_qpromise::voidPromise()
|
void tst_deprecations_helpers_qpromise::voidPromise()
|
||||||
{
|
{
|
||||||
auto resolver = [](const QPromiseResolve<void>& resolve) {
|
auto resolver = [](const QPromiseResolve<void>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -228,7 +228,9 @@ void tst_deprecations_helpers_qpromise::voidPromise()
|
|||||||
|
|
||||||
void tst_deprecations_helpers_qpromise::typedFuture()
|
void tst_deprecations_helpers_qpromise::typedFuture()
|
||||||
{
|
{
|
||||||
auto fn = [](){ return 42; };
|
auto fn = []() {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
QFuture<int> v0 = QtConcurrent::run(fn);
|
QFuture<int> v0 = QtConcurrent::run(fn);
|
||||||
const QFuture<int> v1 = v0;
|
const QFuture<int> v1 = v0;
|
||||||
|
|
||||||
@ -250,7 +252,7 @@ void tst_deprecations_helpers_qpromise::typedFuture()
|
|||||||
|
|
||||||
void tst_deprecations_helpers_qpromise::voidFuture()
|
void tst_deprecations_helpers_qpromise::voidFuture()
|
||||||
{
|
{
|
||||||
auto fn = [](){ };
|
auto fn = []() {};
|
||||||
QFuture<void> v0 = QtConcurrent::run(fn);
|
QFuture<void> v0 = QtConcurrent::run(fn);
|
||||||
const QFuture<void> v1 = v0;
|
const QFuture<void> v1 = v0;
|
||||||
|
|
||||||
|
@ -33,18 +33,14 @@ QTEST_MAIN(tst_deprecations_helpers_qpromiseall)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QPromise<int>>::value));
|
||||||
|
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence promises{
|
Sequence promises{QtPromise::resolve(42), QtPromise::resolve(43), QtPromise::resolve(44)};
|
||||||
QtPromise::resolve(42),
|
|
||||||
QtPromise::resolve(43),
|
|
||||||
QtPromise::resolve(44)
|
|
||||||
};
|
|
||||||
|
|
||||||
promises.push_back(QtPromise::resolve(45));
|
promises.push_back(QtPromise::resolve(45));
|
||||||
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
||||||
@ -58,16 +54,14 @@ struct SequenceTester
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <template <typename, typename...> class Sequence, typename ...Args>
|
template<template<typename, typename...> class Sequence, typename... Args>
|
||||||
struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence<QPromise<void>, Args...> promises{
|
Sequence<QPromise<void>, Args...> promises{QtPromise::resolve(),
|
||||||
QtPromise::resolve(),
|
QtPromise::resolve(),
|
||||||
QtPromise::resolve(),
|
QtPromise::resolve()};
|
||||||
QtPromise::resolve()
|
|
||||||
};
|
|
||||||
|
|
||||||
promises.push_back(QtPromise::resolve());
|
promises.push_back(QtPromise::resolve());
|
||||||
promises.insert(++promises.begin(), QtPromise::resolve());
|
promises.insert(++promises.begin(), QtPromise::resolve());
|
||||||
@ -106,7 +100,7 @@ void tst_deprecations_helpers_qpromiseall::allPromisesSucceed()
|
|||||||
auto p0 = QtPromise::resolve(42);
|
auto p0 = QtPromise::resolve(42);
|
||||||
auto p1 = QtPromise::resolve(44);
|
auto p1 = QtPromise::resolve(44);
|
||||||
auto p2 = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p2 = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(43);
|
resolve(43);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -127,7 +121,7 @@ void tst_deprecations_helpers_qpromiseall::allPromisesSucceed_void()
|
|||||||
auto p0 = QtPromise::resolve();
|
auto p0 = QtPromise::resolve();
|
||||||
auto p1 = QtPromise::resolve();
|
auto p1 = QtPromise::resolve();
|
||||||
auto p2 = QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
auto p2 = QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -148,7 +142,7 @@ void tst_deprecations_helpers_qpromiseall::atLeastOnePromiseReject()
|
|||||||
auto p0 = QtPromise::resolve(42);
|
auto p0 = QtPromise::resolve(42);
|
||||||
auto p1 = QtPromise::resolve(44);
|
auto p1 = QtPromise::resolve(44);
|
||||||
auto p2 = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
auto p2 = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -169,7 +163,7 @@ void tst_deprecations_helpers_qpromiseall::atLeastOnePromiseReject_void()
|
|||||||
auto p0 = QtPromise::resolve();
|
auto p0 = QtPromise::resolve();
|
||||||
auto p1 = QtPromise::resolve();
|
auto p1 = QtPromise::resolve();
|
||||||
auto p2 = QPromise<void>{[](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
auto p2 = QPromise<void>{[](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -210,7 +204,7 @@ void tst_deprecations_helpers_qpromiseall::preserveOrder()
|
|||||||
void tst_deprecations_helpers_qpromiseall::sequenceTypes()
|
void tst_deprecations_helpers_qpromiseall::sequenceTypes()
|
||||||
{
|
{
|
||||||
SequenceTester<QList<QPromise<int>>>::exec();
|
SequenceTester<QList<QPromise<int>>>::exec();
|
||||||
//SequenceTester<QVector<QPromise<int>>>::exec();
|
// SequenceTester<QVector<QPromise<int>>>::exec();
|
||||||
SequenceTester<std::list<QPromise<int>>>::exec();
|
SequenceTester<std::list<QPromise<int>>>::exec();
|
||||||
SequenceTester<std::vector<QPromise<int>>>::exec();
|
SequenceTester<std::vector<QPromise<int>>>::exec();
|
||||||
}
|
}
|
||||||
@ -218,7 +212,7 @@ void tst_deprecations_helpers_qpromiseall::sequenceTypes()
|
|||||||
void tst_deprecations_helpers_qpromiseall::sequenceTypes_void()
|
void tst_deprecations_helpers_qpromiseall::sequenceTypes_void()
|
||||||
{
|
{
|
||||||
SequenceTester<QList<QPromise<void>>>::exec();
|
SequenceTester<QList<QPromise<void>>>::exec();
|
||||||
//SequenceTester<QVector<QPromise<void>>>::exec();
|
// SequenceTester<QVector<QPromise<void>>>::exec();
|
||||||
SequenceTester<std::list<QPromise<void>>>::exec();
|
SequenceTester<std::list<QPromise<void>>>::exec();
|
||||||
SequenceTester<std::vector<QPromise<void>>>::exec();
|
SequenceTester<std::vector<QPromise<void>>>::exec();
|
||||||
}
|
}
|
||||||
|
@ -33,18 +33,14 @@ QTEST_MAIN(tst_deprecations_qpromise_all)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QPromise<int>>::value));
|
||||||
|
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence promises{
|
Sequence promises{QtPromise::resolve(42), QtPromise::resolve(43), QtPromise::resolve(44)};
|
||||||
QtPromise::resolve(42),
|
|
||||||
QtPromise::resolve(43),
|
|
||||||
QtPromise::resolve(44)
|
|
||||||
};
|
|
||||||
|
|
||||||
promises.push_back(QtPromise::resolve(45));
|
promises.push_back(QtPromise::resolve(45));
|
||||||
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
||||||
@ -59,16 +55,14 @@ struct SequenceTester
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <template <typename, typename...> class Sequence, typename ...Args>
|
template<template<typename, typename...> class Sequence, typename... Args>
|
||||||
struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence<QPromise<void>, Args...> promises{
|
Sequence<QPromise<void>, Args...> promises{QtPromise::resolve(),
|
||||||
QtPromise::resolve(),
|
QtPromise::resolve(),
|
||||||
QtPromise::resolve(),
|
QtPromise::resolve()};
|
||||||
QtPromise::resolve()
|
|
||||||
};
|
|
||||||
|
|
||||||
promises.push_back(QtPromise::resolve());
|
promises.push_back(QtPromise::resolve());
|
||||||
promises.insert(++promises.begin(), QtPromise::resolve());
|
promises.insert(++promises.begin(), QtPromise::resolve());
|
||||||
@ -110,7 +104,7 @@ void tst_deprecations_qpromise_all::allPromisesSucceed()
|
|||||||
auto p0 = QtPromise::resolve(42);
|
auto p0 = QtPromise::resolve(42);
|
||||||
auto p1 = QtPromise::resolve(44);
|
auto p1 = QtPromise::resolve(44);
|
||||||
auto p2 = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p2 = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(43);
|
resolve(43);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -132,7 +126,7 @@ void tst_deprecations_qpromise_all::allPromisesSucceed_void()
|
|||||||
auto p0 = QtPromise::resolve();
|
auto p0 = QtPromise::resolve();
|
||||||
auto p1 = QtPromise::resolve();
|
auto p1 = QtPromise::resolve();
|
||||||
auto p2 = QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
auto p2 = QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -154,7 +148,7 @@ void tst_deprecations_qpromise_all::atLeastOnePromiseReject()
|
|||||||
auto p0 = QtPromise::resolve(42);
|
auto p0 = QtPromise::resolve(42);
|
||||||
auto p1 = QtPromise::resolve(44);
|
auto p1 = QtPromise::resolve(44);
|
||||||
auto p2 = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
auto p2 = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -176,7 +170,7 @@ void tst_deprecations_qpromise_all::atLeastOnePromiseReject_void()
|
|||||||
auto p0 = QtPromise::resolve();
|
auto p0 = QtPromise::resolve();
|
||||||
auto p1 = QtPromise::resolve();
|
auto p1 = QtPromise::resolve();
|
||||||
auto p2 = QPromise<void>{[](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
auto p2 = QPromise<void>{[](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -219,7 +213,7 @@ void tst_deprecations_qpromise_all::preserveOrder()
|
|||||||
void tst_deprecations_qpromise_all::sequenceTypes()
|
void tst_deprecations_qpromise_all::sequenceTypes()
|
||||||
{
|
{
|
||||||
SequenceTester<QList<QPromise<int>>>::exec();
|
SequenceTester<QList<QPromise<int>>>::exec();
|
||||||
//SequenceTester<QVector<QPromise<int>>>::exec();
|
// SequenceTester<QVector<QPromise<int>>>::exec();
|
||||||
SequenceTester<std::list<QPromise<int>>>::exec();
|
SequenceTester<std::list<QPromise<int>>>::exec();
|
||||||
SequenceTester<std::vector<QPromise<int>>>::exec();
|
SequenceTester<std::vector<QPromise<int>>>::exec();
|
||||||
}
|
}
|
||||||
@ -227,7 +221,7 @@ void tst_deprecations_qpromise_all::sequenceTypes()
|
|||||||
void tst_deprecations_qpromise_all::sequenceTypes_void()
|
void tst_deprecations_qpromise_all::sequenceTypes_void()
|
||||||
{
|
{
|
||||||
SequenceTester<QList<QPromise<void>>>::exec();
|
SequenceTester<QList<QPromise<void>>>::exec();
|
||||||
//SequenceTester<QVector<QPromise<void>>>::exec();
|
// SequenceTester<QVector<QPromise<void>>>::exec();
|
||||||
SequenceTester<std::list<QPromise<void>>>::exec();
|
SequenceTester<std::list<QPromise<void>>>::exec();
|
||||||
SequenceTester<std::vector<QPromise<void>>>::exec();
|
SequenceTester<std::vector<QPromise<void>>>::exec();
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,12 @@ QTEST_MAIN(tst_exceptions)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class E>
|
template<class E>
|
||||||
void verify()
|
void verify()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::resolve(QtConcurrent::run([]() { throw E(); }));
|
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||||
|
throw E();
|
||||||
|
}));
|
||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
QCOMPARE(waitForRejected<E>(p), true);
|
QCOMPARE(waitForRejected<E>(p), true);
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
|
@ -37,9 +37,7 @@ private Q_SLOTS:
|
|||||||
class MyException : public QException
|
class MyException : public QException
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MyException(const QString& error)
|
MyException(const QString& error) : m_error{error} { }
|
||||||
: m_error{error}
|
|
||||||
{ }
|
|
||||||
|
|
||||||
const QString& error() const { return m_error; }
|
const QString& error() const { return m_error; }
|
||||||
|
|
||||||
@ -64,8 +62,8 @@ void tst_future::fulfilled()
|
|||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.then([&](int res) {
|
p.then([&](int res) {
|
||||||
result = res;
|
result = res;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
QCOMPARE(result, 42);
|
QCOMPARE(result, 42);
|
||||||
@ -74,14 +72,14 @@ void tst_future::fulfilled()
|
|||||||
void tst_future::fulfilled_void()
|
void tst_future::fulfilled_void()
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
auto p = QtPromise::resolve(QtConcurrent::run([]() { }));
|
auto p = QtPromise::resolve(QtConcurrent::run([]() {}));
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.then([&]() {
|
p.then([&]() {
|
||||||
result = 42;
|
result = 42;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
QCOMPARE(result, 42);
|
QCOMPARE(result, 42);
|
||||||
@ -99,9 +97,9 @@ void tst_future::rejected()
|
|||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const MyException& e) {
|
p.fail([&](const MyException& e) {
|
||||||
error = e.error();
|
error = e.error();
|
||||||
return -1;
|
return -1;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"foo"});
|
QCOMPARE(error, QString{"foo"});
|
||||||
@ -119,8 +117,8 @@ void tst_future::rejected_void()
|
|||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const MyException& e) {
|
p.fail([&](const MyException& e) {
|
||||||
error = e.error();
|
error = e.error();
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"foo"});
|
QCOMPARE(error, QString{"foo"});
|
||||||
@ -139,12 +137,14 @@ void tst_future::unhandled()
|
|||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const QString& err) {
|
p.fail([&](const QString& err) {
|
||||||
error += err;
|
error += err;
|
||||||
return -1;
|
return -1;
|
||||||
}).fail([&](const QUnhandledException&) {
|
})
|
||||||
error += "bar";
|
.fail([&](const QUnhandledException&) {
|
||||||
return -1;
|
error += "bar";
|
||||||
}).wait();
|
return -1;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"bar"});
|
QCOMPARE(error, QString{"bar"});
|
||||||
@ -161,10 +161,12 @@ void tst_future::unhandled_void()
|
|||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const QString& err) {
|
p.fail([&](const QString& err) {
|
||||||
error += err;
|
error += err;
|
||||||
}).fail([&](const QUnhandledException&) {
|
})
|
||||||
error += "bar";
|
.fail([&](const QUnhandledException&) {
|
||||||
}).wait();
|
error += "bar";
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"bar"});
|
QCOMPARE(error, QString{"bar"});
|
||||||
@ -173,14 +175,14 @@ void tst_future::unhandled_void()
|
|||||||
void tst_future::canceled()
|
void tst_future::canceled()
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
auto p = QtPromise::resolve(QFuture<int>()); // Constructs an empty, canceled future.
|
auto p = QtPromise::resolve(QFuture<int>()); // Constructs an empty, canceled future.
|
||||||
|
|
||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const QPromiseCanceledException&) {
|
p.fail([&](const QPromiseCanceledException&) {
|
||||||
error = "canceled";
|
error = "canceled";
|
||||||
return -1;
|
return -1;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"canceled"});
|
QCOMPARE(error, QString{"canceled"});
|
||||||
@ -189,13 +191,13 @@ void tst_future::canceled()
|
|||||||
void tst_future::canceled_void()
|
void tst_future::canceled_void()
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
auto p = QtPromise::resolve(QFuture<void>()); // Constructs an empty, canceled future.
|
auto p = QtPromise::resolve(QFuture<void>()); // Constructs an empty, canceled future.
|
||||||
|
|
||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const QPromiseCanceledException&) {
|
p.fail([&](const QPromiseCanceledException&) {
|
||||||
error = "canceled";
|
error = "canceled";
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"canceled"});
|
QCOMPARE(error, QString{"canceled"});
|
||||||
@ -211,8 +213,8 @@ void tst_future::canceledFromThread()
|
|||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
p.fail([&](const QPromiseCanceledException&) {
|
p.fail([&](const QPromiseCanceledException&) {
|
||||||
error = "bar";
|
error = "bar";
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"bar"});
|
QCOMPARE(error, QString{"bar"});
|
||||||
@ -231,9 +233,11 @@ void tst_future::then()
|
|||||||
QCOMPARE(input.isFulfilled(), true);
|
QCOMPARE(input.isFulfilled(), true);
|
||||||
QCOMPARE(output.isPending(), true);
|
QCOMPARE(output.isPending(), true);
|
||||||
|
|
||||||
output.then([&](const QString& res) {
|
output
|
||||||
result = res;
|
.then([&](const QString& res) {
|
||||||
}).wait();
|
result = res;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(output.isFulfilled(), true);
|
QCOMPARE(output.isFulfilled(), true);
|
||||||
QCOMPARE(result, QString{"foo42"});
|
QCOMPARE(result, QString{"foo42"});
|
||||||
@ -252,9 +256,11 @@ void tst_future::then_void()
|
|||||||
QCOMPARE(input.isFulfilled(), true);
|
QCOMPARE(input.isFulfilled(), true);
|
||||||
QCOMPARE(output.isPending(), true);
|
QCOMPARE(output.isPending(), true);
|
||||||
|
|
||||||
output.then([&]() {
|
output
|
||||||
result += "bar";
|
.then([&]() {
|
||||||
}).wait();
|
result += "bar";
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(input.isFulfilled(), true);
|
QCOMPARE(input.isFulfilled(), true);
|
||||||
QCOMPARE(result, QString{"foobar"});
|
QCOMPARE(result, QString{"foobar"});
|
||||||
@ -265,17 +271,21 @@ void tst_future::fail()
|
|||||||
QString result;
|
QString result;
|
||||||
auto input = QPromise<QString>::reject(MyException{"bar"});
|
auto input = QPromise<QString>::reject(MyException{"bar"});
|
||||||
auto output = input.fail([](const MyException& e) {
|
auto output = input.fail([](const MyException& e) {
|
||||||
return QtConcurrent::run([](const QString& error) {
|
return QtConcurrent::run(
|
||||||
return QString{"foo%1"}.arg(error);
|
[](const QString& error) {
|
||||||
}, e.error());
|
return QString{"foo%1"}.arg(error);
|
||||||
|
},
|
||||||
|
e.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
QCOMPARE(input.isRejected(), true);
|
QCOMPARE(input.isRejected(), true);
|
||||||
QCOMPARE(output.isPending(), true);
|
QCOMPARE(output.isPending(), true);
|
||||||
|
|
||||||
output.then([&](const QString& res) {
|
output
|
||||||
result = res;
|
.then([&](const QString& res) {
|
||||||
}).wait();
|
result = res;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(output.isFulfilled(), true);
|
QCOMPARE(output.isFulfilled(), true);
|
||||||
QCOMPARE(result, QString{"foobar"});
|
QCOMPARE(result, QString{"foobar"});
|
||||||
@ -286,17 +296,21 @@ void tst_future::fail_void()
|
|||||||
QString result;
|
QString result;
|
||||||
auto input = QPromise<void>::reject(MyException{"bar"});
|
auto input = QPromise<void>::reject(MyException{"bar"});
|
||||||
auto output = input.fail([&](const MyException& e) {
|
auto output = input.fail([&](const MyException& e) {
|
||||||
return QtConcurrent::run([&](const QString& error) {
|
return QtConcurrent::run(
|
||||||
result = error;
|
[&](const QString& error) {
|
||||||
}, e.error());
|
result = error;
|
||||||
|
},
|
||||||
|
e.error());
|
||||||
});
|
});
|
||||||
|
|
||||||
QCOMPARE(input.isRejected(), true);
|
QCOMPARE(input.isRejected(), true);
|
||||||
QCOMPARE(output.isPending(), true);
|
QCOMPARE(output.isPending(), true);
|
||||||
|
|
||||||
output.then([&]() {
|
output
|
||||||
result = result.prepend("foo");
|
.then([&]() {
|
||||||
}).wait();
|
result = result.prepend("foo");
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(output.isFulfilled(), true);
|
QCOMPARE(output.isFulfilled(), true);
|
||||||
QCOMPARE(result, QString{"foobar"});
|
QCOMPARE(result, QString{"foobar"});
|
||||||
@ -317,9 +331,11 @@ void tst_future::finally()
|
|||||||
QCOMPARE(output.isPending(), true);
|
QCOMPARE(output.isPending(), true);
|
||||||
|
|
||||||
int value = -1;
|
int value = -1;
|
||||||
output.then([&](int res) {
|
output
|
||||||
value = res;
|
.then([&](int res) {
|
||||||
}).wait();
|
value = res;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(output.isFulfilled(), true);
|
QCOMPARE(output.isFulfilled(), true);
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
@ -340,10 +356,12 @@ void tst_future::finallyRejected()
|
|||||||
QCOMPARE(output.isPending(), true);
|
QCOMPARE(output.isPending(), true);
|
||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
output.fail([&](const MyException& e) {
|
output
|
||||||
error = e.error();
|
.fail([&](const MyException& e) {
|
||||||
return -1;
|
error = e.error();
|
||||||
}).wait();
|
return -1;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(output.isRejected(), true);
|
QCOMPARE(output.isRejected(), true);
|
||||||
QCOMPARE(error, QString{"foo"});
|
QCOMPARE(error, QString{"foo"});
|
||||||
|
@ -33,18 +33,14 @@ QTEST_MAIN(tst_helpers_all)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<typename Sequence::value_type, QPromise<int>>::value));
|
||||||
|
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence promises{
|
Sequence promises{QtPromise::resolve(42), QtPromise::resolve(43), QtPromise::resolve(44)};
|
||||||
QtPromise::resolve(42),
|
|
||||||
QtPromise::resolve(43),
|
|
||||||
QtPromise::resolve(44)
|
|
||||||
};
|
|
||||||
|
|
||||||
promises.push_back(QtPromise::resolve(45));
|
promises.push_back(QtPromise::resolve(45));
|
||||||
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
||||||
@ -58,16 +54,14 @@ struct SequenceTester
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <template <typename, typename...> class Sequence, typename ...Args>
|
template<template<typename, typename...> class Sequence, typename... Args>
|
||||||
struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence<QPromise<void>, Args...> promises{
|
Sequence<QPromise<void>, Args...> promises{QtPromise::resolve(),
|
||||||
QtPromise::resolve(),
|
QtPromise::resolve(),
|
||||||
QtPromise::resolve(),
|
QtPromise::resolve()};
|
||||||
QtPromise::resolve()
|
|
||||||
};
|
|
||||||
|
|
||||||
promises.push_back(QtPromise::resolve());
|
promises.push_back(QtPromise::resolve());
|
||||||
promises.insert(++promises.begin(), QtPromise::resolve());
|
promises.insert(++promises.begin(), QtPromise::resolve());
|
||||||
@ -106,7 +100,7 @@ void tst_helpers_all::allPromisesSucceed()
|
|||||||
auto p0 = QtPromise::resolve(42);
|
auto p0 = QtPromise::resolve(42);
|
||||||
auto p1 = QtPromise::resolve(44);
|
auto p1 = QtPromise::resolve(44);
|
||||||
auto p2 = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p2 = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(43);
|
resolve(43);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -127,7 +121,7 @@ void tst_helpers_all::allPromisesSucceed_void()
|
|||||||
auto p0 = QtPromise::resolve();
|
auto p0 = QtPromise::resolve();
|
||||||
auto p1 = QtPromise::resolve();
|
auto p1 = QtPromise::resolve();
|
||||||
auto p2 = QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
auto p2 = QPromise<void>{[](const QPromiseResolve<void>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -148,7 +142,7 @@ void tst_helpers_all::atLeastOnePromiseReject()
|
|||||||
auto p0 = QtPromise::resolve(42);
|
auto p0 = QtPromise::resolve(42);
|
||||||
auto p1 = QtPromise::resolve(44);
|
auto p1 = QtPromise::resolve(44);
|
||||||
auto p2 = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
auto p2 = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -169,7 +163,7 @@ void tst_helpers_all::atLeastOnePromiseReject_void()
|
|||||||
auto p0 = QtPromise::resolve();
|
auto p0 = QtPromise::resolve();
|
||||||
auto p1 = QtPromise::resolve();
|
auto p1 = QtPromise::resolve();
|
||||||
auto p2 = QPromise<void>{[](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
auto p2 = QPromise<void>{[](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
@ -210,7 +204,7 @@ void tst_helpers_all::preserveOrder()
|
|||||||
void tst_helpers_all::sequenceTypes()
|
void tst_helpers_all::sequenceTypes()
|
||||||
{
|
{
|
||||||
SequenceTester<QList<QPromise<int>>>::exec();
|
SequenceTester<QList<QPromise<int>>>::exec();
|
||||||
//SequenceTester<QVector<QPromise<int>>>::exec();
|
// SequenceTester<QVector<QPromise<int>>>::exec();
|
||||||
SequenceTester<std::list<QPromise<int>>>::exec();
|
SequenceTester<std::list<QPromise<int>>>::exec();
|
||||||
SequenceTester<std::vector<QPromise<int>>>::exec();
|
SequenceTester<std::vector<QPromise<int>>>::exec();
|
||||||
}
|
}
|
||||||
@ -218,7 +212,7 @@ void tst_helpers_all::sequenceTypes()
|
|||||||
void tst_helpers_all::sequenceTypes_void()
|
void tst_helpers_all::sequenceTypes_void()
|
||||||
{
|
{
|
||||||
SequenceTester<QList<QPromise<void>>>::exec();
|
SequenceTester<QList<QPromise<void>>>::exec();
|
||||||
//SequenceTester<QVector<QPromise<void>>>::exec();
|
// SequenceTester<QVector<QPromise<void>>>::exec();
|
||||||
SequenceTester<std::list<QPromise<void>>>::exec();
|
SequenceTester<std::list<QPromise<void>>>::exec();
|
||||||
SequenceTester<std::vector<QPromise<void>>>::exec();
|
SequenceTester<std::vector<QPromise<void>>>::exec();
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,12 @@ void tst_helpers_attempt::functorThrows()
|
|||||||
|
|
||||||
void tst_helpers_attempt::callWithParams()
|
void tst_helpers_attempt::callWithParams()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::attempt([&](int i, const QString& s) {
|
auto p = QtPromise::attempt(
|
||||||
return QString{"%1:%2"}.arg(i).arg(s);
|
[&](int i, const QString& s) {
|
||||||
}, 42, "foo");
|
return QString{"%1:%2"}.arg(i).arg(s);
|
||||||
|
},
|
||||||
|
42,
|
||||||
|
"foo");
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
|
@ -32,7 +32,7 @@ QTEST_MAIN(tst_helpers_each)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
@ -92,11 +92,11 @@ void tst_helpers_each::delayedFulfilled()
|
|||||||
QMap<int, int> values;
|
QMap<int, int> values;
|
||||||
auto p = QtPromise::each(QVector<int>{42, 43, 44}, [&](int v, int index) {
|
auto p = QtPromise::each(QVector<int>{42, 43, 44}, [&](int v, int index) {
|
||||||
return QPromise<int>{[&](const QPromiseResolve<int>& resolve) {
|
return QPromise<int>{[&](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=, &values]() {
|
QtPromisePrivate::qtpromise_defer([=, &values]() {
|
||||||
values[v] = index;
|
values[v] = index;
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
});
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||||
@ -108,9 +108,8 @@ void tst_helpers_each::delayedFulfilled()
|
|||||||
void tst_helpers_each::delayedRejected()
|
void tst_helpers_each::delayedRejected()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::each(QVector<int>{42, 43, 44}, [](int v, ...) {
|
auto p = QtPromise::each(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||||
return QPromise<int>{[&](
|
return QPromise<int>{
|
||||||
const QPromiseResolve<int>& resolve,
|
[&](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||||
const QPromiseReject<int>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
if (v == 43) {
|
if (v == 43) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
|
@ -33,7 +33,7 @@ QTEST_MAIN(tst_helpers_filter)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
@ -74,10 +74,10 @@ void tst_helpers_filter::delayedFulfilled()
|
|||||||
{
|
{
|
||||||
auto p = QtPromise::filter(QVector<int>{42, 43, 44}, [](int v, ...) {
|
auto p = QtPromise::filter(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||||
return QPromise<bool>{[&](const QPromiseResolve<bool>& resolve) {
|
return QPromise<bool>{[&](const QPromiseResolve<bool>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(v % 2 == 0);
|
resolve(v % 2 == 0);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
});
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||||
@ -87,9 +87,8 @@ void tst_helpers_filter::delayedFulfilled()
|
|||||||
void tst_helpers_filter::delayedRejected()
|
void tst_helpers_filter::delayedRejected()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::filter(QVector<int>{42, 43, 44}, [](int v, ...) {
|
auto p = QtPromise::filter(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||||
return QPromise<bool>{[&](
|
return QPromise<bool>{
|
||||||
const QPromiseResolve<bool>& resolve,
|
[&](const QPromiseResolve<bool>& resolve, const QPromiseReject<bool>& reject) {
|
||||||
const QPromiseReject<bool>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
if (v == 44) {
|
if (v == 44) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
@ -119,7 +118,7 @@ void tst_helpers_filter::functorThrows()
|
|||||||
void tst_helpers_filter::functorArguments()
|
void tst_helpers_filter::functorArguments()
|
||||||
{
|
{
|
||||||
QMap<int, int> args;
|
QMap<int, int> args;
|
||||||
auto p = QtPromise::filter(QVector<int>{42, 43, 44}, [&](int v, int i) {
|
auto p = QtPromise::filter(QVector<int>{42, 43, 44}, [&](int v, int i) {
|
||||||
args[v] = i;
|
args[v] = i;
|
||||||
return i % 2 == 0;
|
return i % 2 == 0;
|
||||||
});
|
});
|
||||||
|
@ -33,7 +33,7 @@ QTEST_MAIN(tst_helpers_map)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
@ -83,10 +83,10 @@ void tst_helpers_map::delayedFulfilled()
|
|||||||
{
|
{
|
||||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||||
return QPromise<int>{[&](const QPromiseResolve<int>& resolve) {
|
return QPromise<int>{[&](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(v + 1);
|
resolve(v + 1);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
});
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||||
@ -96,9 +96,8 @@ void tst_helpers_map::delayedFulfilled()
|
|||||||
void tst_helpers_map::delayedRejected()
|
void tst_helpers_map::delayedRejected()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
auto p = QtPromise::map(QVector<int>{42, 43, 44}, [](int v, ...) {
|
||||||
return QPromise<int>{[&](
|
return QPromise<int>{
|
||||||
const QPromiseResolve<int>& resolve,
|
[&](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||||
const QPromiseReject<int>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
if (v == 43) {
|
if (v == 43) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
|
@ -34,16 +34,14 @@ QTEST_MAIN(tst_helpers_reduce)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence inputs{
|
Sequence inputs{QtPromise::resolve(4).delay(400),
|
||||||
QtPromise::resolve(4).delay(400),
|
QtPromise::resolve(6).delay(300),
|
||||||
QtPromise::resolve(6).delay(300),
|
QtPromise::resolve(8).delay(200)};
|
||||||
QtPromise::resolve(8).delay(200)
|
|
||||||
};
|
|
||||||
QVector<int> v0;
|
QVector<int> v0;
|
||||||
QVector<int> v1;
|
QVector<int> v1;
|
||||||
|
|
||||||
@ -51,10 +49,13 @@ struct SequenceTester
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::reduce(inputs, [&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::reduce(
|
||||||
v1 << acc << cur << idx;
|
inputs,
|
||||||
return acc + cur + idx;
|
[&](int acc, int cur, int idx) {
|
||||||
}, QtPromise::resolve(2).delay(100));
|
v1 << acc << cur << idx;
|
||||||
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
QtPromise::resolve(2).delay(100));
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -74,10 +75,13 @@ void tst_helpers_reduce::emptySequence()
|
|||||||
{
|
{
|
||||||
bool called = false;
|
bool called = false;
|
||||||
|
|
||||||
auto p = QtPromise::reduce(QVector<int>{}, [&](...) {
|
auto p = QtPromise::reduce(
|
||||||
called = true;
|
QVector<int>{},
|
||||||
return 43;
|
[&](...) {
|
||||||
}, 42);
|
called = true;
|
||||||
|
return 43;
|
||||||
|
},
|
||||||
|
42);
|
||||||
|
|
||||||
// NOTE(SB): reduce() on an empty sequence without an initial value is an error!
|
// NOTE(SB): reduce() on an empty sequence without an initial value is an error!
|
||||||
|
|
||||||
@ -97,10 +101,13 @@ void tst_helpers_reduce::regularValues()
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::reduce(inputs, [&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::reduce(
|
||||||
v1 << acc << cur << idx;
|
inputs,
|
||||||
return acc + cur + idx;
|
[&](int acc, int cur, int idx) {
|
||||||
}, 2);
|
v1 << acc << cur << idx;
|
||||||
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -115,11 +122,9 @@ void tst_helpers_reduce::regularValues()
|
|||||||
|
|
||||||
void tst_helpers_reduce::promiseValues()
|
void tst_helpers_reduce::promiseValues()
|
||||||
{
|
{
|
||||||
QVector<QPromise<int>> inputs{
|
QVector<QPromise<int>> inputs{QtPromise::resolve(4).delay(400),
|
||||||
QtPromise::resolve(4).delay(400),
|
QtPromise::resolve(6).delay(300),
|
||||||
QtPromise::resolve(6).delay(300),
|
QtPromise::resolve(8).delay(200)};
|
||||||
QtPromise::resolve(8).delay(200)
|
|
||||||
};
|
|
||||||
QVector<int> v0;
|
QVector<int> v0;
|
||||||
QVector<int> v1;
|
QVector<int> v1;
|
||||||
|
|
||||||
@ -127,10 +132,13 @@ void tst_helpers_reduce::promiseValues()
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::reduce(inputs, [&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::reduce(
|
||||||
v1 << acc << cur << idx;
|
inputs,
|
||||||
return acc + cur + idx;
|
[&](int acc, int cur, int idx) {
|
||||||
}, 2);
|
v1 << acc << cur << idx;
|
||||||
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -147,9 +155,12 @@ void tst_helpers_reduce::convertResultType()
|
|||||||
{
|
{
|
||||||
QVector<int> inputs{4, 6, 8};
|
QVector<int> inputs{4, 6, 8};
|
||||||
|
|
||||||
auto p = QtPromise::reduce(inputs, [&](const QString& acc, int cur, int idx) {
|
auto p = QtPromise::reduce(
|
||||||
return QString{"%1:%2:%3"}.arg(acc).arg(cur).arg(idx);
|
inputs,
|
||||||
}, QString{"foo"});
|
[&](const QString& acc, int cur, int idx) {
|
||||||
|
return QString{"%1:%2:%3"}.arg(acc).arg(cur).arg(idx);
|
||||||
|
},
|
||||||
|
QString{"foo"});
|
||||||
|
|
||||||
// NOTE(SB): when no initial value is given, the result type is the sequence type.
|
// NOTE(SB): when no initial value is given, the result type is the sequence type.
|
||||||
|
|
||||||
@ -163,10 +174,13 @@ void tst_helpers_reduce::delayedInitialValue()
|
|||||||
{
|
{
|
||||||
QVector<int> values;
|
QVector<int> values;
|
||||||
|
|
||||||
auto p = QtPromise::reduce(QVector<int>{4, 6, 8}, [&](int acc, int cur, int idx) {
|
auto p = QtPromise::reduce(
|
||||||
values << acc << cur << idx;
|
QVector<int>{4, 6, 8},
|
||||||
return acc + cur + idx;
|
[&](int acc, int cur, int idx) {
|
||||||
}, QtPromise::resolve(2).delay(100));
|
values << acc << cur << idx;
|
||||||
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
QtPromise::resolve(2).delay(100));
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||||
|
|
||||||
@ -185,10 +199,13 @@ void tst_helpers_reduce::delayedFulfilled()
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return QtPromise::resolve(acc + cur + idx).delay(100);
|
return QtPromise::resolve(acc + cur + idx).delay(100);
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::reduce(inputs, [&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::reduce(
|
||||||
v1 << acc << cur << idx;
|
inputs,
|
||||||
return QtPromise::resolve(acc + cur + idx).delay(100);
|
[&](int acc, int cur, int idx) {
|
||||||
}, 2);
|
v1 << acc << cur << idx;
|
||||||
|
return QtPromise::resolve(acc + cur + idx).delay(100);
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -214,13 +231,16 @@ void tst_helpers_reduce::delayedRejected()
|
|||||||
}
|
}
|
||||||
return QtPromise::resolve(acc + cur + idx);
|
return QtPromise::resolve(acc + cur + idx);
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::reduce(inputs, [&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::reduce(
|
||||||
v1 << acc << cur << idx;
|
inputs,
|
||||||
if (cur == 6) {
|
[&](int acc, int cur, int idx) {
|
||||||
return QPromise<int>::reject(QString{"bar"});
|
v1 << acc << cur << idx;
|
||||||
}
|
if (cur == 6) {
|
||||||
return QtPromise::resolve(acc + cur + idx);
|
return QPromise<int>::reject(QString{"bar"});
|
||||||
}, 2);
|
}
|
||||||
|
return QtPromise::resolve(acc + cur + idx);
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -246,13 +266,16 @@ void tst_helpers_reduce::functorThrows()
|
|||||||
}
|
}
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::reduce(inputs, [&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::reduce(
|
||||||
v1 << acc << cur << idx;
|
inputs,
|
||||||
if (cur == 6) {
|
[&](int acc, int cur, int idx) {
|
||||||
throw QString{"bar"};
|
v1 << acc << cur << idx;
|
||||||
}
|
if (cur == 6) {
|
||||||
return acc + cur + idx;
|
throw QString{"bar"};
|
||||||
}, 2);
|
}
|
||||||
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
#include "../shared/data.h"
|
#include "../shared/data.h"
|
||||||
#include "../shared/utils.h"
|
#include "../shared/utils.h"
|
||||||
|
|
||||||
#include <QtPromise>
|
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
#include <QtPromise>
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -175,7 +175,7 @@ void tst_helpers_resolve::stdSharedPtr()
|
|||||||
void tst_helpers_resolve::typedPromise()
|
void tst_helpers_resolve::typedPromise()
|
||||||
{
|
{
|
||||||
auto resolver = [](const QPromiseResolve<int>& resolve) {
|
auto resolver = [](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -202,7 +202,7 @@ void tst_helpers_resolve::typedPromise()
|
|||||||
void tst_helpers_resolve::voidPromise()
|
void tst_helpers_resolve::voidPromise()
|
||||||
{
|
{
|
||||||
auto resolver = [](const QPromiseResolve<void>& resolve) {
|
auto resolver = [](const QPromiseResolve<void>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=](){
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -228,7 +228,9 @@ void tst_helpers_resolve::voidPromise()
|
|||||||
|
|
||||||
void tst_helpers_resolve::typedFuture()
|
void tst_helpers_resolve::typedFuture()
|
||||||
{
|
{
|
||||||
auto fn = [](){ return 42; };
|
auto fn = []() {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
QFuture<int> v0 = QtConcurrent::run(fn);
|
QFuture<int> v0 = QtConcurrent::run(fn);
|
||||||
const QFuture<int> v1 = v0;
|
const QFuture<int> v1 = v0;
|
||||||
|
|
||||||
@ -250,7 +252,7 @@ void tst_helpers_resolve::typedFuture()
|
|||||||
|
|
||||||
void tst_helpers_resolve::voidFuture()
|
void tst_helpers_resolve::voidFuture()
|
||||||
{
|
{
|
||||||
auto fn = [](){ };
|
auto fn = []() {};
|
||||||
QFuture<void> v0 = QtConcurrent::run(fn);
|
QFuture<void> v0 = QtConcurrent::run(fn);
|
||||||
const QFuture<void> v1 = v0;
|
const QFuture<void> v1 = v0;
|
||||||
|
|
||||||
|
@ -27,43 +27,88 @@ private Q_SLOTS:
|
|||||||
QTEST_MAIN(tst_internals_argsof)
|
QTEST_MAIN(tst_internals_argsof)
|
||||||
#include "tst_argsof.moc"
|
#include "tst_argsof.moc"
|
||||||
|
|
||||||
#define TEST_ARGS_FOR_TYPE(T, E) \
|
#define TEST_ARGS_FOR_TYPE(T, E) \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<T>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<T>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<T&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<T&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<T&&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<T&&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const T>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const T>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const T&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const T&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const T&&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const T&&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<volatile T>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<volatile T>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<volatile T&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<volatile T&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<volatile T&&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<volatile T&&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const volatile T>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const volatile T>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const volatile T&>::first, E>::value)); \
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const volatile T&>::first, E>::value)); \
|
||||||
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const volatile T&&>::first, E>::value));
|
Q_STATIC_ASSERT((std::is_same<typename ArgsOf<const volatile T&&>::first, E>::value));
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const float kRes = 0.42f;
|
const float kRes = 0.42f;
|
||||||
|
|
||||||
float fnNoArg() { return kRes; }
|
float fnNoArg()
|
||||||
float fnOneArg(float v) { return v; }
|
{
|
||||||
float fnManyArgs(const float& v0, int, char*) { return v0; }
|
return kRes;
|
||||||
|
}
|
||||||
|
float fnOneArg(float v)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
float fnManyArgs(const float& v0, int, char*)
|
||||||
|
{
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
||||||
struct OpNoArg { float operator()() { return kRes; } };
|
struct OpNoArg
|
||||||
struct OpOneArg { float operator()(float v) { return v; } };
|
{
|
||||||
struct OpManyArgs { float operator()(const float& v, int, char*) { return v; } };
|
float operator()() { return kRes; }
|
||||||
|
};
|
||||||
|
struct OpOneArg
|
||||||
|
{
|
||||||
|
float operator()(float v) { return v; }
|
||||||
|
};
|
||||||
|
struct OpManyArgs
|
||||||
|
{
|
||||||
|
float operator()(const float& v, int, char*) { return v; }
|
||||||
|
};
|
||||||
|
|
||||||
struct OpCNoArg { float operator()() const { return kRes; } };
|
struct OpCNoArg
|
||||||
struct OpCOneArg { float operator()(float v) const { return v; } };
|
{
|
||||||
struct OpCManyArgs { float operator()(const float& v, int, char*) const { return v; } };
|
float operator()() const { return kRes; }
|
||||||
|
};
|
||||||
|
struct OpCOneArg
|
||||||
|
{
|
||||||
|
float operator()(float v) const { return v; }
|
||||||
|
};
|
||||||
|
struct OpCManyArgs
|
||||||
|
{
|
||||||
|
float operator()(const float& v, int, char*) const { return v; }
|
||||||
|
};
|
||||||
|
|
||||||
struct OpVNoArg { float operator()() volatile { return kRes; } };
|
struct OpVNoArg
|
||||||
struct OpVOneArg { float operator()(float v) volatile { return v; } };
|
{
|
||||||
struct OpVManyArgs { float operator()(const float& v, int, char*) volatile { return v; } };
|
float operator()() volatile { return kRes; }
|
||||||
|
};
|
||||||
|
struct OpVOneArg
|
||||||
|
{
|
||||||
|
float operator()(float v) volatile { return v; }
|
||||||
|
};
|
||||||
|
struct OpVManyArgs
|
||||||
|
{
|
||||||
|
float operator()(const float& v, int, char*) volatile { return v; }
|
||||||
|
};
|
||||||
|
|
||||||
struct OpCVNoArg { float operator()() const volatile { return kRes; } };
|
struct OpCVNoArg
|
||||||
struct OpCVOneArg { float operator()(float v) const volatile { return v; } };
|
{
|
||||||
struct OpCVManyArgs { float operator()(const float& v, int, char*) const volatile { return v; } };
|
float operator()() const volatile { return kRes; }
|
||||||
|
};
|
||||||
|
struct OpCVOneArg
|
||||||
|
{
|
||||||
|
float operator()(float v) const volatile { return v; }
|
||||||
|
};
|
||||||
|
struct OpCVManyArgs
|
||||||
|
{
|
||||||
|
float operator()(const float& v, int, char*) const volatile { return v; }
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -270,23 +270,23 @@ void tst_qpromise_construct::connectAndResolve()
|
|||||||
std::weak_ptr<int> wptr;
|
std::weak_ptr<int> wptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = QPromise<std::shared_ptr<int>>{[&](
|
auto p =
|
||||||
const QPromiseResolve<std::shared_ptr<int>>& resolve,
|
QPromise<std::shared_ptr<int>>{[&](const QPromiseResolve<std::shared_ptr<int>>& resolve,
|
||||||
const QPromiseReject<std::shared_ptr<int>>& reject) {
|
const QPromiseReject<std::shared_ptr<int>>& reject) {
|
||||||
|
connect(object.data(),
|
||||||
|
&QObject::objectNameChanged,
|
||||||
|
[=, &wptr](const QString& name) {
|
||||||
|
auto sptr = std::make_shared<int>(42);
|
||||||
|
|
||||||
connect(object.data(), &QObject::objectNameChanged,
|
wptr = sptr;
|
||||||
[=, &wptr](const QString& name) {
|
|
||||||
auto sptr = std::make_shared<int>(42);
|
|
||||||
|
|
||||||
wptr = sptr;
|
if (name == "foobar") {
|
||||||
|
resolve(sptr);
|
||||||
if (name == "foobar") {
|
} else {
|
||||||
resolve(sptr);
|
reject(42);
|
||||||
} else {
|
}
|
||||||
reject(42);
|
});
|
||||||
}
|
}};
|
||||||
});
|
|
||||||
}};
|
|
||||||
|
|
||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
|
||||||
@ -307,22 +307,19 @@ void tst_qpromise_construct::connectAndReject()
|
|||||||
std::weak_ptr<int> wptr;
|
std::weak_ptr<int> wptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = QPromise<int>{[&](
|
auto p = QPromise<int>{[&](const QPromiseResolve<int>& resolve,
|
||||||
const QPromiseResolve<int>& resolve,
|
const QPromiseReject<int>& reject) {
|
||||||
const QPromiseReject<int>& reject) {
|
connect(object.data(), &QObject::objectNameChanged, [=, &wptr](const QString& name) {
|
||||||
|
auto sptr = std::make_shared<int>(42);
|
||||||
|
|
||||||
connect(object.data(), &QObject::objectNameChanged,
|
wptr = sptr;
|
||||||
[=, &wptr](const QString& name) {
|
|
||||||
auto sptr = std::make_shared<int>(42);
|
|
||||||
|
|
||||||
wptr = sptr;
|
if (name == "foobar") {
|
||||||
|
reject(sptr);
|
||||||
if (name == "foobar") {
|
} else {
|
||||||
reject(sptr);
|
resolve(42);
|
||||||
} else {
|
}
|
||||||
resolve(42);
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
QCOMPARE(p.isPending(), true);
|
QCOMPARE(p.isPending(), true);
|
||||||
|
@ -32,36 +32,34 @@ QTEST_MAIN(tst_qpromise_each)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
QVector<int> values;
|
QVector<int> values;
|
||||||
auto p = QtPromise::resolve(Sequence{42, 43, 44}).each([&](int v, int i) {
|
auto p = QtPromise::resolve(Sequence{42, 43, 44})
|
||||||
values << i << v;
|
.each([&](int v, int i) {
|
||||||
}).each([&](int v, ...) {
|
values << i << v;
|
||||||
values << v;
|
})
|
||||||
return QString{"foo"};
|
.each([&](int v, ...) {
|
||||||
}).each([&](int v, ...) {
|
values << v;
|
||||||
values << v + 1;
|
return QString{"foo"};
|
||||||
return QtPromise::resolve(QString{"foo"}).then([&](){
|
})
|
||||||
values << -1;
|
.each([&](int v, ...) {
|
||||||
});
|
values << v + 1;
|
||||||
}).each([&](int v, ...) {
|
return QtPromise::resolve(QString{"foo"}).then([&]() {
|
||||||
values << v + 2;
|
values << -1;
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.each([&](int v, ...) {
|
||||||
|
values << v + 2;
|
||||||
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Sequence>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Sequence>>::value));
|
||||||
QCOMPARE(waitForValue(p, Sequence{}), (Sequence{42, 43, 44}));
|
QCOMPARE(waitForValue(p, Sequence{}), (Sequence{42, 43, 44}));
|
||||||
|
|
||||||
QVector<int> expected{
|
QVector<int> expected{0, 42, 1, 43, 2, 44, 42, 43, 44, 43, 44, 45, -1, -1, -1, 44, 45, 46};
|
||||||
0, 42, 1, 43, 2, 44,
|
|
||||||
42, 43, 44,
|
|
||||||
43, 44, 45,
|
|
||||||
-1, -1, -1,
|
|
||||||
44, 45, 46
|
|
||||||
};
|
|
||||||
QCOMPARE(values, expected);
|
QCOMPARE(values, expected);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -124,9 +122,8 @@ void tst_qpromise_each::delayedFulfilled()
|
|||||||
void tst_qpromise_each::delayedRejected()
|
void tst_qpromise_each::delayedRejected()
|
||||||
{
|
{
|
||||||
auto p = QPromise<QVector<int>>::resolve({42, 43, 44}).each([](int v, ...) {
|
auto p = QPromise<QVector<int>>::resolve({42, 43, 44}).each([](int v, ...) {
|
||||||
return QPromise<int>{[&](
|
return QPromise<int>{
|
||||||
const QPromiseResolve<int>& resolve,
|
[&](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||||
const QPromiseReject<int>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
if (v == 44) {
|
if (v == 44) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
|
@ -36,18 +36,28 @@ const QString kErr{"0.42"};
|
|||||||
const float kRes = 0.42f;
|
const float kRes = 0.42f;
|
||||||
const float kFail = -1.f;
|
const float kFail = -1.f;
|
||||||
|
|
||||||
float fnNoArg() { return kErr.toFloat(); }
|
float fnNoArg()
|
||||||
float fnArgByVal(QString e) { return e.toFloat(); }
|
{
|
||||||
float fnArgByRef(const QString& e) { return e.toFloat(); }
|
return kErr.toFloat();
|
||||||
|
}
|
||||||
|
float fnArgByVal(QString e)
|
||||||
|
{
|
||||||
|
return e.toFloat();
|
||||||
|
}
|
||||||
|
float fnArgByRef(const QString& e)
|
||||||
|
{
|
||||||
|
return e.toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
class Klass {
|
class Klass
|
||||||
|
{
|
||||||
public: // STATICS
|
public: // STATICS
|
||||||
static float kFnNoArg() { return kErr.toFloat(); }
|
static float kFnNoArg() { return kErr.toFloat(); }
|
||||||
static float kFnArgByVal(QString e) { return e.toFloat(); }
|
static float kFnArgByVal(QString e) { return e.toFloat(); }
|
||||||
static float kFnArgByRef(const QString& e) { return e.toFloat(); }
|
static float kFnArgByRef(const QString& e) { return e.toFloat(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Klass(float v) : m_v{v} {}
|
Klass(float v) : m_v{v} { }
|
||||||
|
|
||||||
float fnNoArg() const { return m_v; }
|
float fnNoArg() const { return m_v; }
|
||||||
float fnArgByVal(QString v) const { return v.toFloat() + m_v; }
|
float fnArgByVal(QString v) const { return v.toFloat() + m_v; }
|
||||||
@ -66,15 +76,18 @@ void tst_qpromise_fail::sameType()
|
|||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
p.fail([&](const std::domain_error& e) {
|
p.fail([&](const std::domain_error& e) {
|
||||||
error += QString{e.what()} + "0";
|
error += QString{e.what()} + "0";
|
||||||
return -1;
|
return -1;
|
||||||
}).fail([&](const std::out_of_range& e) {
|
})
|
||||||
error += QString{e.what()} + "1";
|
.fail([&](const std::out_of_range& e) {
|
||||||
return -1;
|
error += QString{e.what()} + "1";
|
||||||
}).fail([&](const std::exception& e) {
|
return -1;
|
||||||
error += QString{e.what()} + "2";
|
})
|
||||||
return -1;
|
.fail([&](const std::exception& e) {
|
||||||
}).wait();
|
error += QString{e.what()} + "2";
|
||||||
|
return -1;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(error, QString{"foo1"});
|
QCOMPARE(error, QString{"foo1"});
|
||||||
}
|
}
|
||||||
@ -86,15 +99,18 @@ void tst_qpromise_fail::baseClass()
|
|||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
p.fail([&](const std::runtime_error& e) {
|
p.fail([&](const std::runtime_error& e) {
|
||||||
error += QString{e.what()} + "0";
|
error += QString{e.what()} + "0";
|
||||||
return -1;
|
return -1;
|
||||||
}).fail([&](const std::logic_error& e) {
|
})
|
||||||
error += QString{e.what()} + "1";
|
.fail([&](const std::logic_error& e) {
|
||||||
return -1;
|
error += QString{e.what()} + "1";
|
||||||
}).fail([&](const std::exception& e) {
|
return -1;
|
||||||
error += QString{e.what()} + "2";
|
})
|
||||||
return -1;
|
.fail([&](const std::exception& e) {
|
||||||
}).wait();
|
error += QString{e.what()} + "2";
|
||||||
|
return -1;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(error, QString{"foo1"});
|
QCOMPARE(error, QString{"foo1"});
|
||||||
}
|
}
|
||||||
@ -105,22 +121,25 @@ void tst_qpromise_fail::catchAll()
|
|||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
p.fail([&](const std::runtime_error& e) {
|
p.fail([&](const std::runtime_error& e) {
|
||||||
error += QString{e.what()} + "0";
|
error += QString{e.what()} + "0";
|
||||||
return -1;
|
return -1;
|
||||||
}).fail([&]() {
|
})
|
||||||
error += "bar";
|
.fail([&]() {
|
||||||
return -1;
|
error += "bar";
|
||||||
}).fail([&](const std::exception& e) {
|
return -1;
|
||||||
error += QString{e.what()} + "2";
|
})
|
||||||
return -1;
|
.fail([&](const std::exception& e) {
|
||||||
}).wait();
|
error += QString{e.what()} + "2";
|
||||||
|
return -1;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(error, QString{"bar"});
|
QCOMPARE(error, QString{"bar"});
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_qpromise_fail::functionPtrHandlers()
|
void tst_qpromise_fail::functionPtrHandlers()
|
||||||
{
|
{
|
||||||
{ // Global functions.
|
{ // Global functions.
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail(&fnNoArg);
|
auto p0 = QPromise<float>::reject(kErr).fail(&fnNoArg);
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail(&fnArgByVal);
|
auto p1 = QPromise<float>::reject(kErr).fail(&fnArgByVal);
|
||||||
auto p2 = QPromise<float>::reject(kErr).fail(&fnArgByRef);
|
auto p2 = QPromise<float>::reject(kErr).fail(&fnArgByRef);
|
||||||
@ -129,7 +148,7 @@ void tst_qpromise_fail::functionPtrHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // Static member functions.
|
{ // Static member functions.
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail(&Klass::kFnNoArg);
|
auto p0 = QPromise<float>::reject(kErr).fail(&Klass::kFnNoArg);
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail(&Klass::kFnArgByVal);
|
auto p1 = QPromise<float>::reject(kErr).fail(&Klass::kFnArgByVal);
|
||||||
auto p2 = QPromise<float>::reject(kErr).fail(&Klass::kFnArgByRef);
|
auto p2 = QPromise<float>::reject(kErr).fail(&Klass::kFnArgByRef);
|
||||||
@ -143,7 +162,7 @@ void tst_qpromise_fail::functionPtrHandlers()
|
|||||||
// https://github.com/simonbrunel/qtpromise/issues/29
|
// https://github.com/simonbrunel/qtpromise/issues/29
|
||||||
void tst_qpromise_fail::stdFunctionHandlers()
|
void tst_qpromise_fail::stdFunctionHandlers()
|
||||||
{
|
{
|
||||||
{ // lvalue.
|
{ // lvalue.
|
||||||
std::function<float()> stdFnNoArg = fnNoArg;
|
std::function<float()> stdFnNoArg = fnNoArg;
|
||||||
std::function<float(QString)> stdFnArgByVal = fnArgByVal;
|
std::function<float(QString)> stdFnArgByVal = fnArgByVal;
|
||||||
std::function<float(const QString&)> stdFnArgByRef = fnArgByRef;
|
std::function<float(const QString&)> stdFnArgByRef = fnArgByRef;
|
||||||
@ -156,7 +175,7 @@ void tst_qpromise_fail::stdFunctionHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // const lvalue.
|
{ // const lvalue.
|
||||||
const std::function<float()> stdFnNoArg = fnNoArg;
|
const std::function<float()> stdFnNoArg = fnNoArg;
|
||||||
const std::function<float(QString)> stdFnArgByVal = fnArgByVal;
|
const std::function<float(QString)> stdFnArgByVal = fnArgByVal;
|
||||||
const std::function<float(const QString&)> stdFnArgByRef = fnArgByRef;
|
const std::function<float(const QString&)> stdFnArgByRef = fnArgByRef;
|
||||||
@ -169,10 +188,11 @@ void tst_qpromise_fail::stdFunctionHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // rvalue.
|
{ // rvalue.
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail(std::function<float()>{fnNoArg});
|
auto p0 = QPromise<float>::reject(kErr).fail(std::function<float()>{fnNoArg});
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail(std::function<float(QString)>{fnArgByVal});
|
auto p1 = QPromise<float>::reject(kErr).fail(std::function<float(QString)>{fnArgByVal});
|
||||||
auto p2 = QPromise<float>::reject(kErr).fail(std::function<float(const QString&)>{fnArgByRef});
|
auto p2 =
|
||||||
|
QPromise<float>::reject(kErr).fail(std::function<float(const QString&)>{fnArgByRef});
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p0, kFail), kRes);
|
QCOMPARE(waitForValue(p0, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
@ -190,7 +210,8 @@ void tst_qpromise_fail::stdBindHandlers()
|
|||||||
|
|
||||||
const std::function<float()> bindNoArg = std::bind(&Klass::fnNoArg, &obj);
|
const std::function<float()> bindNoArg = std::bind(&Klass::fnNoArg, &obj);
|
||||||
const std::function<float(QString)> bindArgByVal = std::bind(&Klass::fnArgByVal, &obj, _1);
|
const std::function<float(QString)> bindArgByVal = std::bind(&Klass::fnArgByVal, &obj, _1);
|
||||||
const std::function<float(const QString&)> bindArgByRef = std::bind(&Klass::fnArgByRef, &obj, _1);
|
const std::function<float(const QString&)> bindArgByRef =
|
||||||
|
std::bind(&Klass::fnArgByRef, &obj, _1);
|
||||||
|
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail(bindNoArg);
|
auto p0 = QPromise<float>::reject(kErr).fail(bindNoArg);
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail(bindArgByVal);
|
auto p1 = QPromise<float>::reject(kErr).fail(bindArgByVal);
|
||||||
@ -203,10 +224,16 @@ void tst_qpromise_fail::stdBindHandlers()
|
|||||||
|
|
||||||
void tst_qpromise_fail::lambdaHandlers()
|
void tst_qpromise_fail::lambdaHandlers()
|
||||||
{
|
{
|
||||||
{ // lvalue.
|
{ // lvalue.
|
||||||
auto lambdaNoArg = []() { return kRes; };
|
auto lambdaNoArg = []() {
|
||||||
auto lambdaArgByVal = [](QString v) { return v.toFloat(); };
|
return kRes;
|
||||||
auto lambdaArgByRef = [](const QString& v) { return v.toFloat(); };
|
};
|
||||||
|
auto lambdaArgByVal = [](QString v) {
|
||||||
|
return v.toFloat();
|
||||||
|
};
|
||||||
|
auto lambdaArgByRef = [](const QString& v) {
|
||||||
|
return v.toFloat();
|
||||||
|
};
|
||||||
|
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail(lambdaNoArg);
|
auto p0 = QPromise<float>::reject(kErr).fail(lambdaNoArg);
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail(lambdaArgByVal);
|
auto p1 = QPromise<float>::reject(kErr).fail(lambdaArgByVal);
|
||||||
@ -216,10 +243,16 @@ void tst_qpromise_fail::lambdaHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // const lvalue.
|
{ // const lvalue.
|
||||||
const auto lambdaNoArg = []() { return kRes; };
|
const auto lambdaNoArg = []() {
|
||||||
const auto lambdaArgByVal = [](QString v) { return v.toFloat(); };
|
return kRes;
|
||||||
const auto lambdaArgByRef = [](const QString& v) { return v.toFloat(); };
|
};
|
||||||
|
const auto lambdaArgByVal = [](QString v) {
|
||||||
|
return v.toFloat();
|
||||||
|
};
|
||||||
|
const auto lambdaArgByRef = [](const QString& v) {
|
||||||
|
return v.toFloat();
|
||||||
|
};
|
||||||
|
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail(lambdaNoArg);
|
auto p0 = QPromise<float>::reject(kErr).fail(lambdaNoArg);
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail(lambdaArgByVal);
|
auto p1 = QPromise<float>::reject(kErr).fail(lambdaArgByVal);
|
||||||
@ -229,10 +262,16 @@ void tst_qpromise_fail::lambdaHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // rvalue.
|
{ // rvalue.
|
||||||
auto p0 = QPromise<float>::reject(kErr).fail([]() { return kRes; });
|
auto p0 = QPromise<float>::reject(kErr).fail([]() {
|
||||||
auto p1 = QPromise<float>::reject(kErr).fail([](QString v) { return v.toFloat(); });
|
return kRes;
|
||||||
auto p2 = QPromise<float>::reject(kErr).fail([](const QString& v) { return v.toFloat(); });
|
});
|
||||||
|
auto p1 = QPromise<float>::reject(kErr).fail([](QString v) {
|
||||||
|
return v.toFloat();
|
||||||
|
});
|
||||||
|
auto p2 = QPromise<float>::reject(kErr).fail([](const QString& v) {
|
||||||
|
return v.toFloat();
|
||||||
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p0, kFail), kRes);
|
QCOMPARE(waitForValue(p0, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
|
@ -33,20 +33,21 @@ QTEST_MAIN(tst_qpromise_filter)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::resolve(Sequence{
|
auto p = QtPromise::resolve(Sequence{42, 43, 44, 45, 46, 47, 48, 49, 50, 51})
|
||||||
42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
.filter([](int v, ...) {
|
||||||
}).filter([](int v, ...) {
|
return v > 42 && v < 51;
|
||||||
return v > 42 && v < 51;
|
})
|
||||||
}).filter([](int, int i) {
|
.filter([](int, int i) {
|
||||||
return QPromise<bool>::resolve(i % 2 == 0);
|
return QPromise<bool>::resolve(i % 2 == 0);
|
||||||
}).filter([](int v, ...) {
|
})
|
||||||
return v != 45;
|
.filter([](int v, ...) {
|
||||||
});
|
return v != 45;
|
||||||
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Sequence>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Sequence>>::value));
|
||||||
QCOMPARE(waitForValue(p, Sequence{}), (Sequence{43, 47, 49}));
|
QCOMPARE(waitForValue(p, Sequence{}), (Sequence{43, 47, 49}));
|
||||||
@ -79,10 +80,10 @@ void tst_qpromise_filter::delayedFulfilled()
|
|||||||
{
|
{
|
||||||
auto p = QPromise<QVector<int>>::resolve({42, 43, 44}).filter([](int v, ...) {
|
auto p = QPromise<QVector<int>>::resolve({42, 43, 44}).filter([](int v, ...) {
|
||||||
return QPromise<bool>{[&](const QPromiseResolve<bool>& resolve) {
|
return QPromise<bool>{[&](const QPromiseResolve<bool>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(v % 2 == 0);
|
resolve(v % 2 == 0);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
});
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||||
@ -92,9 +93,8 @@ void tst_qpromise_filter::delayedFulfilled()
|
|||||||
void tst_qpromise_filter::delayedRejected()
|
void tst_qpromise_filter::delayedRejected()
|
||||||
{
|
{
|
||||||
auto p = QPromise<QVector<int>>::resolve({42, 43, 44}).filter([](int v, ...) {
|
auto p = QPromise<QVector<int>>::resolve({42, 43, 44}).filter([](int v, ...) {
|
||||||
return QPromise<bool>{[&](
|
return QPromise<bool>{
|
||||||
const QPromiseResolve<bool>& resolve,
|
[&](const QPromiseResolve<bool>& resolve, const QPromiseReject<bool>& reject) {
|
||||||
const QPromiseReject<bool>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
if (v == 43) {
|
if (v == 43) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
|
@ -184,8 +184,8 @@ void tst_qpromise_finally::rejectedAsyncResolve()
|
|||||||
});
|
});
|
||||||
|
|
||||||
p.then([&](int r) {
|
p.then([&](int r) {
|
||||||
values << r;
|
values << r;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
|
@ -33,23 +33,28 @@ QTEST_MAIN(tst_qpromise_map)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::resolve(Sequence{42, 43, 44}).map([](int v, ...) {
|
auto p = QtPromise::resolve(Sequence{42, 43, 44})
|
||||||
return QString::number(v + 1);
|
.map([](int v, ...) {
|
||||||
}).map([](const QString& v, int i) {
|
return QString::number(v + 1);
|
||||||
return QtPromise::resolve(QString{"%1:%2"}.arg(i).arg(v));
|
})
|
||||||
}).map([](const QString& v, ...) {
|
.map([](const QString& v, int i) {
|
||||||
return QtPromise::resolve((v + "!").toUtf8());
|
return QtPromise::resolve(QString{"%1:%2"}.arg(i).arg(v));
|
||||||
}).map([](const QByteArray& v, ...) {
|
})
|
||||||
return QString::fromUtf8(v);
|
.map([](const QString& v, ...) {
|
||||||
});
|
return QtPromise::resolve((v + "!").toUtf8());
|
||||||
|
})
|
||||||
|
.map([](const QByteArray& v, ...) {
|
||||||
|
return QString::fromUtf8(v);
|
||||||
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<QString>>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<QString>>>::value));
|
||||||
QCOMPARE(waitForValue(p, QVector<QString>{}), (QVector<QString>{"0:43!", "1:44!", "2:45!"}));
|
QCOMPARE(waitForValue(p, QVector<QString>{}),
|
||||||
|
(QVector<QString>{"0:43!", "1:44!", "2:45!"}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,10 +94,10 @@ void tst_qpromise_map::delayedFulfilled()
|
|||||||
{
|
{
|
||||||
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||||
return QPromise<int>{[&](const QPromiseResolve<int>& resolve) {
|
return QPromise<int>{[&](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
resolve(v + 1);
|
resolve(v + 1);
|
||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
});
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||||
@ -102,9 +107,8 @@ void tst_qpromise_map::delayedFulfilled()
|
|||||||
void tst_qpromise_map::delayedRejected()
|
void tst_qpromise_map::delayedRejected()
|
||||||
{
|
{
|
||||||
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||||
return QPromise<int>{[&](
|
return QPromise<int>{
|
||||||
const QPromiseResolve<int>& resolve,
|
[&](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||||
const QPromiseReject<int>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
if (v == 43) {
|
if (v == 43) {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
|
@ -204,7 +204,7 @@ void tst_qpromise_operators::notEqualTo_void()
|
|||||||
void tst_qpromise_operators::chaining()
|
void tst_qpromise_operators::chaining()
|
||||||
{
|
{
|
||||||
auto p = QPromise<int>::resolve(1);
|
auto p = QPromise<int>::resolve(1);
|
||||||
for (int i=0; i<4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
p = p.then([](int res) {
|
p = p.then([](int res) {
|
||||||
return QPromise<int>::resolve(res * 2);
|
return QPromise<int>::resolve(res * 2);
|
||||||
});
|
});
|
||||||
@ -220,7 +220,7 @@ void tst_qpromise_operators::chaining_void()
|
|||||||
|
|
||||||
auto p = QPromise<void>::resolve();
|
auto p = QPromise<void>::resolve();
|
||||||
|
|
||||||
for (int i=0; i<4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
p = p.then([i, &values]() {
|
p = p.then([i, &values]() {
|
||||||
values.append(i * 2);
|
values.append(i * 2);
|
||||||
return QPromise<void>::resolve();
|
return QPromise<void>::resolve();
|
||||||
|
@ -34,16 +34,14 @@ QTEST_MAIN(tst_qpromise_reduce)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <class Sequence>
|
template<class Sequence>
|
||||||
struct SequenceTester
|
struct SequenceTester
|
||||||
{
|
{
|
||||||
static void exec()
|
static void exec()
|
||||||
{
|
{
|
||||||
Sequence inputs{
|
Sequence inputs{QtPromise::resolve(4).delay(400),
|
||||||
QtPromise::resolve(4).delay(400),
|
QtPromise::resolve(6).delay(300),
|
||||||
QtPromise::resolve(6).delay(300),
|
QtPromise::resolve(8).delay(200)};
|
||||||
QtPromise::resolve(8).delay(200)
|
|
||||||
};
|
|
||||||
QVector<int> v0;
|
QVector<int> v0;
|
||||||
QVector<int> v1;
|
QVector<int> v1;
|
||||||
|
|
||||||
@ -51,10 +49,12 @@ struct SequenceTester
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::resolve(inputs).reduce([&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::resolve(inputs).reduce(
|
||||||
v1 << acc << cur << idx;
|
[&](int acc, int cur, int idx) {
|
||||||
return acc + cur + idx;
|
v1 << acc << cur << idx;
|
||||||
}, QtPromise::resolve(2).delay(100));
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
QtPromise::resolve(2).delay(100));
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -74,10 +74,13 @@ void tst_qpromise_reduce::emptySequence()
|
|||||||
{
|
{
|
||||||
bool called = false;
|
bool called = false;
|
||||||
|
|
||||||
auto p = QtPromise::resolve(QVector<int>{}).reduce([&](...) {
|
auto p = QtPromise::resolve(QVector<int>{})
|
||||||
called = true;
|
.reduce(
|
||||||
return 43;
|
[&](...) {
|
||||||
}, 42);
|
called = true;
|
||||||
|
return 43;
|
||||||
|
},
|
||||||
|
42);
|
||||||
|
|
||||||
// NOTE(SB): reduce() on an empty sequence without an initial value is an error!
|
// NOTE(SB): reduce() on an empty sequence without an initial value is an error!
|
||||||
|
|
||||||
@ -97,10 +100,12 @@ void tst_qpromise_reduce::regularValues()
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::resolve(inputs).reduce([&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::resolve(inputs).reduce(
|
||||||
v1 << acc << cur << idx;
|
[&](int acc, int cur, int idx) {
|
||||||
return acc + cur + idx;
|
v1 << acc << cur << idx;
|
||||||
}, 2);
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -115,11 +120,9 @@ void tst_qpromise_reduce::regularValues()
|
|||||||
|
|
||||||
void tst_qpromise_reduce::promiseValues()
|
void tst_qpromise_reduce::promiseValues()
|
||||||
{
|
{
|
||||||
QVector<QPromise<int>> inputs{
|
QVector<QPromise<int>> inputs{QtPromise::resolve(4).delay(400),
|
||||||
QtPromise::resolve(4).delay(400),
|
QtPromise::resolve(6).delay(300),
|
||||||
QtPromise::resolve(6).delay(300),
|
QtPromise::resolve(8).delay(200)};
|
||||||
QtPromise::resolve(8).delay(200)
|
|
||||||
};
|
|
||||||
QVector<int> v0;
|
QVector<int> v0;
|
||||||
QVector<int> v1;
|
QVector<int> v1;
|
||||||
|
|
||||||
@ -127,10 +130,12 @@ void tst_qpromise_reduce::promiseValues()
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::resolve(inputs).reduce([&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::resolve(inputs).reduce(
|
||||||
v1 << acc << cur << idx;
|
[&](int acc, int cur, int idx) {
|
||||||
return acc + cur + idx;
|
v1 << acc << cur << idx;
|
||||||
}, 2);
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -147,9 +152,11 @@ void tst_qpromise_reduce::convertResultType()
|
|||||||
{
|
{
|
||||||
QVector<int> inputs{4, 6, 8};
|
QVector<int> inputs{4, 6, 8};
|
||||||
|
|
||||||
auto p = QtPromise::resolve(inputs).reduce([&](const QString& acc, int cur, int idx) {
|
auto p = QtPromise::resolve(inputs).reduce(
|
||||||
return QString{"%1:%2:%3"}.arg(acc).arg(cur).arg(idx);
|
[&](const QString& acc, int cur, int idx) {
|
||||||
}, QString{"foo"});
|
return QString{"%1:%2:%3"}.arg(acc).arg(cur).arg(idx);
|
||||||
|
},
|
||||||
|
QString{"foo"});
|
||||||
|
|
||||||
// NOTE(SB): when no initial value is given, the result type is the sequence type.
|
// NOTE(SB): when no initial value is given, the result type is the sequence type.
|
||||||
|
|
||||||
@ -163,10 +170,13 @@ void tst_qpromise_reduce::delayedInitialValue()
|
|||||||
{
|
{
|
||||||
QVector<int> values;
|
QVector<int> values;
|
||||||
|
|
||||||
auto p = QtPromise::resolve(QVector<int>{4, 6, 8}).reduce([&](int acc, int cur, int idx) {
|
auto p = QtPromise::resolve(QVector<int>{4, 6, 8})
|
||||||
values << acc << cur << idx;
|
.reduce(
|
||||||
return acc + cur + idx;
|
[&](int acc, int cur, int idx) {
|
||||||
}, QtPromise::resolve(2).delay(100));
|
values << acc << cur << idx;
|
||||||
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
QtPromise::resolve(2).delay(100));
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||||
|
|
||||||
@ -185,10 +195,12 @@ void tst_qpromise_reduce::delayedFulfilled()
|
|||||||
v0 << acc << cur << idx;
|
v0 << acc << cur << idx;
|
||||||
return QtPromise::resolve(acc + cur + idx).delay(100);
|
return QtPromise::resolve(acc + cur + idx).delay(100);
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::resolve(inputs).reduce([&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::resolve(inputs).reduce(
|
||||||
v1 << acc << cur << idx;
|
[&](int acc, int cur, int idx) {
|
||||||
return QtPromise::resolve(acc + cur + idx).delay(100);
|
v1 << acc << cur << idx;
|
||||||
}, 2);
|
return QtPromise::resolve(acc + cur + idx).delay(100);
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -214,13 +226,15 @@ void tst_qpromise_reduce::delayedRejected()
|
|||||||
}
|
}
|
||||||
return QtPromise::resolve(acc + cur + idx);
|
return QtPromise::resolve(acc + cur + idx);
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::resolve(inputs).reduce([&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::resolve(inputs).reduce(
|
||||||
v1 << acc << cur << idx;
|
[&](int acc, int cur, int idx) {
|
||||||
if (cur == 6) {
|
v1 << acc << cur << idx;
|
||||||
return QPromise<int>::reject(QString{"bar"});
|
if (cur == 6) {
|
||||||
}
|
return QPromise<int>::reject(QString{"bar"});
|
||||||
return QtPromise::resolve(acc + cur + idx);
|
}
|
||||||
}, 2);
|
return QtPromise::resolve(acc + cur + idx);
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
@ -246,13 +260,15 @@ void tst_qpromise_reduce::functorThrows()
|
|||||||
}
|
}
|
||||||
return acc + cur + idx;
|
return acc + cur + idx;
|
||||||
});
|
});
|
||||||
auto p1 = QtPromise::resolve(inputs).reduce([&](int acc, int cur, int idx) {
|
auto p1 = QtPromise::resolve(inputs).reduce(
|
||||||
v1 << acc << cur << idx;
|
[&](int acc, int cur, int idx) {
|
||||||
if (cur == 6) {
|
v1 << acc << cur << idx;
|
||||||
throw QString{"bar"};
|
if (cur == 6) {
|
||||||
}
|
throw QString{"bar"};
|
||||||
return acc + cur + idx;
|
}
|
||||||
}, 2);
|
return acc + cur + idx;
|
||||||
|
},
|
||||||
|
2);
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||||
|
@ -92,8 +92,8 @@ void tst_qpromise_tap::fulfilledAsyncResolve()
|
|||||||
});
|
});
|
||||||
|
|
||||||
p.then([&](int r) {
|
p.then([&](int r) {
|
||||||
values << r;
|
values << r;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
QCOMPARE(values, (QVector<int>{2, 3, 1}));
|
QCOMPARE(values, (QVector<int>{2, 3, 1}));
|
||||||
@ -115,8 +115,8 @@ void tst_qpromise_tap::fulfilledAsyncReject()
|
|||||||
});
|
});
|
||||||
|
|
||||||
p.then([&](int r) {
|
p.then([&](int r) {
|
||||||
values << r;
|
values << r;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
|
@ -58,16 +58,14 @@ void tst_qpromise_tapfail::rejected()
|
|||||||
{
|
{
|
||||||
QStringList errors;
|
QStringList errors;
|
||||||
|
|
||||||
auto p0 = QPromise<int>::reject(QString{"foo"})
|
auto p0 = QPromise<int>::reject(QString{"foo"}).tapFail([&](const QString& err) {
|
||||||
.tapFail([&](const QString& err) {
|
errors << "1:" + err;
|
||||||
errors << "1:" + err;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
auto p1 = p0
|
auto p1 = p0.fail([&](const QString& err) {
|
||||||
.fail([&](const QString& err) {
|
errors << "2:" + err;
|
||||||
errors << "2:" + err;
|
return 43;
|
||||||
return 43;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
QCOMPARE(waitForError(p0, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p0, QString{}), QString{"foo"});
|
||||||
QCOMPARE(waitForValue(p1, -1), 43);
|
QCOMPARE(waitForValue(p1, -1), 43);
|
||||||
@ -80,15 +78,13 @@ void tst_qpromise_tapfail::rejected_void()
|
|||||||
{
|
{
|
||||||
QStringList errors;
|
QStringList errors;
|
||||||
|
|
||||||
auto p0 = QPromise<void>::reject(QString{"foo"})
|
auto p0 = QPromise<void>::reject(QString{"foo"}).tapFail([&](const QString& err) {
|
||||||
.tapFail([&](const QString& err) {
|
errors << "1:" + err;
|
||||||
errors << "1:" + err;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
auto p1 = p0
|
auto p1 = p0.fail([&](const QString& err) {
|
||||||
.fail([&](const QString& err) {
|
errors << "2:" + err;
|
||||||
errors << "2:" + err;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
QCOMPARE(waitForError(p0, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p0, QString{}), QString{"foo"});
|
||||||
QCOMPARE(waitForValue(p1, -1, 43), 43);
|
QCOMPARE(waitForValue(p1, -1, 43), 43);
|
||||||
@ -99,10 +95,9 @@ void tst_qpromise_tapfail::rejected_void()
|
|||||||
|
|
||||||
void tst_qpromise_tapfail::throws()
|
void tst_qpromise_tapfail::throws()
|
||||||
{
|
{
|
||||||
auto p = QPromise<int>::reject(QString{"foo"})
|
auto p = QPromise<int>::reject(QString{"foo"}).tapFail([&]() {
|
||||||
.tapFail([&]() {
|
throw QString{"bar"};
|
||||||
throw QString{"bar"};
|
});
|
||||||
});
|
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"bar"});
|
QCOMPARE(waitForError(p, QString{}), QString{"bar"});
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
@ -110,10 +105,9 @@ void tst_qpromise_tapfail::throws()
|
|||||||
|
|
||||||
void tst_qpromise_tapfail::throws_void()
|
void tst_qpromise_tapfail::throws_void()
|
||||||
{
|
{
|
||||||
auto p = QPromise<void>::reject(QString{"foo"})
|
auto p = QPromise<void>::reject(QString{"foo"}).tapFail([&]() {
|
||||||
.tapFail([&]() {
|
throw QString{"bar"};
|
||||||
throw QString{"bar"};
|
});
|
||||||
});
|
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"bar"});
|
QCOMPARE(waitForError(p, QString{}), QString{"bar"});
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
@ -122,18 +116,17 @@ void tst_qpromise_tapfail::throws_void()
|
|||||||
void tst_qpromise_tapfail::delayedResolved()
|
void tst_qpromise_tapfail::delayedResolved()
|
||||||
{
|
{
|
||||||
QVector<int> values;
|
QVector<int> values;
|
||||||
auto p = QPromise<int>::reject(QString{"foo"})
|
auto p = QPromise<int>::reject(QString{"foo"}).tapFail([&]() {
|
||||||
.tapFail([&]() {
|
QPromise<void> p{[&](const QPromiseResolve<void>& resolve) {
|
||||||
QPromise<void> p{[&](const QPromiseResolve<void>& resolve) {
|
QtPromisePrivate::qtpromise_defer([=, &values]() {
|
||||||
QtPromisePrivate::qtpromise_defer([=, &values]() {
|
values << 3;
|
||||||
values << 3;
|
resolve(); // ignored!
|
||||||
resolve(); // ignored!
|
});
|
||||||
});
|
}};
|
||||||
}};
|
|
||||||
|
|
||||||
values << 2;
|
values << 2;
|
||||||
return p;
|
return p;
|
||||||
});
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
||||||
QCOMPARE(values, (QVector<int>{2, 3}));
|
QCOMPARE(values, (QVector<int>{2, 3}));
|
||||||
@ -142,20 +135,17 @@ void tst_qpromise_tapfail::delayedResolved()
|
|||||||
void tst_qpromise_tapfail::delayedRejected()
|
void tst_qpromise_tapfail::delayedRejected()
|
||||||
{
|
{
|
||||||
QVector<int> values;
|
QVector<int> values;
|
||||||
auto p = QPromise<int>::reject(QString{"foo"})
|
auto p = QPromise<int>::reject(QString{"foo"}).tapFail([&]() {
|
||||||
.tapFail([&]() {
|
QPromise<void> p{[&](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||||
QPromise<void> p{[&](
|
QtPromisePrivate::qtpromise_defer([=, &values]() {
|
||||||
const QPromiseResolve<void>&,
|
values << 3;
|
||||||
const QPromiseReject<void>& reject){
|
reject(QString{"bar"});
|
||||||
QtPromisePrivate::qtpromise_defer([=, &values]() {
|
});
|
||||||
values << 3;
|
}};
|
||||||
reject(QString{"bar"});
|
|
||||||
});
|
|
||||||
}};
|
|
||||||
|
|
||||||
values << 2;
|
values << 2;
|
||||||
return p;
|
return p;
|
||||||
});
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"bar"});
|
QCOMPARE(waitForError(p, QString{}), QString{"bar"});
|
||||||
QCOMPARE(values, (QVector<int>{2, 3}));
|
QCOMPARE(values, (QVector<int>{2, 3}));
|
||||||
|
@ -39,18 +39,28 @@ namespace {
|
|||||||
const float kRes = 0.42f;
|
const float kRes = 0.42f;
|
||||||
const float kFail = -1.f;
|
const float kFail = -1.f;
|
||||||
|
|
||||||
float fnNoArg() { return kRes; }
|
float fnNoArg()
|
||||||
float fnArgByVal(float v) { return v; }
|
{
|
||||||
float fnArgByRef(const float& v) { return v; }
|
return kRes;
|
||||||
|
}
|
||||||
|
float fnArgByVal(float v)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
float fnArgByRef(const float& v)
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
class Klass {
|
class Klass
|
||||||
|
{
|
||||||
public: // STATICS
|
public: // STATICS
|
||||||
static float kFnNoArg() { return kRes; }
|
static float kFnNoArg() { return kRes; }
|
||||||
static float kFnArgByVal(float v) { return v; }
|
static float kFnArgByVal(float v) { return v; }
|
||||||
static float kFnArgByRef(const float& v) { return v; }
|
static float kFnArgByRef(const float& v) { return v; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Klass(float v) : m_v{v} {}
|
Klass(float v) : m_v{v} { }
|
||||||
|
|
||||||
float fnNoArg() const { return m_v; }
|
float fnNoArg() const { return m_v; }
|
||||||
float fnArgByVal(float v) const { return v + m_v; }
|
float fnArgByVal(float v) const { return v + m_v; }
|
||||||
@ -69,14 +79,17 @@ void tst_qpromise_then::resolveSync()
|
|||||||
auto input = QPromise<int>::resolve(42);
|
auto input = QPromise<int>::resolve(42);
|
||||||
auto output = input.then([&](int res) {
|
auto output = input.then([&](int res) {
|
||||||
values << res;
|
values << res;
|
||||||
return QString::number(res+1);
|
return QString::number(res + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
output.then([&](const QString& res) {
|
output
|
||||||
values << res;
|
.then([&](const QString& res) {
|
||||||
}).then([&]() {
|
values << res;
|
||||||
values << 44;
|
})
|
||||||
}).wait();
|
.then([&]() {
|
||||||
|
values << 44;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(values, (QVariantList{42, QString{"43"}, 44}));
|
QCOMPARE(values, (QVariantList{42, QString{"43"}, 44}));
|
||||||
QCOMPARE(input.isFulfilled(), true);
|
QCOMPARE(input.isFulfilled(), true);
|
||||||
@ -107,11 +120,14 @@ void tst_qpromise_then::rejectSync()
|
|||||||
});
|
});
|
||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
output.then([&](int res) {
|
output
|
||||||
error += "bar" + QString::number(res);
|
.then([&](int res) {
|
||||||
}).fail([&](const QString& err) {
|
error += "bar" + QString::number(res);
|
||||||
error += err;
|
})
|
||||||
}).wait();
|
.fail([&](const QString& err) {
|
||||||
|
error += err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(error, QString{"foo42"});
|
QCOMPARE(error, QString{"foo42"});
|
||||||
QCOMPARE(input.isFulfilled(), true);
|
QCOMPARE(input.isFulfilled(), true);
|
||||||
@ -121,11 +137,12 @@ void tst_qpromise_then::rejectSync()
|
|||||||
void tst_qpromise_then::rejectAsync()
|
void tst_qpromise_then::rejectAsync()
|
||||||
{
|
{
|
||||||
auto p = QPromise<int>::resolve(42).then([](int res) {
|
auto p = QPromise<int>::resolve(42).then([](int res) {
|
||||||
return QPromise<void>{[=](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
return QPromise<void>{
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
[=](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||||
reject(QString{"foo%1"}.arg(res));
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
});
|
reject(QString{"foo%1"}.arg(res));
|
||||||
}};
|
});
|
||||||
|
}};
|
||||||
});
|
});
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||||
@ -139,8 +156,8 @@ void tst_qpromise_then::skipResult()
|
|||||||
|
|
||||||
int value = -1;
|
int value = -1;
|
||||||
p.then([&]() {
|
p.then([&]() {
|
||||||
value = 43;
|
value = 43;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||||
QCOMPARE(value, 43);
|
QCOMPARE(value, 43);
|
||||||
@ -148,13 +165,13 @@ void tst_qpromise_then::skipResult()
|
|||||||
|
|
||||||
void tst_qpromise_then::nullHandler()
|
void tst_qpromise_then::nullHandler()
|
||||||
{
|
{
|
||||||
{ // resolved
|
{ // resolved
|
||||||
auto p = QPromise<int>::resolve(42).then(nullptr);
|
auto p = QPromise<int>::resolve(42).then(nullptr);
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p, -1), 42);
|
QCOMPARE(waitForValue(p, -1), 42);
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
}
|
}
|
||||||
{ // rejected
|
{ // rejected
|
||||||
auto p = QPromise<int>::reject(QString{"foo"}).then(nullptr);
|
auto p = QPromise<int>::reject(QString{"foo"}).then(nullptr);
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
||||||
@ -164,7 +181,7 @@ void tst_qpromise_then::nullHandler()
|
|||||||
|
|
||||||
void tst_qpromise_then::functionPtrHandlers()
|
void tst_qpromise_then::functionPtrHandlers()
|
||||||
{
|
{
|
||||||
{ // Global functions.
|
{ // Global functions.
|
||||||
auto p0 = QtPromise::resolve().then(&fnNoArg);
|
auto p0 = QtPromise::resolve().then(&fnNoArg);
|
||||||
auto p1 = QtPromise::resolve(kRes).then(&fnArgByVal);
|
auto p1 = QtPromise::resolve(kRes).then(&fnArgByVal);
|
||||||
auto p2 = QtPromise::resolve(kRes).then(&fnArgByRef);
|
auto p2 = QtPromise::resolve(kRes).then(&fnArgByRef);
|
||||||
@ -173,7 +190,7 @@ void tst_qpromise_then::functionPtrHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // Static member functions.
|
{ // Static member functions.
|
||||||
auto p0 = QtPromise::resolve().then(&Klass::kFnNoArg);
|
auto p0 = QtPromise::resolve().then(&Klass::kFnNoArg);
|
||||||
auto p1 = QtPromise::resolve(kRes).then(&Klass::kFnArgByVal);
|
auto p1 = QtPromise::resolve(kRes).then(&Klass::kFnArgByVal);
|
||||||
auto p2 = QtPromise::resolve(kRes).then(&Klass::kFnArgByRef);
|
auto p2 = QtPromise::resolve(kRes).then(&Klass::kFnArgByRef);
|
||||||
@ -187,7 +204,7 @@ void tst_qpromise_then::functionPtrHandlers()
|
|||||||
// https://github.com/simonbrunel/qtpromise/issues/29
|
// https://github.com/simonbrunel/qtpromise/issues/29
|
||||||
void tst_qpromise_then::stdFunctionHandlers()
|
void tst_qpromise_then::stdFunctionHandlers()
|
||||||
{
|
{
|
||||||
{ // lvalue.
|
{ // lvalue.
|
||||||
std::function<float()> stdFnNoArg = fnNoArg;
|
std::function<float()> stdFnNoArg = fnNoArg;
|
||||||
std::function<float(float)> stdFnArgByVal = fnArgByVal;
|
std::function<float(float)> stdFnArgByVal = fnArgByVal;
|
||||||
std::function<float(const float&)> stdFnArgByRef = fnArgByRef;
|
std::function<float(const float&)> stdFnArgByRef = fnArgByRef;
|
||||||
@ -200,7 +217,7 @@ void tst_qpromise_then::stdFunctionHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // const lvalue.
|
{ // const lvalue.
|
||||||
const std::function<float()> stdFnNoArg = fnNoArg;
|
const std::function<float()> stdFnNoArg = fnNoArg;
|
||||||
const std::function<float(float)> stdFnArgByVal = fnArgByVal;
|
const std::function<float(float)> stdFnArgByVal = fnArgByVal;
|
||||||
const std::function<float(const float&)> stdFnArgByRef = fnArgByRef;
|
const std::function<float(const float&)> stdFnArgByRef = fnArgByRef;
|
||||||
@ -213,7 +230,7 @@ void tst_qpromise_then::stdFunctionHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // rvalue.
|
{ // rvalue.
|
||||||
auto p0 = QtPromise::resolve().then(std::function<float()>{fnNoArg});
|
auto p0 = QtPromise::resolve().then(std::function<float()>{fnNoArg});
|
||||||
auto p1 = QtPromise::resolve(kRes).then(std::function<float(float)>{fnArgByVal});
|
auto p1 = QtPromise::resolve(kRes).then(std::function<float(float)>{fnArgByVal});
|
||||||
auto p2 = QtPromise::resolve(kRes).then(std::function<float(const float&)>{fnArgByRef});
|
auto p2 = QtPromise::resolve(kRes).then(std::function<float(const float&)>{fnArgByRef});
|
||||||
@ -247,10 +264,16 @@ void tst_qpromise_then::stdBindHandlers()
|
|||||||
|
|
||||||
void tst_qpromise_then::lambdaHandlers()
|
void tst_qpromise_then::lambdaHandlers()
|
||||||
{
|
{
|
||||||
{ // lvalue.
|
{ // lvalue.
|
||||||
auto lambdaNoArg = []() { return kRes; };
|
auto lambdaNoArg = []() {
|
||||||
auto lambdaArgByVal = [](float v) { return v; };
|
return kRes;
|
||||||
auto lambdaArgByRef = [](const float& v) { return v; };
|
};
|
||||||
|
auto lambdaArgByVal = [](float v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
auto lambdaArgByRef = [](const float& v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
auto p0 = QtPromise::resolve().then(lambdaNoArg);
|
auto p0 = QtPromise::resolve().then(lambdaNoArg);
|
||||||
auto p1 = QtPromise::resolve(kRes).then(lambdaArgByVal);
|
auto p1 = QtPromise::resolve(kRes).then(lambdaArgByVal);
|
||||||
@ -260,10 +283,16 @@ void tst_qpromise_then::lambdaHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // const lvalue.
|
{ // const lvalue.
|
||||||
const auto lambdaNoArg = []() { return kRes; };
|
const auto lambdaNoArg = []() {
|
||||||
const auto lambdaArgByVal = [](float v) { return v; };
|
return kRes;
|
||||||
const auto lambdaArgByRef = [](const float& v) { return v; };
|
};
|
||||||
|
const auto lambdaArgByVal = [](float v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
const auto lambdaArgByRef = [](const float& v) {
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
auto p0 = QtPromise::resolve().then(lambdaNoArg);
|
auto p0 = QtPromise::resolve().then(lambdaNoArg);
|
||||||
auto p1 = QtPromise::resolve(kRes).then(lambdaArgByVal);
|
auto p1 = QtPromise::resolve(kRes).then(lambdaArgByVal);
|
||||||
@ -273,10 +302,16 @@ void tst_qpromise_then::lambdaHandlers()
|
|||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p2, kFail), kRes);
|
QCOMPARE(waitForValue(p2, kFail), kRes);
|
||||||
}
|
}
|
||||||
{ // rvalue.
|
{ // rvalue.
|
||||||
auto p0 = QtPromise::resolve().then([]() { return kRes; });
|
auto p0 = QtPromise::resolve().then([]() {
|
||||||
auto p1 = QtPromise::resolve(kRes).then([](float v) { return v; });
|
return kRes;
|
||||||
auto p2 = QtPromise::resolve(kRes).then([](const float& v) { return v; });
|
});
|
||||||
|
auto p1 = QtPromise::resolve(kRes).then([](float v) {
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
auto p2 = QtPromise::resolve(kRes).then([](const float& v) {
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p0, kFail), kRes);
|
QCOMPARE(waitForValue(p0, kFail), kRes);
|
||||||
QCOMPARE(waitForValue(p1, kFail), kRes);
|
QCOMPARE(waitForValue(p1, kFail), kRes);
|
||||||
|
@ -39,12 +39,13 @@ void tst_qpromise_timeout::fulfilled()
|
|||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QTimer::singleShot(1000, [=]() {
|
QTimer::singleShot(1000, [=]() {
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
}}.timeout(2000).finally([&]() {
|
}}.timeout(2000)
|
||||||
elapsed = timer.elapsed();
|
.finally([&]() {
|
||||||
});
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p, -1), 42);
|
QCOMPARE(waitForValue(p, -1), 42);
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
@ -59,13 +60,13 @@ void tst_qpromise_timeout::rejected()
|
|||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
auto p = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
auto p = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
QTimer::singleShot(1000, [=]() {
|
QTimer::singleShot(1000, [=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}}.timeout(2000).finally([&]() {
|
}}.timeout(2000)
|
||||||
elapsed = timer.elapsed();
|
.finally([&]() {
|
||||||
});
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
@ -81,17 +82,18 @@ void tst_qpromise_timeout::timeout()
|
|||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QTimer::singleShot(4000, [=]() {
|
QTimer::singleShot(4000, [=]() {
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
}}.timeout(2000).finally([&]() {
|
}}.timeout(2000)
|
||||||
elapsed = timer.elapsed();
|
.finally([&]() {
|
||||||
});
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
p.fail([&](const QPromiseTimeoutException&) {
|
p.fail([&](const QPromiseTimeoutException&) {
|
||||||
failed = true;
|
failed = true;
|
||||||
return -1;
|
return -1;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p, -1), -1);
|
QCOMPARE(waitForValue(p, -1), -1);
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
@ -112,12 +114,13 @@ void tst_qpromise_timeout::fulfilledStdChrono()
|
|||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QTimer::singleShot(1000, [=]() {
|
QTimer::singleShot(1000, [=]() {
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
}}.timeout(std::chrono::seconds{2}).finally([&]() {
|
}}.timeout(std::chrono::seconds{2})
|
||||||
elapsed = timer.elapsed();
|
.finally([&]() {
|
||||||
});
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p, -1), 42);
|
QCOMPARE(waitForValue(p, -1), 42);
|
||||||
QCOMPARE(p.isFulfilled(), true);
|
QCOMPARE(p.isFulfilled(), true);
|
||||||
@ -132,13 +135,13 @@ void tst_qpromise_timeout::rejectedStdChrono()
|
|||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
auto p = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
auto p = QPromise<int>{[](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
QTimer::singleShot(1000, [=]() {
|
QTimer::singleShot(1000, [=]() {
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}}.timeout(std::chrono::seconds{2}).finally([&]() {
|
}}.timeout(std::chrono::seconds{2})
|
||||||
elapsed = timer.elapsed();
|
.finally([&]() {
|
||||||
});
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
QCOMPARE(waitForError(p, QString{}), QString{"foo"});
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
@ -154,17 +157,18 @@ void tst_qpromise_timeout::timeoutStdChrono()
|
|||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
auto p = QPromise<int>{[](const QPromiseResolve<int>& resolve) {
|
||||||
QTimer::singleShot(4000, [=]() {
|
QTimer::singleShot(4000, [=]() {
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
}}.timeout(std::chrono::seconds{2}).finally([&]() {
|
}}.timeout(std::chrono::seconds{2})
|
||||||
elapsed = timer.elapsed();
|
.finally([&]() {
|
||||||
});
|
elapsed = timer.elapsed();
|
||||||
|
});
|
||||||
|
|
||||||
p.fail([&](const QPromiseTimeoutException&) {
|
p.fail([&](const QPromiseTimeoutException&) {
|
||||||
failed = true;
|
failed = true;
|
||||||
return -1;
|
return -1;
|
||||||
}).wait();
|
}).wait();
|
||||||
|
|
||||||
QCOMPARE(waitForValue(p, -1), -1);
|
QCOMPARE(waitForValue(p, -1), -1);
|
||||||
QCOMPARE(p.isRejected(), true);
|
QCOMPARE(p.isRejected(), true);
|
||||||
|
@ -18,18 +18,18 @@ class tst_requirements : public QObject
|
|||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
|
||||||
// 2.1. Promise States
|
// 2.1. Promise States
|
||||||
void statePending(); // 2.1.1.
|
void statePending(); // 2.1.1.
|
||||||
void stateFulfilled(); // 2.1.2.
|
void stateFulfilled(); // 2.1.2.
|
||||||
void stateRejected(); // 2.1.3.
|
void stateRejected(); // 2.1.3.
|
||||||
|
|
||||||
// 2.2. The then Method
|
// 2.2. The then Method
|
||||||
void thenArguments(); // 2.2.1.
|
void thenArguments(); // 2.2.1.
|
||||||
void thenOnFulfilled(); // 2.2.2.
|
void thenOnFulfilled(); // 2.2.2.
|
||||||
void thenOnRejected(); // 2.2.3.
|
void thenOnRejected(); // 2.2.3.
|
||||||
void thenAsynchronous(); // 2.2.4.
|
void thenAsynchronous(); // 2.2.4.
|
||||||
// 2.2.5. NOT APPLICABLE
|
// 2.2.5. NOT APPLICABLE
|
||||||
void thenMultipleCalls(); // 2.2.6.
|
void thenMultipleCalls(); // 2.2.6.
|
||||||
void thenHandlers(); // 2.2.7.
|
void thenHandlers(); // 2.2.7.
|
||||||
|
|
||||||
// 2.3. The Promise Resolution Procedure
|
// 2.3. The Promise Resolution Procedure
|
||||||
|
|
||||||
@ -44,7 +44,9 @@ void tst_requirements::statePending()
|
|||||||
// 2.1.1.1. may transition to either the fulfilled state
|
// 2.1.1.1. may transition to either the fulfilled state
|
||||||
{
|
{
|
||||||
QPromise<int> p{[&](const QPromiseResolve<int>& resolve) {
|
QPromise<int> p{[&](const QPromiseResolve<int>& resolve) {
|
||||||
QtPromisePrivate::qtpromise_defer([=]() { resolve(42); });
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
|
resolve(42);
|
||||||
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
QVERIFY(p.isPending());
|
QVERIFY(p.isPending());
|
||||||
@ -59,9 +61,11 @@ void tst_requirements::statePending()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2.1.1.1. ... or the rejected state
|
// 2.1.1.1. ... or the rejected state
|
||||||
{
|
{
|
||||||
QPromise<int> p{[&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
QPromise<int> p{[&](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||||
QtPromisePrivate::qtpromise_defer([=]() { reject(QString{"foo"}); });
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
|
reject(QString{"foo"});
|
||||||
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
QVERIFY(p.isPending());
|
QVERIFY(p.isPending());
|
||||||
@ -82,9 +86,7 @@ void tst_requirements::stateFulfilled()
|
|||||||
int value = -1;
|
int value = -1;
|
||||||
|
|
||||||
// 2.1.2. When fulfilled, a promise:
|
// 2.1.2. When fulfilled, a promise:
|
||||||
QPromise<int> p{[](
|
QPromise<int> p{[](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||||
const QPromiseResolve<int>& resolve,
|
|
||||||
const QPromiseReject<int>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
// 2.1.2.2. must have a value, which must not change.
|
// 2.1.2.2. must have a value, which must not change.
|
||||||
resolve(42);
|
resolve(42);
|
||||||
@ -97,11 +99,14 @@ void tst_requirements::stateFulfilled()
|
|||||||
|
|
||||||
QVERIFY(p.isPending());
|
QVERIFY(p.isPending());
|
||||||
|
|
||||||
p.then([&](int res) {
|
p.then(
|
||||||
value = res;
|
[&](int res) {
|
||||||
}, [&](const QString& err) {
|
value = res;
|
||||||
error = err;
|
},
|
||||||
}).wait();
|
[&](const QString& err) {
|
||||||
|
error = err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(p.isFulfilled());
|
QVERIFY(p.isFulfilled());
|
||||||
QVERIFY(!p.isRejected());
|
QVERIFY(!p.isRejected());
|
||||||
@ -115,9 +120,7 @@ void tst_requirements::stateRejected()
|
|||||||
int value = -1;
|
int value = -1;
|
||||||
|
|
||||||
// 2.1.3 When rejected, a promise:
|
// 2.1.3 When rejected, a promise:
|
||||||
QPromise<int> p{[](
|
QPromise<int> p{[](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||||
const QPromiseResolve<int>& resolve,
|
|
||||||
const QPromiseReject<int>& reject) {
|
|
||||||
QtPromisePrivate::qtpromise_defer([=]() {
|
QtPromisePrivate::qtpromise_defer([=]() {
|
||||||
// 2.1.3.2. must have a reason, which must not change.
|
// 2.1.3.2. must have a reason, which must not change.
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
@ -130,11 +133,14 @@ void tst_requirements::stateRejected()
|
|||||||
|
|
||||||
QVERIFY(p.isPending());
|
QVERIFY(p.isPending());
|
||||||
|
|
||||||
p.then([&](int res) {
|
p.then(
|
||||||
value = res;
|
[&](int res) {
|
||||||
}, [&](const QString& err) {
|
value = res;
|
||||||
error = err;
|
},
|
||||||
}).wait();
|
[&](const QString& err) {
|
||||||
|
error = err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(!p.isFulfilled());
|
QVERIFY(!p.isFulfilled());
|
||||||
QVERIFY(p.isRejected());
|
QVERIFY(p.isRejected());
|
||||||
@ -148,10 +154,15 @@ void tst_requirements::thenArguments()
|
|||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QPromise<int>::resolve(42).then(
|
QPromise<int>::resolve(42)
|
||||||
[&](int res) { value = res; },
|
.then(
|
||||||
[&](const QString& err) { error = err; }
|
[&](int res) {
|
||||||
).wait();
|
value = res;
|
||||||
|
},
|
||||||
|
[&](const QString& err) {
|
||||||
|
error = err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(error.isEmpty());
|
QVERIFY(error.isEmpty());
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
@ -159,10 +170,15 @@ void tst_requirements::thenArguments()
|
|||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QPromise<int>::reject(QString{"foo"}).then(
|
QPromise<int>::reject(QString{"foo"})
|
||||||
[&](int res) { value = res; },
|
.then(
|
||||||
[&](const QString& err){ error = err; }
|
[&](int res) {
|
||||||
).wait();
|
value = res;
|
||||||
|
},
|
||||||
|
[&](const QString& err) {
|
||||||
|
error = err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(error, QString{"foo"});
|
QCOMPARE(error, QString{"foo"});
|
||||||
QCOMPARE(value, -1);
|
QCOMPARE(value, -1);
|
||||||
@ -171,10 +187,13 @@ void tst_requirements::thenArguments()
|
|||||||
// 2.2.1. onFulfilled is an optional arguments:
|
// 2.2.1. onFulfilled is an optional arguments:
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
QPromise<int>::reject(QString{"foo"}).then(
|
QPromise<int>::reject(QString{"foo"})
|
||||||
nullptr,
|
.then(nullptr,
|
||||||
[&](const QString& err){ error = err; return 42; }
|
[&](const QString& err) {
|
||||||
).wait();
|
error = err;
|
||||||
|
return 42;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(error, QString{"foo"});
|
QCOMPARE(error, QString{"foo"});
|
||||||
}
|
}
|
||||||
@ -182,9 +201,11 @@ void tst_requirements::thenArguments()
|
|||||||
// 2.2.1. onRejected is an optional arguments:
|
// 2.2.1. onRejected is an optional arguments:
|
||||||
{
|
{
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QPromise<int>::resolve(42).then(
|
QPromise<int>::resolve(42)
|
||||||
[&value](int res) { value = res; }
|
.then([&value](int res) {
|
||||||
).wait();
|
value = res;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(value, 42);
|
QCOMPARE(value, 42);
|
||||||
}
|
}
|
||||||
@ -206,7 +227,9 @@ void tst_requirements::thenOnFulfilled()
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
auto p1 = p0.then([&](int res) { values << res; });
|
auto p1 = p0.then([&](int res) {
|
||||||
|
values << res;
|
||||||
|
});
|
||||||
|
|
||||||
// 2.2.2.2. it must not be called before promise is fulfilled.
|
// 2.2.2.2. it must not be called before promise is fulfilled.
|
||||||
QVERIFY(p0.isPending());
|
QVERIFY(p0.isPending());
|
||||||
@ -234,7 +257,9 @@ void tst_requirements::thenOnRejected()
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
auto p1 = p0.then(nullptr, [&](const QString& err) { errors << err; });
|
auto p1 = p0.then(nullptr, [&](const QString& err) {
|
||||||
|
errors << err;
|
||||||
|
});
|
||||||
|
|
||||||
// 2.2.3.2. it must not be called before promise is rejected.
|
// 2.2.3.2. it must not be called before promise is rejected.
|
||||||
QVERIFY(p0.isPending());
|
QVERIFY(p0.isPending());
|
||||||
@ -260,7 +285,9 @@ void tst_requirements::thenAsynchronous()
|
|||||||
auto p0 = QPromise<int>::resolve(42);
|
auto p0 = QPromise<int>::resolve(42);
|
||||||
QVERIFY(p0.isFulfilled());
|
QVERIFY(p0.isFulfilled());
|
||||||
|
|
||||||
auto p1 = p0.then([&](int res){ value = res; });
|
auto p1 = p0.then([&](int res) {
|
||||||
|
value = res;
|
||||||
|
});
|
||||||
QVERIFY(p1.isPending());
|
QVERIFY(p1.isPending());
|
||||||
QCOMPARE(value, -1);
|
QCOMPARE(value, -1);
|
||||||
|
|
||||||
@ -283,11 +310,16 @@ void tst_requirements::thenMultipleCalls()
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
QtPromise::all(QVector<QPromise<void>>{
|
QtPromise::all(QVector<QPromise<void>>{p.then([&](int r) {
|
||||||
p.then([&](int r) { values << r + 1; }),
|
values << r + 1;
|
||||||
p.then([&](int r) { values << r + 2; }),
|
}),
|
||||||
p.then([&](int r) { values << r + 3; })
|
p.then([&](int r) {
|
||||||
}).wait();
|
values << r + 2;
|
||||||
|
}),
|
||||||
|
p.then([&](int r) {
|
||||||
|
values << r + 3;
|
||||||
|
})})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(values, (QVector<int>{43, 44, 45}));
|
QCOMPARE(values, (QVector<int>{43, 44, 45}));
|
||||||
}
|
}
|
||||||
@ -302,11 +334,22 @@ void tst_requirements::thenMultipleCalls()
|
|||||||
});
|
});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
QtPromise::all(QVector<QPromise<int>>{
|
QtPromise::all(QVector<QPromise<int>>{p.then(nullptr,
|
||||||
p.then(nullptr, [&](int r) { values << r + 1; return r + 1; }),
|
[&](int r) {
|
||||||
p.then(nullptr, [&](int r) { values << r + 2; return r + 2; }),
|
values << r + 1;
|
||||||
p.then(nullptr, [&](int r) { values << r + 3; return r + 3; })
|
return r + 1;
|
||||||
}).wait();
|
}),
|
||||||
|
p.then(nullptr,
|
||||||
|
[&](int r) {
|
||||||
|
values << r + 2;
|
||||||
|
return r + 2;
|
||||||
|
}),
|
||||||
|
p.then(nullptr,
|
||||||
|
[&](int r) {
|
||||||
|
values << r + 3;
|
||||||
|
return r + 3;
|
||||||
|
})})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QCOMPARE(values, (QVector<int>{9, 10, 11}));
|
QCOMPARE(values, (QVector<int>{9, 10, 11}));
|
||||||
}
|
}
|
||||||
@ -316,7 +359,9 @@ void tst_requirements::thenHandlers()
|
|||||||
{
|
{
|
||||||
// 2.2.7. then must return a promise: p2 = p1.then(onFulfilled, onRejected);
|
// 2.2.7. then must return a promise: p2 = p1.then(onFulfilled, onRejected);
|
||||||
{
|
{
|
||||||
auto handler = [](){ return 42; };
|
auto handler = []() {
|
||||||
|
return 42;
|
||||||
|
};
|
||||||
auto p1 = QPromise<int>::resolve(42);
|
auto p1 = QPromise<int>::resolve(42);
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1.then(handler, nullptr)), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1.then(handler, nullptr)), QPromise<int>>::value));
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p1.then(nullptr, handler)), QPromise<int>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p1.then(nullptr, handler)), QPromise<int>>::value));
|
||||||
@ -331,8 +376,12 @@ void tst_requirements::thenHandlers()
|
|||||||
{
|
{
|
||||||
QString reason;
|
QString reason;
|
||||||
auto p1 = QPromise<int>::resolve(42);
|
auto p1 = QPromise<int>::resolve(42);
|
||||||
auto p2 = p1.then([](){ throw QString{"foo"}; });
|
auto p2 = p1.then([]() {
|
||||||
p2.then(nullptr, [&](const QString& e) { reason = e; }).wait();
|
throw QString{"foo"};
|
||||||
|
});
|
||||||
|
p2.then(nullptr, [&](const QString& e) {
|
||||||
|
reason = e;
|
||||||
|
}).wait();
|
||||||
|
|
||||||
QVERIFY(p1.isFulfilled());
|
QVERIFY(p1.isFulfilled());
|
||||||
QVERIFY(p2.isRejected());
|
QVERIFY(p2.isRejected());
|
||||||
@ -341,8 +390,14 @@ void tst_requirements::thenHandlers()
|
|||||||
{
|
{
|
||||||
QString reason;
|
QString reason;
|
||||||
auto p1 = QPromise<int>::reject(QString{"foo"});
|
auto p1 = QPromise<int>::reject(QString{"foo"});
|
||||||
auto p2 = p1.then(nullptr, [](){ throw QString{"bar"}; return 42; });
|
auto p2 = p1.then(nullptr, []() {
|
||||||
p2.then(nullptr, [&](const QString& e) { reason = e; return 0; }).wait();
|
throw QString{"bar"};
|
||||||
|
return 42;
|
||||||
|
});
|
||||||
|
p2.then(nullptr, [&](const QString& e) {
|
||||||
|
reason = e;
|
||||||
|
return 0;
|
||||||
|
}).wait();
|
||||||
|
|
||||||
QVERIFY(p1.isRejected());
|
QVERIFY(p1.isRejected());
|
||||||
QVERIFY(p2.isRejected());
|
QVERIFY(p2.isRejected());
|
||||||
@ -354,9 +409,13 @@ void tst_requirements::thenHandlers()
|
|||||||
{
|
{
|
||||||
QString value;
|
QString value;
|
||||||
auto p1 = QPromise<QString>::resolve("42");
|
auto p1 = QPromise<QString>::resolve("42");
|
||||||
auto p2 = p1.then(nullptr, [](){ return QString{}; });
|
auto p2 = p1.then(nullptr, []() {
|
||||||
|
return QString{};
|
||||||
|
});
|
||||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<QString>>::value));
|
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<QString>>::value));
|
||||||
p2.then([&](const QString& e) { value = e; }).wait();
|
p2.then([&](const QString& e) {
|
||||||
|
value = e;
|
||||||
|
}).wait();
|
||||||
|
|
||||||
QVERIFY(p1.isFulfilled());
|
QVERIFY(p1.isFulfilled());
|
||||||
QVERIFY(p2.isFulfilled());
|
QVERIFY(p2.isFulfilled());
|
||||||
|
@ -10,13 +10,15 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
struct Logs {
|
struct Logs
|
||||||
|
{
|
||||||
int ctor = 0;
|
int ctor = 0;
|
||||||
int copy = 0;
|
int copy = 0;
|
||||||
int move = 0;
|
int move = 0;
|
||||||
int refs = 0;
|
int refs = 0;
|
||||||
|
|
||||||
void reset() {
|
void reset()
|
||||||
|
{
|
||||||
ctor = 0;
|
ctor = 0;
|
||||||
copy = 0;
|
copy = 0;
|
||||||
move = 0;
|
move = 0;
|
||||||
@ -26,21 +28,45 @@ struct Logs {
|
|||||||
|
|
||||||
struct Logger
|
struct Logger
|
||||||
{
|
{
|
||||||
Logger() { logs().ctor++; logs().refs++; }
|
Logger()
|
||||||
Logger(const Logger&) { logs().copy++; logs().refs++; }
|
{
|
||||||
Logger(Logger&&) { logs().move++; logs().refs++; }
|
logs().ctor++;
|
||||||
|
logs().refs++;
|
||||||
|
}
|
||||||
|
Logger(const Logger&)
|
||||||
|
{
|
||||||
|
logs().copy++;
|
||||||
|
logs().refs++;
|
||||||
|
}
|
||||||
|
Logger(Logger&&)
|
||||||
|
{
|
||||||
|
logs().move++;
|
||||||
|
logs().refs++;
|
||||||
|
}
|
||||||
~Logger() { logs().refs--; }
|
~Logger() { logs().refs--; }
|
||||||
|
|
||||||
Logger& operator=(const Logger&) { logs().copy++; return *this; }
|
Logger& operator=(const Logger&)
|
||||||
Logger& operator=(Logger&&) { logs().move++; return *this; }
|
{
|
||||||
|
logs().copy++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Logger& operator=(Logger&&)
|
||||||
|
{
|
||||||
|
logs().move++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
public: // STATICS
|
public: // STATICS
|
||||||
static Logs& logs() { static Logs logs; return logs; }
|
static Logs& logs()
|
||||||
|
{
|
||||||
|
static Logs logs;
|
||||||
|
return logs;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Data : public Logger
|
struct Data : public Logger
|
||||||
{
|
{
|
||||||
Data(int v) : Logger{}, m_value{v} {}
|
Data(int v) : Logger{}, m_value{v} { }
|
||||||
int value() const { return m_value; }
|
int value() const { return m_value; }
|
||||||
|
|
||||||
// MSVC 2013 doesn't support implicit generation of the move constructor and
|
// MSVC 2013 doesn't support implicit generation of the move constructor and
|
||||||
@ -48,15 +74,9 @@ struct Data : public Logger
|
|||||||
// constructor and operator also need to be explicitly defined (error C2280).
|
// constructor and operator also need to be explicitly defined (error C2280).
|
||||||
// https://stackoverflow.com/a/26581337
|
// https://stackoverflow.com/a/26581337
|
||||||
|
|
||||||
Data(const Data& other)
|
Data(const Data& other) : Logger{other}, m_value{other.m_value} { }
|
||||||
: Logger{other}
|
|
||||||
, m_value{other.m_value}
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Data(Data&& other) : Logger{std::forward<Data>(other)}
|
Data(Data&& other) : Logger{std::forward<Data>(other)} { std::swap(m_value, other.m_value); }
|
||||||
{
|
|
||||||
std::swap(m_value, other.m_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Data& operator=(const Data& other)
|
Data& operator=(const Data& other)
|
||||||
{
|
{
|
||||||
|
@ -10,54 +10,65 @@
|
|||||||
|
|
||||||
#include <QtPromise>
|
#include <QtPromise>
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
static inline T waitForValue(const QtPromise::QPromise<T>& promise, const T& initial)
|
static inline T waitForValue(const QtPromise::QPromise<T>& promise, const T& initial)
|
||||||
{
|
{
|
||||||
T value(initial);
|
T value(initial);
|
||||||
promise.then([&](const T& res) {
|
promise
|
||||||
value = res;
|
.then([&](const T& res) {
|
||||||
}).wait();
|
value = res;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
static inline T waitForValue(const QtPromise::QPromise<void>& promise, const T& initial, const T& expected)
|
static inline T
|
||||||
|
waitForValue(const QtPromise::QPromise<void>& promise, const T& initial, const T& expected)
|
||||||
{
|
{
|
||||||
T value(initial);
|
T value(initial);
|
||||||
promise.then([&]() {
|
promise
|
||||||
value = expected;
|
.then([&]() {
|
||||||
}).wait();
|
value = expected;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename E>
|
template<typename T, typename E>
|
||||||
static inline E waitForError(const QtPromise::QPromise<T>& promise, const E& initial)
|
static inline E waitForError(const QtPromise::QPromise<T>& promise, const E& initial)
|
||||||
{
|
{
|
||||||
E error(initial);
|
E error(initial);
|
||||||
promise.fail([&](const E& err) {
|
promise
|
||||||
error = err;
|
.fail([&](const E& err) {
|
||||||
return T();
|
error = err;
|
||||||
}).wait();
|
return T();
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E>
|
template<typename E>
|
||||||
static inline E waitForError(const QtPromise::QPromise<void>& promise, const E& initial)
|
static inline E waitForError(const QtPromise::QPromise<void>& promise, const E& initial)
|
||||||
{
|
{
|
||||||
E error(initial);
|
E error(initial);
|
||||||
promise.fail([&](const E& err) {
|
promise
|
||||||
error = err;
|
.fail([&](const E& err) {
|
||||||
}).wait();
|
error = err;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename E, typename T>
|
template<typename E, typename T>
|
||||||
static inline bool waitForRejected(const T& promise)
|
static inline bool waitForRejected(const T& promise)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
promise.tapFail([&](const E&) {
|
promise
|
||||||
result = true;
|
.tapFail([&](const E&) {
|
||||||
}).wait();
|
result = true;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +40,12 @@ void tst_thread::resolve()
|
|||||||
source = QThread::currentThread();
|
source = QThread::currentThread();
|
||||||
resolve(42);
|
resolve(42);
|
||||||
});
|
});
|
||||||
}}.then([&](int res) {
|
}}
|
||||||
target = QThread::currentThread();
|
.then([&](int res) {
|
||||||
value = res;
|
target = QThread::currentThread();
|
||||||
}).wait();
|
value = res;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(source != nullptr);
|
QVERIFY(source != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
@ -62,10 +64,12 @@ void tst_thread::resolve_void()
|
|||||||
source = QThread::currentThread();
|
source = QThread::currentThread();
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}}.then([&]() {
|
}}
|
||||||
target = QThread::currentThread();
|
.then([&]() {
|
||||||
value = 43;
|
target = QThread::currentThread();
|
||||||
}).wait();
|
value = 43;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(source != nullptr);
|
QVERIFY(source != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
@ -84,11 +88,13 @@ void tst_thread::reject()
|
|||||||
source = QThread::currentThread();
|
source = QThread::currentThread();
|
||||||
reject(QString{"foo"});
|
reject(QString{"foo"});
|
||||||
});
|
});
|
||||||
}}.fail([&](const QString& err) {
|
}}
|
||||||
target = QThread::currentThread();
|
.fail([&](const QString& err) {
|
||||||
error = err;
|
target = QThread::currentThread();
|
||||||
return -1;
|
error = err;
|
||||||
}).wait();
|
return -1;
|
||||||
|
})
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(source != nullptr);
|
QVERIFY(source != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
@ -106,12 +112,15 @@ void tst_thread::then()
|
|||||||
|
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QThread* target = nullptr;
|
QThread* target = nullptr;
|
||||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<int>& p) {
|
QtPromise::resolve(QtConcurrent::run(
|
||||||
p.then([&](int res) {
|
[&](const QPromise<int>& p) {
|
||||||
target = QThread::currentThread();
|
p.then([&](int res) {
|
||||||
value = res;
|
target = QThread::currentThread();
|
||||||
}).wait();
|
value = res;
|
||||||
}, p)).wait();
|
}).wait();
|
||||||
|
},
|
||||||
|
p))
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(target != nullptr);
|
QVERIFY(target != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
@ -129,12 +138,15 @@ void tst_thread::then_void()
|
|||||||
|
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QThread* target = nullptr;
|
QThread* target = nullptr;
|
||||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<void>& p) {
|
QtPromise::resolve(QtConcurrent::run(
|
||||||
p.then([&]() {
|
[&](const QPromise<void>& p) {
|
||||||
target = QThread::currentThread();
|
p.then([&]() {
|
||||||
value = 43;
|
target = QThread::currentThread();
|
||||||
}).wait();
|
value = 43;
|
||||||
}, p)).wait();
|
}).wait();
|
||||||
|
},
|
||||||
|
p))
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(target != nullptr);
|
QVERIFY(target != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
@ -152,13 +164,16 @@ void tst_thread::fail()
|
|||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
QThread* target = nullptr;
|
QThread* target = nullptr;
|
||||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<int>& p) {
|
QtPromise::resolve(QtConcurrent::run(
|
||||||
p.fail([&](const QString& err) {
|
[&](const QPromise<int>& p) {
|
||||||
target = QThread::currentThread();
|
p.fail([&](const QString& err) {
|
||||||
error = err;
|
target = QThread::currentThread();
|
||||||
return -1;
|
error = err;
|
||||||
}).wait();
|
return -1;
|
||||||
}, p)).wait();
|
}).wait();
|
||||||
|
},
|
||||||
|
p))
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(target != nullptr);
|
QVERIFY(target != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
@ -176,12 +191,15 @@ void tst_thread::finally()
|
|||||||
|
|
||||||
int value = -1;
|
int value = -1;
|
||||||
QThread* target = nullptr;
|
QThread* target = nullptr;
|
||||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<int>& p) {
|
QtPromise::resolve(QtConcurrent::run(
|
||||||
p.finally([&]() {
|
[&](const QPromise<int>& p) {
|
||||||
target = QThread::currentThread();
|
p.finally([&]() {
|
||||||
value = 43;
|
target = QThread::currentThread();
|
||||||
}).wait();
|
value = 43;
|
||||||
}, p)).wait();
|
}).wait();
|
||||||
|
},
|
||||||
|
p))
|
||||||
|
.wait();
|
||||||
|
|
||||||
QVERIFY(target != nullptr);
|
QVERIFY(target != nullptr);
|
||||||
QVERIFY(source != target);
|
QVERIFY(source != target);
|
||||||
|
Loading…
Reference in New Issue
Block a user