mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2024-11-22 02:34:30 +08:00
Implement QPromise<T>::convert<U>() (#41)
Converts the resolved value of `QPromise<T>` to the type `U`. Depending on types `T` and `U`, it performs a static cast, calls a converting constructor or tries to convert using `QVariant`.
This commit is contained in:
parent
60b36e7a70
commit
0c3955cca5
@ -40,6 +40,7 @@ module.exports = {
|
||||
title: 'QPromise',
|
||||
children: [
|
||||
'/qtpromise/qpromise/constructor',
|
||||
'/qtpromise/qpromise/convert',
|
||||
'/qtpromise/qpromise/delay',
|
||||
'/qtpromise/qpromise/each',
|
||||
'/qtpromise/qpromise/fail',
|
||||
@ -77,6 +78,7 @@ module.exports = {
|
||||
children: [
|
||||
'/qtpromise/exceptions/canceled',
|
||||
'/qtpromise/exceptions/context',
|
||||
'/qtpromise/exceptions/conversion',
|
||||
'/qtpromise/exceptions/timeout',
|
||||
'/qtpromise/exceptions/undefined'
|
||||
]
|
||||
|
@ -3,6 +3,7 @@
|
||||
## Functions
|
||||
|
||||
- [`QPromise<T>::QPromise`](qpromise/constructor.md)
|
||||
- [`QPromise<T>::convert`](qpromise/convert.md)
|
||||
- [`QPromise<T>::delay`](qpromise/delay.md)
|
||||
- [`QPromise<T>::each`](qpromise/each.md)
|
||||
- [`QPromise<T>::fail`](qpromise/fail.md)
|
||||
@ -39,6 +40,7 @@
|
||||
|
||||
- [`QPromiseCanceledException`](exceptions/canceled.md)
|
||||
- [`QPromiseContextException`](exceptions/context.md)
|
||||
- [`QPromiseConversionException`](exceptions/conversion.md)
|
||||
- [`QPromiseTimeoutException`](exceptions/timeout.md)
|
||||
- [`QPromiseUndefinedException`](exceptions/undefined.md)
|
||||
|
||||
|
13
docs/qtpromise/exceptions/conversion.md
Normal file
13
docs/qtpromise/exceptions/conversion.md
Normal file
@ -0,0 +1,13 @@
|
||||
# QPromiseConversionException
|
||||
|
||||
*Since: 0.7.0*
|
||||
|
||||
This exception is thrown whenever a promise result conversion fails, for example:
|
||||
|
||||
```cpp
|
||||
QPromise<QVariant> input = {...};
|
||||
auto output = input.convert<int>()
|
||||
.fail([](const QPromiseconversionException& e) {
|
||||
// conversion may fail because input could not be converted to number
|
||||
});
|
||||
```
|
124
docs/qtpromise/qpromise/convert.md
Normal file
124
docs/qtpromise/qpromise/convert.md
Normal file
@ -0,0 +1,124 @@
|
||||
---
|
||||
title: .convert
|
||||
---
|
||||
|
||||
# QPromise::convert
|
||||
|
||||
*Since: 0.7.0*
|
||||
|
||||
```cpp
|
||||
QPromise<T>::convert<U>() -> QPromise<U>
|
||||
```
|
||||
|
||||
This method converts the resolved value of `QPromise<T>` to the type `U`. Depending on types `T`
|
||||
and `U`, it performs a [static cast](https://en.cppreference.com/w/cpp/language/static_cast),
|
||||
calls a [converting constructor](https://en.cppreference.com/w/cpp/language/converting_constructor),
|
||||
or tries to convert using [QVariant](https://doc.qt.io/qt-5/qvariant.html).
|
||||
|
||||
If `T` and `U` are [fundamental types](https://en.cppreference.com/w/cpp/language/types) or
|
||||
[enumerations](https://en.cppreference.com/w/cpp/language/enum), the result of the conversion is
|
||||
the same as calling `static_cast<U>` for type `T`:
|
||||
|
||||
```cpp
|
||||
QPromise<int> input = {...}
|
||||
|
||||
// output type: QPromise<double>
|
||||
auto output = input.convert<double>();
|
||||
|
||||
output.then([](double value) {
|
||||
// the value has been converted using static_cast
|
||||
});
|
||||
```
|
||||
|
||||
If `U` has a [converting constructor](https://en.cppreference.com/w/cpp/language/converting_constructor)
|
||||
from `T`, i.e., a non-explicit constructor with a single argument accepting `T`, it is used to
|
||||
convert the value:
|
||||
|
||||
```cpp
|
||||
QPromise<QByteArray> input = {...}
|
||||
|
||||
// output type: QPromise<QString>
|
||||
auto output = input.convert<QString>();
|
||||
|
||||
output.then([](const QString& value) {
|
||||
// the value has been converted using static_cast that effectively calls QString(QByteArray)
|
||||
});
|
||||
```
|
||||
|
||||
::: tip NOTE
|
||||
When using this method to convert to your own classes, make sure that the constructor meeting the
|
||||
converting constructor criteria actually performs conversion.
|
||||
:::
|
||||
|
||||
::: tip NOTE
|
||||
If `U` is `void`, the resolved value of `QPromise<T>` is dropped.
|
||||
:::
|
||||
|
||||
Calling this method for `QPromise<QVariant>` tries to convert the resolved `QVariant` to type `U`
|
||||
using the `QVariant` [conversion algorithm](https://doc.qt.io/qt-5/qvariant.html#using-canconvert-and-convert-consecutively).
|
||||
For example, this allows to convert a string contained in `QVariant` to number. If such a
|
||||
conversion fails, the promise is rejected with
|
||||
[`QPromiseConversionException`](../exceptions/conversion.md).
|
||||
|
||||
```cpp
|
||||
// resolves to QVariant(int, 42) or QVariant(string, "foo")
|
||||
QPromise<QVariant> input = {...};
|
||||
|
||||
auto output = input.convert<int>();
|
||||
|
||||
// output type: QPromise<int>
|
||||
output.then([](int value) {
|
||||
// input was QVariant(int, 42), value is 42
|
||||
})
|
||||
.fail(const QPromiseConversionException& e) {
|
||||
// input was QVariant(string, "foo")
|
||||
});
|
||||
```
|
||||
|
||||
Conversion of `T` to `QVariant` using this method effectively calls `QVariant::fromValue<T>()`.
|
||||
All custom types must be registered with
|
||||
[`Q_DECLARE_METATYPE`](https://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE) for this
|
||||
conversion to work:
|
||||
|
||||
```cpp
|
||||
struct Foo {};
|
||||
Q_DECLARE_METATYPE(Foo);
|
||||
|
||||
QPromise<Foo> input = {...}
|
||||
|
||||
auto output = input.convert<QVariant>();
|
||||
|
||||
// output type: QPromise<QVariant>
|
||||
output.then([](const QVariant& value) {
|
||||
// value contains an instance of Foo
|
||||
});
|
||||
```
|
||||
|
||||
All other combinations of `T` and `U` are converted via `QVariant`. All non-Qt types should provide
|
||||
a [conversion function](https://doc.qt.io/qt-5/qmetatype.html#registerConverter), otherwise the
|
||||
promise is rejected with [`QPromiseConversionException`](../exceptions/conversion.md):
|
||||
|
||||
```cpp
|
||||
struct Foo {};
|
||||
Q_DECLARE_METATYPE(Foo);
|
||||
|
||||
QMetaType::registerConverter<Foo, QString>([](const Foo& foo) {
|
||||
return QString{...};
|
||||
});
|
||||
|
||||
QPromise<Foo> input = {...}
|
||||
|
||||
auto output = input.convert<QVariant>();
|
||||
|
||||
// output type: QPromise<QString>
|
||||
output.then([](const QString& value) {
|
||||
// value contains a result produced by the custom converter
|
||||
})
|
||||
.fail([](const QPromiseConversionException& e) {
|
||||
// QVariant was unable to convert Foo to QString
|
||||
})
|
||||
```
|
||||
|
||||
::: warning IMPORTANT
|
||||
Calling this method for `QPromise<void>` is not supported.
|
||||
:::
|
@ -111,6 +111,9 @@ public:
|
||||
QPromise(F&& resolver) : QPromiseBase<T>(std::forward<F>(resolver))
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
inline QPromise<U> convert() const;
|
||||
|
||||
template<typename Functor>
|
||||
inline QPromise<T> each(Functor fn);
|
||||
|
||||
|
@ -242,6 +242,13 @@ inline QPromise<QVector<T>> QPromise<T>::all(const Sequence<QPromise<T>, Args...
|
||||
return QtPromise::all(promises);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
inline QPromise<U> QPromise<T>::convert() const
|
||||
{
|
||||
return QPromiseBase<T>::then(QtPromisePrivate::PromiseConverter<T, U>::create());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline QPromise<T> QPromise<T>::resolve(const T& value)
|
||||
{
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <QtCore/QSharedData>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
namespace QtPromise {
|
||||
@ -30,6 +31,8 @@ class QPromiseResolve;
|
||||
template<typename T>
|
||||
class QPromiseReject;
|
||||
|
||||
class QPromiseConversionException;
|
||||
|
||||
} // namespace QtPromise
|
||||
|
||||
namespace QtPromisePrivate {
|
||||
@ -553,6 +556,63 @@ struct PromiseInspect
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename U, bool IsConvertibleViaStaticCast>
|
||||
struct PromiseConverterBase;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct PromiseConverterBase<T, U, true>
|
||||
{
|
||||
static std::function<U(const T&)> create()
|
||||
{
|
||||
return [](const T& value) {
|
||||
return static_cast<U>(value);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct PromiseConverterBase<T, U, false>
|
||||
{
|
||||
static std::function<U(const T&)> create()
|
||||
{
|
||||
return [](const T& value) {
|
||||
auto tmp = QVariant::fromValue(value);
|
||||
|
||||
// https://doc.qt.io/qt-5/qvariant.html#using-canconvert-and-convert-consecutively
|
||||
if (tmp.canConvert(qMetaTypeId<U>()) && tmp.convert(qMetaTypeId<U>())) {
|
||||
return qvariant_cast<U>(tmp);
|
||||
}
|
||||
|
||||
throw QtPromise::QPromiseConversionException{};
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct PromiseConverterBase<T, QVariant, false>
|
||||
{
|
||||
static std::function<QVariant(const T&)> create()
|
||||
{
|
||||
return [](const T& value) {
|
||||
return QVariant::fromValue(value);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct PromiseConverter
|
||||
: PromiseConverterBase<T,
|
||||
U,
|
||||
// Fundamental types and converting constructors.
|
||||
std::is_convertible<T, U>::value ||
|
||||
// Conversion to void.
|
||||
std::is_same<U, void>::value ||
|
||||
// Conversion between enums and arithmetic types.
|
||||
((std::is_enum<T>::value && std::is_arithmetic<U>::value)
|
||||
|| (std::is_arithmetic<T>::value && std::is_enum<U>::value)
|
||||
|| (std::is_enum<T>::value && std::is_enum<U>::value))>
|
||||
{ };
|
||||
|
||||
} // namespace QtPromisePrivate
|
||||
|
||||
#endif // QTPROMISE_QPROMISE_H
|
||||
|
@ -35,6 +35,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class QPromiseConversionException : public QException
|
||||
{
|
||||
public:
|
||||
void raise() const Q_DECL_OVERRIDE { throw *this; }
|
||||
QPromiseConversionException* clone() const Q_DECL_OVERRIDE
|
||||
{
|
||||
return new QPromiseConversionException{*this};
|
||||
}
|
||||
};
|
||||
|
||||
class QPromiseTimeoutException : public QException
|
||||
{
|
||||
public:
|
||||
|
@ -20,6 +20,7 @@ class tst_exceptions : public QObject
|
||||
private Q_SLOTS:
|
||||
void canceled();
|
||||
void context();
|
||||
void conversion();
|
||||
void timeout();
|
||||
void undefined();
|
||||
|
||||
@ -53,6 +54,11 @@ void tst_exceptions::context()
|
||||
verify<QPromiseContextException>();
|
||||
}
|
||||
|
||||
void tst_exceptions::conversion()
|
||||
{
|
||||
verify<QPromiseConversionException>();
|
||||
}
|
||||
|
||||
void tst_exceptions::timeout()
|
||||
{
|
||||
verify<QPromiseTimeoutException>();
|
||||
|
@ -1,6 +1,7 @@
|
||||
qtpromise_add_tests(qpromise
|
||||
SOURCES
|
||||
tst_construct.cpp
|
||||
tst_convert.cpp
|
||||
tst_delay.cpp
|
||||
tst_each.cpp
|
||||
tst_fail.cpp
|
||||
|
266
tests/auto/qtpromise/qpromise/tst_convert.cpp
Normal file
266
tests/auto/qtpromise/qpromise/tst_convert.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (c) Simon Brunel, https://github.com/simonbrunel
|
||||
*
|
||||
* This source code is licensed under the MIT license found in
|
||||
* the LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "../shared/utils.h"
|
||||
|
||||
#include <QtPromise>
|
||||
#include <QtTest>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
using namespace QtPromise;
|
||||
|
||||
class tst_qpromise_convert : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void fulfillTAsU();
|
||||
void fulfillTAsVoid();
|
||||
void fulfillTAsQVariant();
|
||||
void fulfillQVariantAsU();
|
||||
void fulfillQVariantAsVoid();
|
||||
|
||||
void rejectUnconvertibleTypes();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_qpromise_convert)
|
||||
#include "tst_convert.moc"
|
||||
|
||||
namespace {
|
||||
struct Foo
|
||||
{
|
||||
Foo() = default;
|
||||
Foo(int foo) : m_foo{foo} { }
|
||||
|
||||
bool operator==(const Foo& rhs) const { return m_foo == rhs.m_foo; }
|
||||
|
||||
int m_foo{-1};
|
||||
};
|
||||
|
||||
struct Bar
|
||||
{
|
||||
Bar() = default;
|
||||
Bar(const Foo& other) : m_bar{other.m_foo} { }
|
||||
|
||||
bool operator==(const Bar& rhs) const { return m_bar == rhs.m_bar; }
|
||||
|
||||
int m_bar{-1};
|
||||
};
|
||||
|
||||
enum class Enum1 { Value0, Value1, Value2 };
|
||||
enum class Enum2 { Value0, Value1, Value2 };
|
||||
} // namespace
|
||||
|
||||
Q_DECLARE_METATYPE(Foo)
|
||||
Q_DECLARE_METATYPE(Bar)
|
||||
|
||||
void tst_qpromise_convert::initTestCase()
|
||||
{
|
||||
// Register converter used by QVariant.
|
||||
// https://doc.qt.io/qt-5/qmetatype.html#registerConverter
|
||||
QMetaType::registerConverter<Foo, QString>([](const Foo& foo) {
|
||||
return QString{"Foo{%1}"}.arg(foo.m_foo);
|
||||
});
|
||||
}
|
||||
|
||||
void tst_qpromise_convert::fulfillTAsU()
|
||||
{
|
||||
// Static cast between primitive types.
|
||||
{
|
||||
auto p = QtPromise::resolve(42.13).convert<int>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, -1), 42);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Convert enum class to int.
|
||||
{
|
||||
auto p = QtPromise::resolve(Enum1::Value1).convert<int>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, -1), 1);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Convert int to enum class.
|
||||
{
|
||||
auto p = QtPromise::resolve(1).convert<Enum1>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Enum1>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, Enum1::Value0), Enum1::Value1);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Convert between enums
|
||||
{
|
||||
auto p = QtPromise::resolve(Enum1::Value1).convert<Enum2>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Enum2>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, Enum2::Value0), Enum2::Value1);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Converting constructor for Qt types.
|
||||
// https://en.cppreference.com/w/cpp/language/converting_constructor
|
||||
{
|
||||
auto p = QtPromise::resolve(QByteArray{"foo"}).convert<QString>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, QString{}), QString{"foo"});
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Converting constructor for non-Qt types.
|
||||
// https://en.cppreference.com/w/cpp/language/converting_constructor
|
||||
{
|
||||
auto p = QtPromise::resolve(Foo{42}).convert<Bar>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Bar>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, Bar{}), Bar{42});
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Conversion of types Qt is aware of via QVariant.
|
||||
{
|
||||
auto p = QtPromise::resolve(42).convert<QString>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, QString{}), QString{"42"});
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Conversion of a non-Qt type via QVariant.
|
||||
// https://doc.qt.io/qt-5/qmetatype.html#registerConverter
|
||||
{
|
||||
auto p = QtPromise::resolve(Foo{42}).convert<QString>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, QString{}), QString{"Foo{42}"});
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qpromise_convert::fulfillTAsVoid()
|
||||
{
|
||||
auto p = QtPromise::resolve(42).convert<void>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, -1, 42), 42);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
void tst_qpromise_convert::fulfillTAsQVariant()
|
||||
{
|
||||
// Primitive type to QVariant.
|
||||
{
|
||||
auto p = QtPromise::resolve(42).convert<QVariant>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVariant>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, QVariant{}), QVariant{42});
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Non-Qt user-defined type to QVariant.
|
||||
{
|
||||
auto p = QtPromise::resolve(Foo{42}).convert<QVariant>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QVariant>>::value));
|
||||
|
||||
QVariant value = waitForValue(p, QVariant{});
|
||||
QCOMPARE(value, QVariant::fromValue(Foo{42}));
|
||||
QCOMPARE(value.value<Foo>().m_foo, 42);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qpromise_convert::fulfillQVariantAsU()
|
||||
{
|
||||
// Test whether a directly stored value can be extracted.
|
||||
{
|
||||
auto p = QtPromise::resolve(QVariant{42}).convert<int>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, -1), 42);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Test automatic conversion from string performed by QVariant.
|
||||
// https://doc.qt.io/qt-5/qvariant.html#toInt
|
||||
{
|
||||
auto p = QtPromise::resolve(QVariant{"42"}).convert<int>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, -1), 42);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
// Non-Qt user-defined type
|
||||
{
|
||||
auto p = QtPromise::resolve(QVariant::fromValue(Foo{42})).convert<Foo>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<Foo>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, Foo{}), Foo{42});
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qpromise_convert::fulfillQVariantAsVoid()
|
||||
{
|
||||
auto p = QtPromise::resolve(QVariant{42}).convert<void>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<void>>::value));
|
||||
|
||||
QCOMPARE(waitForValue(p, -1, 42), 42);
|
||||
QVERIFY(p.isFulfilled());
|
||||
}
|
||||
|
||||
void tst_qpromise_convert::rejectUnconvertibleTypes()
|
||||
{
|
||||
// A string incompatible with int due to its value.
|
||||
{
|
||||
auto p = QtPromise::resolve(QString{"42foo"}).convert<int>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
||||
QVERIFY(waitForRejected<QPromiseConversionException>(p));
|
||||
}
|
||||
|
||||
// A user-defined type unconvertible to string because there is no converter.
|
||||
{
|
||||
auto p = QtPromise::resolve(QVariant::fromValue(Bar{42})).convert<QString>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<QString>>::value));
|
||||
|
||||
QVERIFY(waitForRejected<QPromiseConversionException>(p));
|
||||
}
|
||||
|
||||
// A standard library type unconvertible to a primitive type because there is no converter.
|
||||
{
|
||||
auto p = QtPromise::resolve(std::vector<int>{42, -42}).convert<int>();
|
||||
|
||||
Q_STATIC_ASSERT((std::is_same<decltype(p), QPromise<int>>::value));
|
||||
|
||||
QVERIFY(waitForRejected<QPromiseConversionException>(p));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user