mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2024-11-21 18:24:29 +08:00
Rename qPromise() helper to QtPromise::resolve()
For consistency with other helpers, deprecate `qPromise()` in favor of `QtPromise::resolve()` but also add support for calling this helper with lvalue. Add extra unit tests to make sure that rvalue is not copied.
This commit is contained in:
parent
1f30224578
commit
963ec621e1
@ -51,7 +51,7 @@ module.exports = {
|
||||
'qtpromise/helpers/each',
|
||||
'qtpromise/helpers/filter',
|
||||
'qtpromise/helpers/map',
|
||||
'qtpromise/helpers/qpromise',
|
||||
'qtpromise/helpers/resolve',
|
||||
'qtpromise/helpers/qpromiseall'
|
||||
]
|
||||
},
|
||||
|
@ -31,7 +31,7 @@
|
||||
* [`QtPromise::each`](helpers/each.md)
|
||||
* [`QtPromise::filter`](helpers/filter.md)
|
||||
* [`QtPromise::map`](helpers/map.md)
|
||||
* [`qPromise`](helpers/qpromise.md)
|
||||
* [`QtPromise::resolve`](helpers/resolve.md)
|
||||
* [`qPromiseAll`](helpers/qpromiseall.md)
|
||||
|
||||
## Exceptions
|
||||
@ -39,3 +39,7 @@
|
||||
* [`QPromiseCanceledException`](exceptions/canceled.md)
|
||||
* [`QPromiseTimeoutException`](exceptions/timeout.md)
|
||||
* [`QPromiseUndefinedException`](exceptions/undefined.md)
|
||||
|
||||
## Deprecations
|
||||
|
||||
* `QtPromise::qPromise`: use [`QtPromise::resolve`](helpers/resolve.md) instead (since 0.5.0)
|
||||
|
@ -9,7 +9,7 @@ title: QPromiseCanceledException
|
||||
This exception is thrown for promise created from a [`QFuture`](../qtconcurrent.md) which has been canceled (e.g. using [`QFuture::cancel()`](http://doc.qt.io/qt-5/qfuture.html#cancel)), for example:
|
||||
|
||||
```cpp
|
||||
auto output = qPromise(future)
|
||||
auto output = QtPromise::resolve(future)
|
||||
.fail([](const QPromiseCanceledException&) {
|
||||
// `future` has been canceled!
|
||||
});
|
||||
|
@ -56,7 +56,7 @@ The following method `uncompress` data in a separate thread and returns a [promi
|
||||
```cpp
|
||||
QPromise<Entries> uncompress(const QByteArray& data)
|
||||
{
|
||||
return qPromise(QtConcurrent::run([](const QByteArray& data) {
|
||||
return QtPromise::resolve(QtConcurrent::run([](const QByteArray& data) {
|
||||
Entries entries;
|
||||
|
||||
// {...} uncompress data and parse content.
|
||||
|
@ -1,21 +0,0 @@
|
||||
---
|
||||
title: qPromise
|
||||
---
|
||||
|
||||
# qPromise
|
||||
|
||||
*Since: 0.1.0*
|
||||
|
||||
```
|
||||
qPromise(T value) -> QPromise<R>
|
||||
```
|
||||
|
||||
Similar to the [`QPromise<T>::resolve`](../qpromise/resolve.md) static method, creates a promise resolved from a given `value` without the extra typing:
|
||||
|
||||
```cpp
|
||||
auto promise = qPromise(); // QPromise<void>
|
||||
auto promise = qPromise(42); // QPromise<int>
|
||||
auto promise = qPromise(QString("foo")); // QPromise<QString>
|
||||
```
|
||||
|
||||
This method also allows to convert `QFuture<T>` to `QPromise<T>` delayed until the `QFuture` is finished ([read more](../qtconcurrent.md#convert)).
|
21
docs/qtpromise/helpers/resolve.md
Normal file
21
docs/qtpromise/helpers/resolve.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: resolve
|
||||
---
|
||||
|
||||
# QtPromise::resolve
|
||||
|
||||
*Since: 0.5.0*
|
||||
|
||||
```
|
||||
QtPromise::resolve(T value) -> QPromise<R>
|
||||
```
|
||||
|
||||
Similar to the [`QPromise<T>::resolve`](../qpromise/resolve.md) static method, creates a promise resolved from a given `value` but without the extra typing:
|
||||
|
||||
```cpp
|
||||
auto promise = QtPromise::resolve(); // QPromise<void>
|
||||
auto promise = QtPromise::resolve(42); // QPromise<int>
|
||||
auto promise = QtPromise::resolve(QString("foo")); // QPromise<QString>
|
||||
```
|
||||
|
||||
This method also allows to convert `QFuture<T>` to `QPromise<T>`, delayed until the `QFuture` is finished ([read more](../qtconcurrent.md#convert)).
|
@ -25,4 +25,4 @@ QPromise<int> compute(const QString& type)
|
||||
}
|
||||
```
|
||||
|
||||
See also: [`qPromise`](../helpers/qpromise.md)
|
||||
See also: [`QtPromise::resolve`](../helpers/resolve.md)
|
||||
|
@ -15,7 +15,7 @@ This method holds the execution of the remaining code until the `input` promise
|
||||
```cpp
|
||||
int result = -1;
|
||||
|
||||
QPromise<int> input = qPromise(QtConcurrent::run([]() {
|
||||
QPromise<int> input = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
return 42;
|
||||
})).tap([&](int res) {
|
||||
result = res;
|
||||
|
@ -4,7 +4,7 @@ QtPromise integrates with [QtConcurrent](https://doc.qt.io/qt-5/qtconcurrent-ind
|
||||
|
||||
## <a name="qtconcurrent-convert"></a> Convert
|
||||
|
||||
Converting `QFuture<T>` to `QPromise<T>` is done using the [`qPromise`](helpers/qpromise.md) helper:
|
||||
Converting `QFuture<T>` to `QPromise<T>` is done using the [`QtPromise::resolve`](helpers/resolve.md) helper:
|
||||
|
||||
```cpp
|
||||
QFuture<int> future = QtConcurrent::run([]() {
|
||||
@ -12,13 +12,13 @@ QFuture<int> future = QtConcurrent::run([]() {
|
||||
return 42;
|
||||
});
|
||||
|
||||
QPromise<int> promise = qPromise(future);
|
||||
QPromise<int> promise = QtPromise::resolve(future);
|
||||
```
|
||||
|
||||
or simply:
|
||||
|
||||
```cpp
|
||||
auto promise = qPromise(QtConcurrent::run([]() {
|
||||
auto promise = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
// {...}
|
||||
}));
|
||||
```
|
||||
|
@ -279,9 +279,7 @@ inline QPromise<void> QPromise<void>::all(const Sequence<QPromise<void>, Args...
|
||||
|
||||
inline QPromise<void> QPromise<void>::resolve()
|
||||
{
|
||||
return QPromise<void>([](const QPromiseResolve<void>& resolve) {
|
||||
resolve();
|
||||
});
|
||||
return QtPromise::resolve();
|
||||
}
|
||||
|
||||
} // namespace QtPromise
|
||||
|
@ -110,9 +110,24 @@ private:
|
||||
template <typename T>
|
||||
struct PromiseDeduce
|
||||
{
|
||||
using Type = QtPromise::QPromise<Unqualified<T>>;
|
||||
using Type = QtPromise::QPromise<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PromiseDeduce<T&>
|
||||
: public PromiseDeduce<T>
|
||||
{ };
|
||||
|
||||
template <typename T>
|
||||
struct PromiseDeduce<const T>
|
||||
: public PromiseDeduce<T>
|
||||
{ };
|
||||
|
||||
template <typename T>
|
||||
struct PromiseDeduce<const volatile T>
|
||||
: public PromiseDeduce<T>
|
||||
{ };
|
||||
|
||||
template <typename T>
|
||||
struct PromiseDeduce<QtPromise::QPromise<T>>
|
||||
: public PromiseDeduce<T>
|
||||
@ -128,22 +143,21 @@ struct PromiseFunctor
|
||||
template <typename T>
|
||||
struct PromiseFulfill
|
||||
{
|
||||
static void call(
|
||||
T&& value,
|
||||
const QtPromise::QPromiseResolve<T>& resolve,
|
||||
const QtPromise::QPromiseReject<T>&)
|
||||
template <typename V, typename TResolve, typename TReject>
|
||||
static void call(V&& value, const TResolve& resolve, const TReject&)
|
||||
{
|
||||
resolve(std::move(value));
|
||||
resolve(std::forward<V>(value));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PromiseFulfill<QtPromise::QPromise<T>>
|
||||
{
|
||||
template <typename TResolve, typename TReject>
|
||||
static void call(
|
||||
const QtPromise::QPromise<T>& promise,
|
||||
const QtPromise::QPromiseResolve<T>& resolve,
|
||||
const QtPromise::QPromiseReject<T>& reject)
|
||||
const TResolve& resolve,
|
||||
const TReject& reject)
|
||||
{
|
||||
if (promise.isFulfilled()) {
|
||||
resolve(promise.m_d->value());
|
||||
|
@ -7,21 +7,34 @@
|
||||
namespace QtPromise {
|
||||
|
||||
template <typename T>
|
||||
static inline typename QtPromisePrivate::PromiseDeduce<T>::Type qPromise(T&& value)
|
||||
static inline typename QtPromisePrivate::PromiseDeduce<T>::Type
|
||||
resolve(T&& value)
|
||||
{
|
||||
using namespace QtPromisePrivate;
|
||||
using Promise = typename PromiseDeduce<T>::Type;
|
||||
return Promise([&](
|
||||
const QPromiseResolve<typename Promise::Type>& resolve,
|
||||
const QPromiseReject<typename Promise::Type>& reject) {
|
||||
PromiseFulfill<T>::call(std::forward<T>(value), resolve, reject);
|
||||
using PromiseType = typename PromiseDeduce<T>::Type;
|
||||
using ValueType = typename PromiseType::Type;
|
||||
using ResolveType = QPromiseResolve<ValueType>;
|
||||
using RejectType = QPromiseReject<ValueType>;
|
||||
|
||||
return PromiseType([&](ResolveType&& resolve, RejectType&& reject) {
|
||||
PromiseFulfill<Unqualified<T>>::call(
|
||||
std::forward<T>(value),
|
||||
std::forward<ResolveType>(resolve),
|
||||
std::forward<RejectType>(reject));
|
||||
});
|
||||
}
|
||||
|
||||
static inline QPromise<void> qPromise()
|
||||
template <typename T>
|
||||
static inline QPromise<T>
|
||||
resolve(QPromise<T> value)
|
||||
{
|
||||
return QPromise<void>([](
|
||||
const QPromiseResolve<void>& resolve) {
|
||||
return std::move(value);
|
||||
}
|
||||
|
||||
static inline QPromise<void>
|
||||
resolve()
|
||||
{
|
||||
return QPromise<void>([](const QPromiseResolve<void>& resolve) {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
@ -153,6 +166,17 @@ static inline QPromise<Sequence> filter(const Sequence& values, Functor fn)
|
||||
});
|
||||
}
|
||||
|
||||
// DEPRECATIONS (remove at version 1)
|
||||
|
||||
template <typename... Args>
|
||||
Q_DECL_DEPRECATED_X("Use QtPromise::resolve instead")
|
||||
static inline auto
|
||||
qPromise(Args&&... args)
|
||||
-> decltype(QtPromise::resolve(std::forward<Args>(args)...))
|
||||
{
|
||||
return QtPromise::resolve(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace QtPromise
|
||||
|
||||
#endif // QTPROMISE_QPROMISEHELPERS_H
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "../shared/data.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
@ -20,7 +22,6 @@ class tst_benchmark : public QObject
|
||||
|
||||
private Q_SLOTS:
|
||||
void valueResolve();
|
||||
void valueResolveStatic();
|
||||
void valueReject();
|
||||
void valueThen();
|
||||
void valueFinally();
|
||||
@ -34,72 +35,6 @@ private Q_SLOTS:
|
||||
QTEST_MAIN(tst_benchmark)
|
||||
#include "tst_benchmark.moc"
|
||||
|
||||
struct Logs {
|
||||
int ctor = 0;
|
||||
int copy = 0;
|
||||
int move = 0;
|
||||
int refs = 0;
|
||||
|
||||
void reset() {
|
||||
ctor = 0;
|
||||
copy = 0;
|
||||
move = 0;
|
||||
refs = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Logger
|
||||
{
|
||||
Logger() { logs().ctor++; logs().refs++; }
|
||||
Logger(const Logger&) { logs().copy++; logs().refs++; }
|
||||
Logger(Logger&&) { logs().move++; logs().refs++; }
|
||||
~Logger() { logs().refs--; }
|
||||
|
||||
Logger& operator=(const Logger&) { logs().copy++; return *this; }
|
||||
Logger& operator=(Logger&&) { logs().move++; return *this; }
|
||||
|
||||
public: // STATICS
|
||||
static Logs& logs() { static Logs logs; return logs; }
|
||||
};
|
||||
|
||||
struct Data : public Logger
|
||||
{
|
||||
Data(int v): Logger(), m_value(v) {}
|
||||
int value() const { return m_value; }
|
||||
|
||||
// MSVC 2013 doesn't support implicit generation of the move constructor and
|
||||
// operator, so we need to explicitly define these methods and thus the copy
|
||||
// constructor and operator also need to be explicitly defined (error C2280).
|
||||
// https://stackoverflow.com/a/26581337
|
||||
|
||||
Data(const Data& other)
|
||||
: Logger(other)
|
||||
, m_value(other.m_value)
|
||||
{ }
|
||||
|
||||
Data(Data&& other) : Logger(std::forward<Data>(other))
|
||||
{
|
||||
qSwap(m_value, other.m_value);
|
||||
}
|
||||
|
||||
Data& operator=(const Data& other)
|
||||
{
|
||||
Logger::operator=(other);
|
||||
m_value = other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data& operator=(Data&& other)
|
||||
{
|
||||
Logger::operator=(std::forward<Data>(other));
|
||||
qSwap(m_value, other.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_value;
|
||||
};
|
||||
|
||||
void tst_benchmark::valueResolve()
|
||||
{
|
||||
{ // should move the value when resolved by rvalue
|
||||
@ -127,31 +62,6 @@ void tst_benchmark::valueResolve()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_benchmark::valueResolveStatic()
|
||||
{
|
||||
{ // should move the value when resolved by rvalue
|
||||
Data::logs().reset();
|
||||
QPromise<Data>::resolve(Data(42)).wait();
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 1); // move value to the promise data
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
{ // should create one copy of the value when resolved by lvalue
|
||||
{
|
||||
Data::logs().reset();
|
||||
Data value(42);
|
||||
QPromise<Data>::resolve(value).wait();
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 1); // copy value to the promise data
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_benchmark::valueReject()
|
||||
{
|
||||
{ // should not create any data if rejected
|
||||
|
5
tests/auto/qtpromise/deprecations/deprecations.pri
Normal file
5
tests/auto/qtpromise/deprecations/deprecations.pri
Normal file
@ -0,0 +1,5 @@
|
||||
include(../qtpromise.pri)
|
||||
|
||||
DEFINES -= QT_DEPRECATED_WARNINGS
|
||||
gcc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations
|
||||
msvc:QMAKE_CXXFLAGS -= -wd4996
|
3
tests/auto/qtpromise/deprecations/deprecations.pro
Normal file
3
tests/auto/qtpromise/deprecations/deprecations.pro
Normal file
@ -0,0 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
helpers
|
3
tests/auto/qtpromise/deprecations/helpers/helpers.pro
Normal file
3
tests/auto/qtpromise/deprecations/helpers/helpers.pro
Normal file
@ -0,0 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
qpromise
|
@ -0,0 +1,5 @@
|
||||
QT += concurrent
|
||||
TARGET = tst_deprecations_helpers_qpromise
|
||||
SOURCES += $$PWD/tst_qpromise.cpp
|
||||
|
||||
include(../../deprecations.pri)
|
@ -0,0 +1,268 @@
|
||||
#include "../../../shared/data.h"
|
||||
#include "../../../shared/utils.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
// Qt
|
||||
#include <QtConcurrent>
|
||||
#include <QtTest>
|
||||
|
||||
// STL
|
||||
#include <memory>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_deprecations_helpers_qpromise : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void value();
|
||||
void noValue();
|
||||
void moveRValue();
|
||||
void copyLValue();
|
||||
void qtSharedPtr();
|
||||
void stdSharedPtr();
|
||||
void typedPromise();
|
||||
void voidPromise();
|
||||
void typedFuture();
|
||||
void voidFuture();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_deprecations_helpers_qpromise)
|
||||
#include "tst_qpromise.moc"
|
||||
|
||||
void tst_deprecations_helpers_qpromise::value()
|
||||
{
|
||||
int v0 = 42;
|
||||
const int v1 = 42;
|
||||
|
||||
auto p0 = qPromise(42);
|
||||
auto p1 = qPromise(v0);
|
||||
auto p2 = qPromise(v1);
|
||||
|
||||
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(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& p : {p0, p1, p2}) {
|
||||
QCOMPARE(p.isFulfilled(), true);
|
||||
}
|
||||
for (const auto& p : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(p, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::noValue()
|
||||
{
|
||||
auto p = qPromise();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
|
||||
QCOMPARE(p.isFulfilled(), true);
|
||||
QCOMPARE(waitForValue(p, -1, 42), 42);
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::moveRValue()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
{
|
||||
auto p = qPromise(Data(42)).wait();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Data>>::value));
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 1);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::copyLValue()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
{
|
||||
Data value(42);
|
||||
auto p = qPromise(value).wait();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Data>>::value));
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 1);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_deprecations_helpers_qpromise::qtSharedPtr()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
QWeakPointer<Data> wptr;
|
||||
|
||||
{
|
||||
QSharedPointer<Data> sptr0(new Data(42));
|
||||
const QSharedPointer<Data> sptr1 = sptr0;
|
||||
|
||||
auto p0 = qPromise(QSharedPointer<Data>(new Data(42)));
|
||||
auto p1 = qPromise(sptr0);
|
||||
auto p2 = qPromise(sptr1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<QSharedPointer<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<QSharedPointer<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<QSharedPointer<Data>>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p1, QSharedPointer<Data>()), sptr0);
|
||||
QCOMPARE(waitForValue(p2, QSharedPointer<Data>()), sptr1);
|
||||
|
||||
wptr = sptr0;
|
||||
|
||||
QCOMPARE(wptr.isNull(), false);
|
||||
QCOMPARE(Data::logs().refs, 2);
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.isNull(), true);
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 2);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_deprecations_helpers_qpromise::stdSharedPtr()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
std::weak_ptr<Data> wptr;
|
||||
|
||||
{
|
||||
std::shared_ptr<Data> sptr0(new Data(42));
|
||||
const std::shared_ptr<Data> sptr1 = sptr0;
|
||||
|
||||
auto p0 = qPromise(std::shared_ptr<Data>(new Data(42)));
|
||||
auto p1 = qPromise(sptr0);
|
||||
auto p2 = qPromise(sptr1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<std::shared_ptr<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<std::shared_ptr<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<std::shared_ptr<Data>>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p1, std::shared_ptr<Data>()), sptr0);
|
||||
QCOMPARE(waitForValue(p2, std::shared_ptr<Data>()), sptr1);
|
||||
|
||||
wptr = sptr0;
|
||||
|
||||
QCOMPARE(wptr.use_count(), 4l);
|
||||
QCOMPARE(Data::logs().refs, 2);
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.use_count(), 0l);
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 2);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::typedPromise()
|
||||
{
|
||||
auto resolver = [](const QPromiseResolve<int>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve(42);
|
||||
});
|
||||
};
|
||||
|
||||
QPromise<int> v0(resolver);
|
||||
const QPromise<int> v1 = v0;
|
||||
|
||||
auto p0 = qPromise(QPromise<int>(resolver));
|
||||
auto p1 = qPromise(v0);
|
||||
auto p2 = qPromise(v1);
|
||||
|
||||
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(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::voidPromise()
|
||||
{
|
||||
auto resolver = [](const QPromiseResolve<void>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
QPromise<void> v0(resolver);
|
||||
const QPromise<void> v1 = v0;
|
||||
|
||||
auto p0 = qPromise(QPromise<void>(resolver));
|
||||
auto p1 = qPromise(v0);
|
||||
auto p2 = qPromise(v1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<void>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1, 42), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::typedFuture()
|
||||
{
|
||||
auto fn = [](){ return 42; };
|
||||
QFuture<int> v0 = QtConcurrent::run(fn);
|
||||
const QFuture<int> v1 = v0;
|
||||
|
||||
auto p0 = qPromise(QtConcurrent::run(fn));
|
||||
auto p1 = qPromise(v0);
|
||||
auto p2 = qPromise(v1);
|
||||
|
||||
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(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_deprecations_helpers_qpromise::voidFuture()
|
||||
{
|
||||
auto fn = [](){ };
|
||||
QFuture<void> v0 = QtConcurrent::run(fn);
|
||||
const QFuture<void> v1 = v0;
|
||||
|
||||
auto p0 = qPromise(QtConcurrent::run(fn));
|
||||
auto p1 = qPromise(v0);
|
||||
auto p2 = qPromise(v1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<void>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1, 42), 42);
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ namespace {
|
||||
template <class E>
|
||||
void verify()
|
||||
{
|
||||
auto p = qPromise(QtConcurrent::run([]() { throw E(); }));
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() { throw E(); }));
|
||||
QCOMPARE(p.isPending(), true);
|
||||
QCOMPARE(waitForRejected<E>(p), true);
|
||||
QCOMPARE(p.isRejected(), true);
|
||||
|
@ -52,7 +52,7 @@ QTEST_MAIN(tst_future)
|
||||
void tst_future::fulfilled()
|
||||
{
|
||||
int result = -1;
|
||||
auto p = qPromise(QtConcurrent::run([]() {
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
return 42;
|
||||
}));
|
||||
|
||||
@ -70,7 +70,7 @@ void tst_future::fulfilled()
|
||||
void tst_future::fulfilled_void()
|
||||
{
|
||||
int result = -1;
|
||||
auto p = qPromise(QtConcurrent::run([]() { }));
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() { }));
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
QCOMPARE(p.isPending(), true);
|
||||
@ -86,7 +86,7 @@ void tst_future::fulfilled_void()
|
||||
void tst_future::rejected()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QtConcurrent::run([]() {
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
throw MyException("foo");
|
||||
return 42;
|
||||
}));
|
||||
@ -106,7 +106,7 @@ void tst_future::rejected()
|
||||
void tst_future::rejected_void()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QtConcurrent::run([]() {
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
throw MyException("foo");
|
||||
}));
|
||||
|
||||
@ -125,7 +125,7 @@ void tst_future::rejected_void()
|
||||
void tst_future::unhandled()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QtConcurrent::run([]() {
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
throw QString("foo");
|
||||
return 42;
|
||||
}));
|
||||
@ -149,7 +149,7 @@ void tst_future::unhandled()
|
||||
void tst_future::unhandled_void()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QtConcurrent::run([]() {
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
throw QString("foo");
|
||||
}));
|
||||
|
||||
@ -169,7 +169,7 @@ void tst_future::unhandled_void()
|
||||
void tst_future::canceled()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QFuture<int>()); // Constructs an empty, canceled future.
|
||||
auto p = QtPromise::resolve(QFuture<int>()); // Constructs an empty, canceled future.
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
|
||||
@ -185,7 +185,7 @@ void tst_future::canceled()
|
||||
void tst_future::canceled_void()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QFuture<void>()); // Constructs an empty, canceled future.
|
||||
auto p = QtPromise::resolve(QFuture<void>()); // Constructs an empty, canceled future.
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
|
||||
@ -200,7 +200,7 @@ void tst_future::canceled_void()
|
||||
void tst_future::canceledFromThread()
|
||||
{
|
||||
QString error;
|
||||
auto p = qPromise(QtConcurrent::run([]() {
|
||||
auto p = QtPromise::resolve(QtConcurrent::run([]() {
|
||||
throw QPromiseCanceledException();
|
||||
}));
|
||||
|
||||
@ -217,7 +217,7 @@ void tst_future::canceledFromThread()
|
||||
void tst_future::then()
|
||||
{
|
||||
QString result;
|
||||
auto input = qPromise(42);
|
||||
auto input = QtPromise::resolve(42);
|
||||
auto output = input.then([](int res) {
|
||||
return QtConcurrent::run([=]() {
|
||||
return QString("foo%1").arg(res);
|
||||
@ -238,7 +238,7 @@ void tst_future::then()
|
||||
void tst_future::then_void()
|
||||
{
|
||||
QString result;
|
||||
auto input = qPromise();
|
||||
auto input = QtPromise::resolve();
|
||||
auto output = input.then([&]() {
|
||||
return QtConcurrent::run([&]() {
|
||||
result = "foo";
|
||||
@ -300,7 +300,7 @@ void tst_future::fail_void()
|
||||
|
||||
void tst_future::finally()
|
||||
{
|
||||
auto input = qPromise(42);
|
||||
auto input = QtPromise::resolve(42);
|
||||
auto output = input.finally([]() {
|
||||
return QtConcurrent::run([]() {
|
||||
return QString("foo");
|
||||
@ -323,7 +323,7 @@ void tst_future::finally()
|
||||
|
||||
void tst_future::finallyRejected()
|
||||
{
|
||||
auto input = qPromise(42);
|
||||
auto input = QtPromise::resolve(42);
|
||||
auto output = input.finally([]() {
|
||||
return QtConcurrent::run([]() {
|
||||
throw MyException("foo");
|
||||
|
@ -37,13 +37,13 @@ struct SequenceTester
|
||||
static void exec()
|
||||
{
|
||||
Sequence promises{
|
||||
QtPromise::qPromise(42),
|
||||
QtPromise::qPromise(43),
|
||||
QtPromise::qPromise(44)
|
||||
QtPromise::resolve(42),
|
||||
QtPromise::resolve(43),
|
||||
QtPromise::resolve(44)
|
||||
};
|
||||
|
||||
promises.push_back(QtPromise::qPromise(45));
|
||||
promises.insert(++promises.begin(), QtPromise::qPromise(46));
|
||||
promises.push_back(QtPromise::resolve(45));
|
||||
promises.insert(++promises.begin(), QtPromise::resolve(46));
|
||||
promises.pop_back();
|
||||
|
||||
auto p = QtPromise::qPromiseAll(promises);
|
||||
@ -60,13 +60,13 @@ struct SequenceTester<Sequence<QPromise<void>, Args...>>
|
||||
static void exec()
|
||||
{
|
||||
Sequence<QPromise<void>, Args...> promises{
|
||||
QtPromise::qPromise(),
|
||||
QtPromise::qPromise(),
|
||||
QtPromise::qPromise()
|
||||
QtPromise::resolve(),
|
||||
QtPromise::resolve(),
|
||||
QtPromise::resolve()
|
||||
};
|
||||
|
||||
promises.push_back(QtPromise::qPromise());
|
||||
promises.insert(++promises.begin(), QtPromise::qPromise());
|
||||
promises.push_back(QtPromise::resolve());
|
||||
promises.insert(++promises.begin(), QtPromise::resolve());
|
||||
promises.pop_back();
|
||||
|
||||
auto p = QtPromise::qPromiseAll(promises);
|
||||
@ -99,8 +99,8 @@ void tst_helpers_all::emptySequence_void()
|
||||
|
||||
void tst_helpers_all::allPromisesSucceed()
|
||||
{
|
||||
auto p0 = QtPromise::qPromise(42);
|
||||
auto p1 = QtPromise::qPromise(44);
|
||||
auto p0 = QtPromise::resolve(42);
|
||||
auto p1 = QtPromise::resolve(44);
|
||||
auto p2 = QPromise<int>([](const QPromiseResolve<int>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve(43);
|
||||
@ -120,8 +120,8 @@ void tst_helpers_all::allPromisesSucceed()
|
||||
|
||||
void tst_helpers_all::allPromisesSucceed_void()
|
||||
{
|
||||
auto p0 = QtPromise::qPromise();
|
||||
auto p1 = QtPromise::qPromise();
|
||||
auto p0 = QtPromise::resolve();
|
||||
auto p1 = QtPromise::resolve();
|
||||
auto p2 = QPromise<void>([](const QPromiseResolve<void>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve();
|
||||
@ -141,8 +141,8 @@ void tst_helpers_all::allPromisesSucceed_void()
|
||||
|
||||
void tst_helpers_all::atLeastOnePromiseReject()
|
||||
{
|
||||
auto p0 = QtPromise::qPromise(42);
|
||||
auto p1 = QtPromise::qPromise(44);
|
||||
auto p0 = QtPromise::resolve(42);
|
||||
auto p1 = QtPromise::resolve(44);
|
||||
auto p2 = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
reject(QString("foo"));
|
||||
@ -162,8 +162,8 @@ void tst_helpers_all::atLeastOnePromiseReject()
|
||||
|
||||
void tst_helpers_all::atLeastOnePromiseReject_void()
|
||||
{
|
||||
auto p0 = QtPromise::qPromise();
|
||||
auto p1 = QtPromise::qPromise();
|
||||
auto p0 = QtPromise::resolve();
|
||||
auto p1 = QtPromise::resolve();
|
||||
auto p2 = QPromise<void>([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
reject(QString("foo"));
|
||||
@ -183,9 +183,9 @@ void tst_helpers_all::atLeastOnePromiseReject_void()
|
||||
|
||||
void tst_helpers_all::preserveOrder()
|
||||
{
|
||||
auto p0 = QtPromise::qPromise(42).delay(500);
|
||||
auto p1 = QtPromise::qPromise(43).delay(100);
|
||||
auto p2 = QtPromise::qPromise(44).delay(250);
|
||||
auto p0 = QtPromise::resolve(42).delay(500);
|
||||
auto p1 = QtPromise::resolve(43).delay(100);
|
||||
auto p2 = QtPromise::resolve(44).delay(250);
|
||||
|
||||
auto p = QtPromise::qPromiseAll(QVector<QPromise<int>>{p0, p1, p2});
|
||||
|
||||
|
@ -64,7 +64,7 @@ void tst_helpers_attempt::futureResult()
|
||||
void tst_helpers_attempt::promiseResult()
|
||||
{
|
||||
auto p = QtPromise::attempt([]() {
|
||||
return QtPromise::qPromise(42).delay(200);
|
||||
return QtPromise::resolve(42).delay(200);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
@ -1,3 +1,4 @@
|
||||
QT += concurrent
|
||||
TARGET = tst_helpers_resolve
|
||||
SOURCES += $$PWD/tst_resolve.cpp
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include "../../shared/data.h"
|
||||
#include "../../shared/utils.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
// Qt
|
||||
#include <QtConcurrent>
|
||||
#include <QtTest>
|
||||
|
||||
// STL
|
||||
@ -16,109 +18,251 @@ class tst_helpers_resolve : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void resolveWithValue();
|
||||
void resolveWithNoValue();
|
||||
void resolveWithTypedPromise();
|
||||
void resolveWithVoidPromise();
|
||||
void resolveWithQSharedPtr();
|
||||
void resolveWithStdSharedPtr();
|
||||
void value();
|
||||
void noValue();
|
||||
void moveRValue();
|
||||
void copyLValue();
|
||||
void qtSharedPtr();
|
||||
void stdSharedPtr();
|
||||
void typedPromise();
|
||||
void voidPromise();
|
||||
void typedFuture();
|
||||
void voidFuture();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_helpers_resolve)
|
||||
#include "tst_resolve.moc"
|
||||
|
||||
void tst_helpers_resolve::resolveWithValue()
|
||||
void tst_helpers_resolve::value()
|
||||
{
|
||||
const int value = 42;
|
||||
auto p0 = QPromise<int>::resolve(value);
|
||||
auto p1 = QPromise<int>::resolve(43);
|
||||
int v0 = 42;
|
||||
const int v1 = 42;
|
||||
|
||||
auto p0 = QtPromise::resolve(42);
|
||||
auto p1 = QtPromise::resolve(v0);
|
||||
auto p2 = QtPromise::resolve(v1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<int>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<int>>::value));
|
||||
QCOMPARE(p0.isFulfilled(), true);
|
||||
QCOMPARE(p1.isFulfilled(), true);
|
||||
QCOMPARE(waitForValue(p0, -1), 42);
|
||||
QCOMPARE(waitForValue(p1, -1), 43);
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& p : {p0, p1, p2}) {
|
||||
QCOMPARE(p.isFulfilled(), true);
|
||||
}
|
||||
for (const auto& p : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(p, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::resolveWithNoValue()
|
||||
void tst_helpers_resolve::noValue()
|
||||
{
|
||||
auto p = QPromise<void>::resolve();
|
||||
auto p = QtPromise::resolve();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
|
||||
QCOMPARE(p.isFulfilled(), true);
|
||||
QCOMPARE(waitForValue(p, -1, 42), 42);
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::resolveWithTypedPromise()
|
||||
void tst_helpers_resolve::moveRValue()
|
||||
{
|
||||
auto p = QtPromise::qPromise(
|
||||
QPromise<QString>([](const QPromiseResolve<QString>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve("foo");
|
||||
});
|
||||
}));
|
||||
Data::logs().reset();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
||||
{
|
||||
auto p = QtPromise::resolve(Data(42)).wait();
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
QCOMPARE(waitForValue(p, QString()), QString("foo"));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Data>>::value));
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 1);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::resolveWithVoidPromise()
|
||||
void tst_helpers_resolve::copyLValue()
|
||||
{
|
||||
int check;
|
||||
auto p = QtPromise::qPromise(
|
||||
QPromise<void>([&](const QPromiseResolve<void>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=, &check](){
|
||||
check = 8;
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
Data::logs().reset();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
{
|
||||
Data value(42);
|
||||
auto p = QtPromise::resolve(value).wait();
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
QCOMPARE(waitForValue(p, -1, 42), 42);
|
||||
QCOMPARE(check, 8);
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Data>>::value));
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 1);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_helpers_resolve::resolveWithQSharedPtr()
|
||||
void tst_helpers_resolve::qtSharedPtr()
|
||||
{
|
||||
QWeakPointer<int> wptr;
|
||||
Data::logs().reset();
|
||||
|
||||
QWeakPointer<Data> wptr;
|
||||
|
||||
{
|
||||
QSharedPointer<int> sptr(new int(42));
|
||||
auto p = QPromise<QSharedPointer<int>>::resolve(sptr);
|
||||
QSharedPointer<Data> sptr0(new Data(42));
|
||||
const QSharedPointer<Data> sptr1 = sptr0;
|
||||
|
||||
QCOMPARE(waitForValue(p, QSharedPointer<int>()), sptr);
|
||||
auto p0 = QtPromise::resolve(QSharedPointer<Data>(new Data(42)));
|
||||
auto p1 = QtPromise::resolve(sptr0);
|
||||
auto p2 = QtPromise::resolve(sptr1);
|
||||
|
||||
wptr = sptr;
|
||||
sptr.reset();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<QSharedPointer<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<QSharedPointer<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<QSharedPointer<Data>>>::value));
|
||||
|
||||
QCOMPARE(wptr.isNull(), false); // "p" still holds a reference
|
||||
QCOMPARE(waitForValue(p1, QSharedPointer<Data>()), sptr0);
|
||||
QCOMPARE(waitForValue(p2, QSharedPointer<Data>()), sptr1);
|
||||
|
||||
wptr = sptr0;
|
||||
|
||||
QCOMPARE(wptr.isNull(), false);
|
||||
QCOMPARE(Data::logs().refs, 2);
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.isNull(), true);
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 2);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_helpers_resolve::resolveWithStdSharedPtr()
|
||||
void tst_helpers_resolve::stdSharedPtr()
|
||||
{
|
||||
std::weak_ptr<int> wptr;
|
||||
Data::logs().reset();
|
||||
|
||||
std::weak_ptr<Data> wptr;
|
||||
|
||||
{
|
||||
std::shared_ptr<int> sptr(new int(42));
|
||||
auto p = QPromise<std::shared_ptr<int>>::resolve(sptr);
|
||||
std::shared_ptr<Data> sptr0(new Data(42));
|
||||
const std::shared_ptr<Data> sptr1 = sptr0;
|
||||
|
||||
QCOMPARE(waitForValue(p, std::shared_ptr<int>()), sptr);
|
||||
auto p0 = QtPromise::resolve(std::shared_ptr<Data>(new Data(42)));
|
||||
auto p1 = QtPromise::resolve(sptr0);
|
||||
auto p2 = QtPromise::resolve(sptr1);
|
||||
|
||||
wptr = sptr;
|
||||
sptr.reset();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<std::shared_ptr<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<std::shared_ptr<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<std::shared_ptr<Data>>>::value));
|
||||
|
||||
QCOMPARE(wptr.use_count(), 1l); // "p" still holds a reference
|
||||
QCOMPARE(waitForValue(p1, std::shared_ptr<Data>()), sptr0);
|
||||
QCOMPARE(waitForValue(p2, std::shared_ptr<Data>()), sptr1);
|
||||
|
||||
wptr = sptr0;
|
||||
|
||||
QCOMPARE(wptr.use_count(), 4l);
|
||||
QCOMPARE(Data::logs().refs, 2);
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.use_count(), 0l);
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 2);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::typedPromise()
|
||||
{
|
||||
auto resolver = [](const QPromiseResolve<int>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve(42);
|
||||
});
|
||||
};
|
||||
|
||||
QPromise<int> v0(resolver);
|
||||
const QPromise<int> v1 = v0;
|
||||
|
||||
auto p0 = QtPromise::resolve(QPromise<int>(resolver));
|
||||
auto p1 = QtPromise::resolve(v0);
|
||||
auto p2 = QtPromise::resolve(v1);
|
||||
|
||||
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(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::voidPromise()
|
||||
{
|
||||
auto resolver = [](const QPromiseResolve<void>& resolve) {
|
||||
QtPromisePrivate::qtpromise_defer([=](){
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
QPromise<void> v0(resolver);
|
||||
const QPromise<void> v1 = v0;
|
||||
|
||||
auto p0 = QtPromise::resolve(QPromise<void>(resolver));
|
||||
auto p1 = QtPromise::resolve(v0);
|
||||
auto p2 = QtPromise::resolve(v1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<void>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1, 42), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::typedFuture()
|
||||
{
|
||||
auto fn = [](){ return 42; };
|
||||
QFuture<int> v0 = QtConcurrent::run(fn);
|
||||
const QFuture<int> v1 = v0;
|
||||
|
||||
auto p0 = QtPromise::resolve(QtConcurrent::run(fn));
|
||||
auto p1 = QtPromise::resolve(v0);
|
||||
auto p2 = QtPromise::resolve(v1);
|
||||
|
||||
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(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_helpers_resolve::voidFuture()
|
||||
{
|
||||
auto fn = [](){ };
|
||||
QFuture<void> v0 = QtConcurrent::run(fn);
|
||||
const QFuture<void> v1 = v0;
|
||||
|
||||
auto p0 = QtPromise::resolve(QtConcurrent::run(fn));
|
||||
auto p1 = QtPromise::resolve(v0);
|
||||
auto p2 = QtPromise::resolve(v1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<void>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<void>>::value));
|
||||
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(promise.isPending(), true);
|
||||
}
|
||||
for (const auto& promise : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(promise, -1, 42), 42);
|
||||
}
|
||||
}
|
||||
|
@ -34,14 +34,14 @@ struct SequenceTester
|
||||
static void exec()
|
||||
{
|
||||
QVector<int> values;
|
||||
auto p = QtPromise::qPromise(Sequence{42, 43, 44}).each([&](int v, int i) {
|
||||
auto p = QtPromise::resolve(Sequence{42, 43, 44}).each([&](int v, int i) {
|
||||
values << i << v;
|
||||
}).each([&](int v, ...) {
|
||||
values << v;
|
||||
return QString("foo");
|
||||
}).each([&](int v, ...) {
|
||||
values << v + 1;
|
||||
return QPromise<QString>::resolve(QString("foo")).then([&](){
|
||||
return QtPromise::resolve(QString("foo")).then([&](){
|
||||
values << -1;
|
||||
});
|
||||
}).each([&](int v, ...) {
|
||||
|
@ -33,7 +33,7 @@ struct SequenceTester
|
||||
{
|
||||
static void exec()
|
||||
{
|
||||
auto p = QtPromise::qPromise(Sequence{
|
||||
auto p = QtPromise::resolve(Sequence{
|
||||
42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
||||
}).filter([](int v, ...) {
|
||||
return v > 42 && v < 51;
|
||||
|
@ -34,12 +34,12 @@ struct SequenceTester
|
||||
{
|
||||
static void exec()
|
||||
{
|
||||
auto p = QtPromise::qPromise(Sequence{42, 43, 44}).map([](int v, ...) {
|
||||
auto p = QtPromise::resolve(Sequence{42, 43, 44}).map([](int v, ...) {
|
||||
return QString::number(v + 1);
|
||||
}).map([](const QString& v, int i) {
|
||||
return QtPromise::qPromise(QString("%1:%2").arg(i).arg(v));
|
||||
return QtPromise::resolve(QString("%1:%2").arg(i).arg(v));
|
||||
}).map([](const QString& v, ...) {
|
||||
return QtPromise::qPromise((v + "!").toUtf8());
|
||||
return QtPromise::resolve((v + "!").toUtf8());
|
||||
}).map([](const QByteArray& v, ...) {
|
||||
return QString::fromUtf8(v);
|
||||
});
|
||||
@ -53,7 +53,7 @@ struct SequenceTester
|
||||
|
||||
void tst_qpromise_map::emptySequence()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{}).map([](int v, ...) {
|
||||
auto p = QtPromise::resolve(QVector<int>{}).map([](int v, ...) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
@ -63,7 +63,7 @@ void tst_qpromise_map::emptySequence()
|
||||
|
||||
void tst_qpromise_map::modifyValues()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
return v + 1;
|
||||
});
|
||||
|
||||
@ -73,7 +73,7 @@ void tst_qpromise_map::modifyValues()
|
||||
|
||||
void tst_qpromise_map::convertValues()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
return QString::number(v + 1);
|
||||
});
|
||||
|
||||
@ -83,7 +83,7 @@ void tst_qpromise_map::convertValues()
|
||||
|
||||
void tst_qpromise_map::delayedFulfilled()
|
||||
{
|
||||
auto p = QtPromise::qPromise(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) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
resolve(v + 1);
|
||||
@ -97,7 +97,7 @@ void tst_qpromise_map::delayedFulfilled()
|
||||
|
||||
void tst_qpromise_map::delayedRejected()
|
||||
{
|
||||
auto p = QtPromise::qPromise(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,
|
||||
const QPromiseReject<int>& reject) {
|
||||
@ -116,7 +116,7 @@ void tst_qpromise_map::delayedRejected()
|
||||
|
||||
void tst_qpromise_map::functorThrows()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
auto p = QtPromise::resolve(QVector<int>{42, 43, 44}).map([](int v, ...) {
|
||||
if (v == 43) {
|
||||
throw QString("foo");
|
||||
}
|
||||
@ -129,7 +129,7 @@ void tst_qpromise_map::functorThrows()
|
||||
|
||||
void tst_qpromise_map::functorArguments()
|
||||
{
|
||||
auto p1 = QtPromise::qPromise(QVector<int>{42, 42, 42}).map([](int v, int i) {
|
||||
auto p1 = QtPromise::resolve(QVector<int>{42, 42, 42}).map([](int v, int i) {
|
||||
return v * i;
|
||||
});
|
||||
|
||||
@ -139,8 +139,8 @@ void tst_qpromise_map::functorArguments()
|
||||
|
||||
void tst_qpromise_map::preserveOrder()
|
||||
{
|
||||
auto p = QtPromise::qPromise(QVector<int>{250, 500, 100}).map([](int v, ...) {
|
||||
return QtPromise::qPromise(v + 1).delay(v);
|
||||
auto p = QtPromise::resolve(QVector<int>{250, 500, 100}).map([](int v, ...) {
|
||||
return QtPromise::resolve(v + 1).delay(v);
|
||||
});
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVector<int>>>::value));
|
||||
|
@ -8,6 +8,7 @@ SUBDIRS += \
|
||||
finally \
|
||||
map \
|
||||
operators \
|
||||
resolve \
|
||||
tap \
|
||||
tapfail \
|
||||
then \
|
||||
|
4
tests/auto/qtpromise/qpromise/resolve/resolve.pro
Normal file
4
tests/auto/qtpromise/qpromise/resolve/resolve.pro
Normal file
@ -0,0 +1,4 @@
|
||||
TARGET = tst_qpromise_resolve
|
||||
SOURCES += $$PWD/tst_resolve.cpp
|
||||
|
||||
include(../../qtpromise.pri)
|
165
tests/auto/qtpromise/qpromise/resolve/tst_resolve.cpp
Normal file
165
tests/auto/qtpromise/qpromise/resolve/tst_resolve.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include "../../shared/data.h"
|
||||
#include "../../shared/utils.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
// Qt
|
||||
#include <QtTest>
|
||||
|
||||
// STL
|
||||
#include <memory>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_qpromise_resolve : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void value();
|
||||
void noValue();
|
||||
void moveRValue();
|
||||
void copyLValue();
|
||||
void qtSharedPtr();
|
||||
void stdSharedPtr();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_qpromise_resolve)
|
||||
#include "tst_resolve.moc"
|
||||
|
||||
void tst_qpromise_resolve::value()
|
||||
{
|
||||
int v0 = 42;
|
||||
const int v1 = 42;
|
||||
|
||||
auto p0 = QPromise<int>::resolve(42);
|
||||
auto p1 = QPromise<int>::resolve(v0);
|
||||
auto p2 = QPromise<int>::resolve(v1);
|
||||
|
||||
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(p2), QPromise<int>>::value));
|
||||
|
||||
for (const auto& p : {p0, p1, p2}) {
|
||||
QCOMPARE(p.isFulfilled(), true);
|
||||
}
|
||||
for (const auto& p : {p0, p1, p2}) {
|
||||
QCOMPARE(waitForValue(p, -1), 42);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qpromise_resolve::noValue()
|
||||
{
|
||||
auto p = QPromise<void>::resolve();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
|
||||
QCOMPARE(p.isFulfilled(), true);
|
||||
QCOMPARE(waitForValue(p, -1, 42), 42);
|
||||
}
|
||||
|
||||
void tst_qpromise_resolve::moveRValue()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
{
|
||||
auto p = QtPromise::resolve(Data(42)).wait();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Data>>::value));
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 1);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
void tst_qpromise_resolve::copyLValue()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
{
|
||||
Data value(42);
|
||||
auto p = QtPromise::resolve(value).wait();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Data>>::value));
|
||||
}
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 1);
|
||||
QCOMPARE(Data::logs().copy, 1);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_qpromise_resolve::qtSharedPtr()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
QWeakPointer<Data> wptr;
|
||||
|
||||
{
|
||||
QSharedPointer<Data> sptr0(new Data(42));
|
||||
const QSharedPointer<Data> sptr1 = sptr0;
|
||||
|
||||
auto p0 = QPromise<QSharedPointer<Data>>::resolve(QSharedPointer<Data>(new Data(42)));
|
||||
auto p1 = QPromise<QSharedPointer<Data>>::resolve(sptr0);
|
||||
auto p2 = QPromise<QSharedPointer<Data>>::resolve(sptr1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<QSharedPointer<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<QSharedPointer<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<QSharedPointer<Data>>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p1, QSharedPointer<Data>()), sptr0);
|
||||
QCOMPARE(waitForValue(p2, QSharedPointer<Data>()), sptr1);
|
||||
|
||||
wptr = sptr0;
|
||||
|
||||
QCOMPARE(wptr.isNull(), false);
|
||||
QCOMPARE(Data::logs().refs, 2);
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.isNull(), true);
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 2);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_qpromise_resolve::stdSharedPtr()
|
||||
{
|
||||
Data::logs().reset();
|
||||
|
||||
std::weak_ptr<Data> wptr;
|
||||
|
||||
{
|
||||
std::shared_ptr<Data> sptr0(new Data(42));
|
||||
const std::shared_ptr<Data> sptr1 = sptr0;
|
||||
|
||||
auto p0 = QPromise<std::shared_ptr<Data>>::resolve(std::shared_ptr<Data>(new Data(42)));
|
||||
auto p1 = QPromise<std::shared_ptr<Data>>::resolve(sptr0);
|
||||
auto p2 = QPromise<std::shared_ptr<Data>>::resolve(sptr1);
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p0), QPromise<std::shared_ptr<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p1), QPromise<std::shared_ptr<Data>>>::value));
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p2), QPromise<std::shared_ptr<Data>>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p1, std::shared_ptr<Data>()), sptr0);
|
||||
QCOMPARE(waitForValue(p2, std::shared_ptr<Data>()), sptr1);
|
||||
|
||||
wptr = sptr0;
|
||||
|
||||
QCOMPARE(wptr.use_count(), 4l);
|
||||
QCOMPARE(Data::logs().refs, 2);
|
||||
}
|
||||
|
||||
QCOMPARE(wptr.use_count(), 0l);
|
||||
|
||||
QCOMPARE(Data::logs().ctor, 2);
|
||||
QCOMPARE(Data::logs().copy, 0);
|
||||
QCOMPARE(Data::logs().move, 0);
|
||||
QCOMPARE(Data::logs().refs, 0);
|
||||
}
|
@ -8,7 +8,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
# Additional warnings and make all warnings into errors
|
||||
# https://github.com/simonbrunel/qtpromise/issues/10
|
||||
gcc:QMAKE_CXXFLAGS += -Werror -Wold-style-cast
|
||||
msvc:QMAKE_CXXFLAGS -= -WX
|
||||
msvc:QMAKE_CXXFLAGS += -WX
|
||||
|
||||
coverage {
|
||||
gcc {
|
||||
@ -21,6 +21,7 @@ coverage {
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/shared/data.h \
|
||||
$$PWD/shared/object.h \
|
||||
$$PWD/shared/utils.h
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
benchmark \
|
||||
deprecations \
|
||||
exceptions \
|
||||
future \
|
||||
helpers \
|
||||
|
76
tests/auto/qtpromise/shared/data.h
Normal file
76
tests/auto/qtpromise/shared/data.h
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef QTPROMISE_TESTS_AUTO_SHARED_DATA_H
|
||||
#define QTPROMISE_TESTS_AUTO_SHARED_DATA_H
|
||||
|
||||
// STL
|
||||
#include <utility>
|
||||
|
||||
struct Logs {
|
||||
int ctor = 0;
|
||||
int copy = 0;
|
||||
int move = 0;
|
||||
int refs = 0;
|
||||
|
||||
void reset() {
|
||||
ctor = 0;
|
||||
copy = 0;
|
||||
move = 0;
|
||||
refs = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Logger
|
||||
{
|
||||
Logger() { logs().ctor++; logs().refs++; }
|
||||
Logger(const Logger&) { logs().copy++; logs().refs++; }
|
||||
Logger(Logger&&) { logs().move++; logs().refs++; }
|
||||
~Logger() { logs().refs--; }
|
||||
|
||||
Logger& operator=(const Logger&) { logs().copy++; return *this; }
|
||||
Logger& operator=(Logger&&) { logs().move++; return *this; }
|
||||
|
||||
public: // STATICS
|
||||
static Logs& logs() { static Logs logs; return logs; }
|
||||
};
|
||||
|
||||
struct Data : public Logger
|
||||
{
|
||||
Data(int v) : Logger(), m_value(v) {}
|
||||
int value() const { return m_value; }
|
||||
|
||||
// MSVC 2013 doesn't support implicit generation of the move constructor and
|
||||
// operator, so we need to explicitly define these methods and thus the copy
|
||||
// constructor and operator also need to be explicitly defined (error C2280).
|
||||
// https://stackoverflow.com/a/26581337
|
||||
|
||||
Data(const Data& other)
|
||||
: Logger(other)
|
||||
, m_value(other.m_value)
|
||||
{ }
|
||||
|
||||
Data(Data&& other) : Logger(std::forward<Data>(other))
|
||||
{
|
||||
std::swap(m_value, other.m_value);
|
||||
}
|
||||
|
||||
Data& operator=(const Data& other)
|
||||
{
|
||||
Logger::operator=(other);
|
||||
m_value = other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data& operator=(Data&& other)
|
||||
{
|
||||
Logger::operator=(std::forward<Data>(other));
|
||||
std::swap(m_value, other.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Data& other) const { return (m_value == other.m_value); }
|
||||
bool operator!=(const Data& other) const { return (m_value != other.m_value); }
|
||||
|
||||
private:
|
||||
int m_value;
|
||||
};
|
||||
|
||||
#endif // QTPROMISE_TESTS_AUTO_SHARED_DATA_H
|
@ -102,7 +102,7 @@ void tst_thread::then()
|
||||
|
||||
int value = -1;
|
||||
QThread* target = nullptr;
|
||||
qPromise(QtConcurrent::run([&](const QPromise<int>& p) {
|
||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<int>& p) {
|
||||
p.then([&](int res) {
|
||||
target = QThread::currentThread();
|
||||
value = res;
|
||||
@ -125,7 +125,7 @@ void tst_thread::then_void()
|
||||
|
||||
int value = -1;
|
||||
QThread* target = nullptr;
|
||||
qPromise(QtConcurrent::run([&](const QPromise<void>& p) {
|
||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<void>& p) {
|
||||
p.then([&]() {
|
||||
target = QThread::currentThread();
|
||||
value = 43;
|
||||
@ -148,7 +148,7 @@ void tst_thread::fail()
|
||||
|
||||
QString error;
|
||||
QThread* target = nullptr;
|
||||
qPromise(QtConcurrent::run([&](const QPromise<int>& p) {
|
||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<int>& p) {
|
||||
p.fail([&](const QString& err) {
|
||||
target = QThread::currentThread();
|
||||
error = err;
|
||||
@ -172,7 +172,7 @@ void tst_thread::finally()
|
||||
|
||||
int value = -1;
|
||||
QThread* target = nullptr;
|
||||
qPromise(QtConcurrent::run([&](const QPromise<int>& p) {
|
||||
QtPromise::resolve(QtConcurrent::run([&](const QPromise<int>& p) {
|
||||
p.finally([&]() {
|
||||
target = QThread::currentThread();
|
||||
value = 43;
|
||||
|
Loading…
Reference in New Issue
Block a user