Add QPromise assignment and equality operators

This commit is contained in:
Simon Brunel 2017-09-18 23:33:44 +02:00
parent d3b69f1248
commit d306423159
5 changed files with 249 additions and 7 deletions

View File

@ -16,18 +16,27 @@ class QPromiseBase
public: public:
using Type = T; using Type = T;
QPromiseBase(const QPromiseBase<T>& other): m_d(other.m_d) {}
QPromiseBase(const QPromise<T>& other): m_d(other.m_d) {}
QPromiseBase(QPromiseBase<T>&& other) { swap(other); }
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 != 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);
QPromiseBase(const QPromiseBase<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); }
virtual ~QPromiseBase() { } virtual ~QPromiseBase() { }
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>(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); }
void swap(QPromiseBase<T>& other) Q_DECL_NOEXCEPT { qSwap(m_d, other.m_d); }
bool isFulfilled() const { return m_d->isFulfilled(); } bool isFulfilled() const { return m_d->isFulfilled(); }
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(); }
@ -56,8 +65,6 @@ public:
inline QPromise<T> delay(int msec) const; inline QPromise<T> delay(int msec) const;
inline QPromise<T> wait() const; inline QPromise<T> wait() const;
void swap(QPromiseBase<T>& other) { qSwap(m_d, other.m_d); }
public: // STATIC public: // STATIC
template <typename E> template <typename E>
inline static QPromise<T> reject(E&& error); inline static QPromise<T> reject(E&& error);

View File

@ -36,7 +36,7 @@ public:
swap(other); swap(other);
} }
QPromiseError& operator =(QPromiseError other) QPromiseError& operator=(QPromiseError other)
{ {
swap(other); swap(other);
return *this; return *this;

View File

@ -0,0 +1,4 @@
TARGET = tst_qpromise_operators
SOURCES += $$PWD/tst_operators.cpp
include(../../qtpromise.pri)

View File

@ -0,0 +1,230 @@
// Tests
#include "../../shared/utils.h"
// QtPromise
#include <QtPromise>
// Qt
#include <QtTest>
using namespace QtPromise;
class tst_qpromise_operators : public QObject
{
Q_OBJECT
private Q_SLOTS:
void move();
void move_void();
void copy();
void copy_void();
void equalTo();
void equalTo_void();
void notEqualTo();
void notEqualTo_void();
void chaining();
void chaining_void();
};
QTEST_MAIN(tst_qpromise_operators)
#include "tst_operators.moc"
void tst_qpromise_operators::move()
{
auto p0 = QPromise<int>::resolve(42);
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(waitForValue(p0, -1), 42);
p0 = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
QCOMPARE(p0.isPending(), true);
QCOMPARE(waitForError(p0, QString()), QString("foo"));
p0 = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(43);
});
});
QCOMPARE(p0.isPending(), true);
QCOMPARE(waitForValue(p0, -1), 43);
}
void tst_qpromise_operators::move_void()
{
auto p0 = QPromise<void>::resolve();
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(waitForValue(p0, -1, 42), 42);
p0 = QPromise<void>([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
QCOMPARE(p0.isPending(), true);
QCOMPARE(waitForError(p0, QString()), QString("foo"));
p0 = QPromise<void>([](const QPromiseResolve<void>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve();
});
});
QCOMPARE(p0.isPending(), true);
QCOMPARE(waitForValue(p0, -1, 43), 43);
}
void tst_qpromise_operators::copy()
{
auto p0 = QPromise<int>([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
auto p1 = QPromise<int>([](const QPromiseResolve<int>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve(42);
});
});
QCOMPARE(p0 == p1, false);
QCOMPARE(p0.isPending(), true);
QCOMPARE(p1.isPending(), true);
p0 = p1;
QCOMPARE(p0 == p1, true);
QCOMPARE(p0.isPending(), true);
QCOMPARE(p1.isPending(), true);
QCOMPARE(waitForValue(p0, -1), 42);
QCOMPARE(waitForValue(p1, -1), 42);
}
void tst_qpromise_operators::copy_void()
{
auto p0 = QPromise<void>([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
QtPromisePrivate::qtpromise_defer([=]() {
reject(QString("foo"));
});
});
auto p1 = QPromise<void>([](const QPromiseResolve<void>& resolve) {
QtPromisePrivate::qtpromise_defer([=]() {
resolve();
});
});
QCOMPARE(p0 == p1, false);
QCOMPARE(p0.isPending(), true);
QCOMPARE(p1.isPending(), true);
p0 = p1;
QCOMPARE(p0 == p1, true);
QCOMPARE(p0.isPending(), true);
QCOMPARE(p1.isPending(), true);
p0.wait();
QCOMPARE(p0.isFulfilled(), true);
QCOMPARE(p1.isFulfilled(), true);
}
void tst_qpromise_operators::equalTo()
{
auto p0 = QPromise<int>::resolve(42);
auto p1 = QPromise<int>::resolve(42);
auto p2 = p1;
auto p3(p2);
QCOMPARE(p0 == p1, false);
QCOMPARE(p0 == p2, false);
QCOMPARE(p0 == p3, false);
QCOMPARE(p1 == p2, true);
QCOMPARE(p1 == p3, true);
QCOMPARE(p2 == p3, true);
}
void tst_qpromise_operators::equalTo_void()
{
auto p0 = QPromise<void>::resolve();
auto p1 = QPromise<void>::resolve();
auto p2 = p1;
auto p3(p2);
QCOMPARE(p0 == p1, false);
QCOMPARE(p0 == p2, false);
QCOMPARE(p0 == p3, false);
QCOMPARE(p1 == p2, true);
QCOMPARE(p1 == p3, true);
QCOMPARE(p2 == p3, true);
}
void tst_qpromise_operators::notEqualTo()
{
auto p0 = QPromise<int>::resolve(42);
auto p1 = QPromise<int>::resolve(42);
auto p2 = p1;
auto p3(p2);
QCOMPARE(p0 != p1, true);
QCOMPARE(p0 != p2, true);
QCOMPARE(p0 != p3, true);
QCOMPARE(p1 != p2, false);
QCOMPARE(p1 != p3, false);
QCOMPARE(p2 != p3, false);
}
void tst_qpromise_operators::notEqualTo_void()
{
auto p0 = QPromise<void>::resolve();
auto p1 = QPromise<void>::resolve();
auto p2 = p1;
auto p3(p2);
QCOMPARE(p0 != p1, true);
QCOMPARE(p0 != p2, true);
QCOMPARE(p0 != p3, true);
QCOMPARE(p1 != p2, false);
QCOMPARE(p1 != p3, false);
QCOMPARE(p2 != p3, false);
}
void tst_qpromise_operators::chaining()
{
auto p = QPromise<int>::resolve(1);
for (int i=0; i<4; ++i) {
p = p.then([](int res) {
return QPromise<int>::resolve(res * 2);
});
}
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForValue(p, -1), 16);
}
void tst_qpromise_operators::chaining_void()
{
QVector<int> values;
auto p = QPromise<void>::resolve();
for (int i=0; i<4; ++i) {
p = p.then([i, &values]() {
values.append(i * 2);
return QPromise<void>::resolve();
});
}
QCOMPARE(p.isPending(), true);
QCOMPARE(waitForValue(p, -1, 42), 42);
QCOMPARE(values, QVector<int>({0, 2, 4, 6}));
}

View File

@ -4,6 +4,7 @@ SUBDIRS += \
delay \ delay \
fail \ fail \
finally \ finally \
operators \
tap \ tap \
then \ then \
timeout timeout