aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2023-01-28 17:08:05 +0100
committerLinus Jahn <lnj@kaidan.im>2023-01-28 17:19:35 +0100
commit8ac881a544e8fc7f85d78132610fce1b696d2025 (patch)
tree60742c9e76e7f404c96ba902b6e86fe90ce6e3c8
parent5602c655ac32000e113dffc4aef2b3ed8d733c58 (diff)
downloadqxmpp-8ac881a544e8fc7f85d78132610fce1b696d2025.tar.gz
Task/Promise: Don't allow abstract types
Supporting abstract types only has little advantages and we might want to store the result by value later.
-rw-r--r--src/base/QXmppPromise.h5
-rw-r--r--src/base/QXmppTask.h9
-rw-r--r--tests/qxmppclient/tst_qxmppclient.cpp12
3 files changed, 10 insertions, 16 deletions
diff --git a/src/base/QXmppPromise.h b/src/base/QXmppPromise.h
index 09bc5bcb..91443c7f 100644
--- a/src/base/QXmppPromise.h
+++ b/src/base/QXmppPromise.h
@@ -21,6 +21,7 @@
template<typename T>
class QXmppPromise
{
+ static_assert(!std::is_abstract_v<T>);
public:
template<typename U = T, std::enable_if_t<std::is_void_v<U>> * = nullptr>
QXmppPromise()
@@ -43,7 +44,7 @@ public:
#ifdef QXMPP_DOC
void reportFinished(T &&value)
#else
- template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_base_of_v<T, U>> * = nullptr>
+ template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_same_v<T, U>> * = nullptr>
void finish(U &&value)
#endif
{
@@ -59,7 +60,7 @@ public:
}
/// \cond
- template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_constructible_v<T, U> && !std::is_base_of_v<T, U>> * = nullptr>
+ template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_constructible_v<T, U> && !std::is_same_v<T, U>> * = nullptr>
void finish(U &&value)
{
Q_ASSERT(!d.isFinished());
diff --git a/src/base/QXmppTask.h b/src/base/QXmppTask.h
index 141cf10e..84ba8a33 100644
--- a/src/base/QXmppTask.h
+++ b/src/base/QXmppTask.h
@@ -50,10 +50,6 @@ private:
///
/// Tasks are generated by QXmppPromise and can be handled using QXmppTask::then().
///
-/// It supports abstract types, i.e. you can create a QXmppTask<QXmppStanza> and report MyIq
-/// (derived from QXmppStanza) to it and when handling the result it is possible to cast the result
-/// back to MyIq.
-///
/// Unlike QFuture, this is not thread-safe. This avoids the need to do mutex locking at every
/// access though.
///
@@ -177,10 +173,7 @@ public:
///
/// Moves the result of the operation out of the task.
///
- /// Since this returns by value, you will not be able to cast the result to derived types. Use
- /// result() for read-only access or register a handler function using then().
- ///
- /// \warning This can only be used once the operation is finished.
+ /// \warning This can only be used once and only after the operation has finished.
///
#ifdef QXMPP_DOC
[[nodiscard]] T takeResult()
diff --git a/tests/qxmppclient/tst_qxmppclient.cpp b/tests/qxmppclient/tst_qxmppclient.cpp
index 0b5d33ea..a18fa0d2 100644
--- a/tests/qxmppclient/tst_qxmppclient.cpp
+++ b/tests/qxmppclient/tst_qxmppclient.cpp
@@ -174,8 +174,8 @@ void tst_QXmppClient::testTaskDirect()
bool thenCalled = false;
p.task().then(this, [&thenCalled](QXmppIq &&iq) {
thenCalled = true;
- QVERIFY(dynamic_cast<QXmppRegisterIq *>(&iq));
- QCOMPARE(dynamic_cast<QXmppRegisterIq &>(iq).username(), QStringLiteral("username"));
+ // casting not supported
+ QVERIFY(!dynamic_cast<QXmppRegisterIq *>(&iq));
});
p.finish(std::move(iq));
@@ -203,8 +203,8 @@ void tst_QXmppClient::testTaskStore()
thenCalled = true;
QCOMPARE(iq.from(), QStringLiteral("juliet"));
- QVERIFY(dynamic_cast<QXmppRegisterIq *>(&iq));
- QCOMPARE(dynamic_cast<QXmppRegisterIq &>(iq).username(), QStringLiteral("username"));
+ // casting not supported
+ QVERIFY(!dynamic_cast<QXmppRegisterIq *>(&iq));
});
QVERIFY(thenCalled);
@@ -219,8 +219,8 @@ void tst_QXmppClient::testTaskStore()
thenCalled = false;
p.task().then(this, [&thenCalled](QXmppIq &&iq) {
thenCalled = true;
- QVERIFY(dynamic_cast<QXmppRegisterIq *>(&iq));
- QCOMPARE(dynamic_cast<QXmppRegisterIq &>(iq).username(), QStringLiteral("username"));
+ // casting not supported
+ QVERIFY(!dynamic_cast<QXmppRegisterIq *>(&iq));
});
QVERIFY(thenCalled);