mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2024-11-22 02:34:30 +08:00
- wip -
- wip -
This commit is contained in:
parent
26a2110a14
commit
5523597e7c
@ -23,6 +23,9 @@ public:
|
||||
template <typename F, typename std::enable_if<QtPromisePrivate::ArgsOf<F>::count != 1, int>::type = 0>
|
||||
inline QPromiseBase(F resolver);
|
||||
|
||||
template <typename U>
|
||||
inline QPromiseBase(const QPromise<U>& other);
|
||||
|
||||
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); }
|
||||
@ -94,6 +97,9 @@ public: // STATIC
|
||||
inline static QPromise<T> resolve(const T& value);
|
||||
inline static QPromise<T> resolve(T&& value);
|
||||
|
||||
template <typename U>
|
||||
operator QPromise<U>();
|
||||
|
||||
private:
|
||||
friend class QPromiseBase<T>;
|
||||
};
|
||||
@ -105,6 +111,9 @@ public:
|
||||
template <typename F>
|
||||
QPromise(F&& resolver): QPromiseBase<void>(std::forward<F>(resolver)) { }
|
||||
|
||||
template <typename T>
|
||||
QPromise(const QPromise<T>& other);
|
||||
|
||||
public: // STATIC
|
||||
template <template <typename, typename...> class Sequence = QVector, typename ...Args>
|
||||
inline static QPromise<void> all(const Sequence<QPromise<void>, Args...>& promises);
|
||||
|
@ -74,6 +74,19 @@ inline QPromiseBase<T>::QPromiseBase(F callback)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
inline QPromiseBase<T>::QPromiseBase(const QPromise<U>& other)
|
||||
: m_d(new QtPromisePrivate::PromiseData<T>())
|
||||
{
|
||||
using namespace QtPromisePrivate;
|
||||
|
||||
QPromiseResolve<T> resolve(*this);
|
||||
QPromiseReject<T> reject(*this);
|
||||
|
||||
PromiseFulfill<QPromise<U> >::call(other, PromiseCast<U, T>::apply(resolve), reject);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename TFulfilled, typename TRejected>
|
||||
inline typename QtPromisePrivate::PromiseHandler<T, TFulfilled>::Promise
|
||||
@ -244,6 +257,21 @@ inline QPromise<T> QPromise<T>::resolve(T&& value)
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
QPromise<T>::operator QPromise<U>()
|
||||
{
|
||||
return QPromise<U>::resolve(U());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QPromise<void>::QPromise(const QPromise<T>& other)
|
||||
: QPromiseBase<void>([&](const QPromiseResolve<void>& resolve, const QPromiseReject<void>& reject) {
|
||||
QtPromisePrivate::PromiseFulfill<QPromise<T> >::call(other, resolve, reject);
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
template <template <typename, typename...> class Sequence, typename ...Args>
|
||||
inline QPromise<void> QPromise<void>::all(const Sequence<QPromise<void>, Args...>& promises)
|
||||
{
|
||||
|
@ -122,10 +122,8 @@ struct PromiseDeduce<QtPromise::QPromise<T>>
|
||||
template <typename T>
|
||||
struct PromiseFulfill
|
||||
{
|
||||
static void call(
|
||||
T&& value,
|
||||
const QtPromise::QPromiseResolve<T>& resolve,
|
||||
const QtPromise::QPromiseReject<T>&)
|
||||
template <typename TResolve, typename TReject>
|
||||
static void call(T&& value, const TResolve& resolve, const TReject&)
|
||||
{
|
||||
resolve(std::move(value));
|
||||
}
|
||||
@ -134,10 +132,11 @@ struct PromiseFulfill
|
||||
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());
|
||||
@ -156,9 +155,9 @@ struct PromiseFulfill<QtPromise::QPromise<T>>
|
||||
template <>
|
||||
struct PromiseFulfill<QtPromise::QPromise<void>>
|
||||
{
|
||||
template <typename TPromise, typename TResolve, typename TReject>
|
||||
template <typename TResolve, typename TReject>
|
||||
static void call(
|
||||
const TPromise& promise,
|
||||
const QtPromise::QPromise<void>& promise,
|
||||
const TResolve& resolve,
|
||||
const TReject& reject)
|
||||
{
|
||||
@ -397,6 +396,67 @@ struct PromiseCatcher<T, std::nullptr_t, void>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct PromiseCast
|
||||
{
|
||||
template <typename F>
|
||||
static auto apply(const F& resolve)
|
||||
{
|
||||
return [=](const QSharedPointer<T>& value) {
|
||||
resolve(static_cast<T>(*value));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PromiseCast<T, void>
|
||||
{
|
||||
template <typename F>
|
||||
static auto apply(const F& resolve)
|
||||
{
|
||||
return [=](const QSharedPointer<T>&) {
|
||||
resolve();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <typename T>
|
||||
struct PromiseCast<T, QVariant>
|
||||
{
|
||||
static QtPromise::QPromise<QVariant> cast(
|
||||
const QtPromise::QPromiseBase<T>& input)
|
||||
{
|
||||
return input.then([](const T& res) {
|
||||
return QVariant::fromValue(res);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
struct PromiseCast<QVariant, U>
|
||||
{
|
||||
static QtPromise::QPromise<U> cast(
|
||||
const QtPromise::QPromiseBase<QVariant>& input)
|
||||
{
|
||||
return input.then([](const QVariant& res) {
|
||||
return res.value<U>();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct PromiseCast<void, QVariant>
|
||||
{
|
||||
static QtPromise::QPromise<void> cast(
|
||||
const QtPromise::QPromiseBase<QVariant>& input)
|
||||
{
|
||||
return input.then([]() {
|
||||
});
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
template <typename T> class PromiseData;
|
||||
|
||||
template <typename T, typename F>
|
||||
@ -626,4 +686,4 @@ private:
|
||||
|
||||
} // namespace QtPromise
|
||||
|
||||
#endif // ifndef QTPROMISE_QPROMISE_H
|
||||
#endif // ifndef QTPROMISE_QPROMISE_P_H
|
||||
|
4
tests/auto/qtpromise/qpromise/cast/cast.pro
Normal file
4
tests/auto/qtpromise/qpromise/cast/cast.pro
Normal file
@ -0,0 +1,4 @@
|
||||
TARGET = tst_qpromise_cast
|
||||
SOURCES += $$PWD/tst_cast.cpp
|
||||
|
||||
include(../../qtpromise.pri)
|
135
tests/auto/qtpromise/qpromise/cast/tst_cast.cpp
Normal file
135
tests/auto/qtpromise/qpromise/cast/tst_cast.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
// Tests
|
||||
#include "../../shared/utils.h"
|
||||
|
||||
// QtPromise
|
||||
#include <QtPromise>
|
||||
|
||||
// Qt
|
||||
#include <QtTest>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_qpromise_cast : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void typeToVoid();
|
||||
|
||||
|
||||
//void castToVoidOperator();
|
||||
//void typeToVariant(); // QPromise<T>.cast<QVariant>()
|
||||
//void variantToType();
|
||||
//void voidToVariant(); // QPromise<void>.cast<QVariant>()
|
||||
//void variantToVoid();
|
||||
|
||||
//void jsonValueToJsonObject();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_qpromise_cast)
|
||||
#include "tst_cast.moc"
|
||||
|
||||
void tst_qpromise_cast::typeToVoid()
|
||||
{
|
||||
QPromise<void> p0 = QPromise<int>::resolve(42);
|
||||
QPromise<void> p1 = QPromise<QString>::resolve(QString("foo"));
|
||||
QVERIFY(p0.isFulfilled());
|
||||
QVERIFY(p1.isFulfilled());
|
||||
}
|
||||
|
||||
//void tst_qpromise_cast::castToVoidOperator()
|
||||
//{
|
||||
//auto p0 = QPromise<int>::resolve(42);
|
||||
//QPromise<double> p1(p0);
|
||||
//QPromise<void> p2(p0);
|
||||
//auto p4 = QPromise<QString>::resolve("foo");
|
||||
//
|
||||
//p0.then([](int res) { qDebug() << res; });
|
||||
//p1.then([](double res) { qDebug() << res; });
|
||||
//p2.then([]() { qDebug() << "done"; });
|
||||
//
|
||||
//foo().then([]() {
|
||||
// qDebug() << "done";
|
||||
//}).wait();
|
||||
//
|
||||
//QPromise<QVariant>::all({p0, p1, p4}).then([](const QVector<QVariant>& res) {
|
||||
// qDebug() << "all done!" << res;
|
||||
//}).wait();
|
||||
//}
|
||||
|
||||
/*
|
||||
namespace {
|
||||
|
||||
template <typename T, typename U>
|
||||
void test_qpromise_cast(const T& t, const U& u)
|
||||
{
|
||||
auto p = QPromise<T>::resolve(t).cast<U>();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<U> >::value));
|
||||
QCOMPARE(waitForValue(p, U()), u);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void test_qpromise_cast(const U& u)
|
||||
{
|
||||
auto p = QPromise<void>::resolve().cast<U>();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<U> >::value));
|
||||
QCOMPARE(waitForValue(p, U()), u);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
void tst_qpromise_cast::typeToVariant()
|
||||
{
|
||||
test_qpromise_cast(42, QVariant(42));
|
||||
test_qpromise_cast(4.2, QVariant(4.2));
|
||||
test_qpromise_cast(true, QVariant(true));
|
||||
test_qpromise_cast(QString("foo"), QVariant(QString("foo")));
|
||||
test_qpromise_cast(QUrl("http://x.y.z"), QVariant(QUrl("http://x.y.z")));
|
||||
test_qpromise_cast(QSize(128, 256), QVariant(QSize(128, 256)));
|
||||
test_qpromise_cast(QDate(2018, 1, 1), QVariant(QDate(2018, 1, 1)));
|
||||
test_qpromise_cast(QJsonValue("foo"), QVariant(QJsonValue("foo")));
|
||||
test_qpromise_cast(QStringList{"foo", "bar"}, QVariant(QStringList{"foo", "bar"}));
|
||||
test_qpromise_cast(QList<QVariant>{"foo", 42}, QVariant(QList<QVariant>{"foo", 42}));
|
||||
test_qpromise_cast(QMap<QString, QVariant>{{"foo", 42}}, QVariant(QVariantMap{{"foo", 42}}));
|
||||
}
|
||||
|
||||
void tst_qpromise_cast::voidToVariant()
|
||||
{
|
||||
test_qpromise_cast(QVariant());
|
||||
}
|
||||
|
||||
void tst_qpromise_cast::variantToType()
|
||||
{
|
||||
// invalid
|
||||
// int
|
||||
// QString
|
||||
// QColor
|
||||
// QList
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void tst_qpromise_cast::jsonValueToJsonObject()
|
||||
{
|
||||
{ // QJsonValue(Null) -> QJsonObject
|
||||
auto p = QPromise<QJsonValue>::resolve(QJsonValue()).cast<QJsonObject>();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QJsonObject> >::value));
|
||||
const QJsonObject res = waitForValue(p, QJsonObject());
|
||||
QVERIFY(res.isEmpty());
|
||||
}
|
||||
{ // QJsonValue(int) -> QJsonObject
|
||||
auto p = QPromise<QJsonValue>::resolve(QJsonValue(42)).cast<QJsonObject>();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QJsonObject> >::value));
|
||||
const QJsonObject res = waitForValue(p, QJsonObject());
|
||||
QVERIFY(res.isEmpty());
|
||||
}
|
||||
{ // QJsonValue(QJsonObject) -> QJsonObject
|
||||
const QJsonObject object{{"magic", 42}};
|
||||
auto p = QPromise<QJsonValue>::resolve(QJsonValue(object)).cast<QJsonObject>();
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QJsonObject> >::value));
|
||||
const QJsonObject res = waitForValue(p, QJsonObject());
|
||||
QCOMPARE(res.value("magic"), 42);
|
||||
}
|
||||
}
|
||||
*/
|
@ -1,6 +1,7 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += \
|
||||
all \
|
||||
cast \
|
||||
construct \
|
||||
delay \
|
||||
fail \
|
||||
|
Loading…
Reference in New Issue
Block a user