diff options
| author | Linus Jahn <lnj@kaidan.im> | 2023-01-28 17:08:05 +0100 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2023-01-28 17:19:35 +0100 |
| commit | 8ac881a544e8fc7f85d78132610fce1b696d2025 (patch) | |
| tree | 60742c9e76e7f404c96ba902b6e86fe90ce6e3c8 | |
| parent | 5602c655ac32000e113dffc4aef2b3ed8d733c58 (diff) | |
| download | qxmpp-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.h | 5 | ||||
| -rw-r--r-- | src/base/QXmppTask.h | 9 | ||||
| -rw-r--r-- | tests/qxmppclient/tst_qxmppclient.cpp | 12 |
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); |
