diff --git a/src/base/Algorithms.h b/src/base/Algorithms.h new file mode 100644 index 000000000..a29ab6af4 --- /dev/null +++ b/src/base/Algorithms.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2024 Linus Jahn +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef ALGORITHMS_H +#define ALGORITHMS_H + +#include + +namespace QXmpp::Private { + +template +auto transform(InputVector &input, Converter convert) +{ + OutputVector output; + output.reserve(input.size()); + std::transform(input.begin(), input.end(), std::back_inserter(output), std::forward(convert)); + return output; +} + +} // namespace QXmpp::Private + +#endif // ALGORITHMS_H diff --git a/src/base/QXmppFileMetadata.cpp b/src/base/QXmppFileMetadata.cpp index 2705d5dc1..2edc5cdd8 100644 --- a/src/base/QXmppFileMetadata.cpp +++ b/src/base/QXmppFileMetadata.cpp @@ -10,6 +10,8 @@ #include "QXmppUtils.h" #include "QXmppUtils_p.h" +#include "Algorithms.h" + #include #include @@ -79,10 +81,8 @@ QVector allChildElements(const QDomElement &el, const QString &name template QVector> forAllChildElements(const QDomElement &el, const QString &name, Func func) { - auto elements = allChildElements(el, name); - QVector> out; - std::transform(elements.begin(), elements.end(), std::back_inserter(out), func); - return out; + return transform>>( + allChildElements(el, name), std::forward(func)); } template diff --git a/src/base/QXmppHashing.cpp b/src/base/QXmppHashing.cpp index ece922a28..40328fe08 100644 --- a/src/base/QXmppHashing.cpp +++ b/src/base/QXmppHashing.cpp @@ -6,6 +6,8 @@ #include "QXmppHash.h" #include "QXmppHashing_p.h" +#include "Algorithms.h" + #include #include #include @@ -167,16 +169,6 @@ uint16_t QXmpp::Private::hashPriority(HashAlgorithm algorithm) return 0; } -template -auto transform(std::vector &input, Converter convert) -{ - using Output = std::decay_t; - std::vector output; - output.reserve(input.size()); - std::transform(input.begin(), input.end(), std::back_inserter(output), std::move(convert)); - return output; -} - auto makeReadyResult(HashingResult::Result result, std::unique_ptr device) { return makeReadyFuture(std::make_shared(std::move(result), std::move(device))); @@ -263,7 +255,7 @@ class HashGenerator : public QObject std::function isCancelled) { // convert to QCryptographicHash::Algorithm for hashing - auto qtAlgorithms = transform(algorithms, [](auto algorithm) { + auto qtAlgorithms = transform>(algorithms, [](auto algorithm) { auto converted = toCryptograhicHashAlgorithm(algorithm); Q_ASSERT_X(converted.has_value(), "calculate hashes", "Must only be called with algorithms supported by QCryptographicHash"); return *converted; @@ -304,7 +296,7 @@ class HashGenerator : public QObject m_isCancelled(std::move(isCancelled)) { // create hash processors - m_hashProcessors = transform(algorithms, [this](auto algorithm) { + m_hashProcessors = transform>(algorithms, [this](auto algorithm) { return HashProcessor(this, algorithm); }); @@ -389,7 +381,7 @@ class HashGenerator : public QObject void finish() { - auto hashes = transform(m_hashProcessors, [](auto &processor) { + auto hashes = transform>(m_hashProcessors, [](auto &processor) { QXmppHash hash; hash.setAlgorithm(toHashAlgorithm(processor.algorithm)); hash.setHash(processor.hash->result()); diff --git a/src/client/QXmppFileSharingManager.cpp b/src/client/QXmppFileSharingManager.cpp index 660ea5e29..21c8a23d2 100644 --- a/src/client/QXmppFileSharingManager.cpp +++ b/src/client/QXmppFileSharingManager.cpp @@ -7,7 +7,6 @@ #include "QXmppBitsOfBinaryContentId.h" #include "QXmppBitsOfBinaryData.h" -#include "QXmppClient.h" #include "QXmppFileMetadata.h" #include "QXmppFileShare.h" #include "QXmppFutureUtils_p.h" @@ -16,6 +15,8 @@ #include "QXmppUploadRequestManager.h" #include "QXmppUtils_p.h" +#include "Algorithms.h" + #include #include #include @@ -43,16 +44,6 @@ static std::vector hashAlgorithms() #endif } -template -auto transform(T &input, Converter convert) -{ - using Output = std::decay_t; - std::vector output; - output.reserve(input.size()); - std::transform(input.begin(), input.end(), std::back_inserter(output), std::move(convert)); - return output; -} - class QXmppFileUploadPrivate { public: @@ -475,12 +466,9 @@ std::shared_ptr QXmppFileSharingManager::uploadFile(std::shared auto &hashValue = hashResult->result; if (std::holds_alternative>(hashValue)) { const auto &hashesVector = std::get>(hashValue); - QVector hashes; - hashes.reserve(hashesVector.size()); - std::transform(hashesVector.begin(), hashesVector.end(), - std::back_inserter(hashes), [](auto &&hash) { - return hash; - }); + auto hashes = transform>(hashesVector, [](auto &&hash) { + return hash; + }); upload->d->metadata.setHashes(hashes); upload->d->success = true; } else if (std::holds_alternative(hashValue)) { @@ -564,7 +552,7 @@ std::shared_ptr QXmppFileSharingManager::downloadFile( download->d->hashesFuture = verifyHashes( std::move(file), - transform(download->d->hashes, [](auto hash) { return hash; })); + transform>(download->d->hashes, [](auto hash) { return hash; })); await(download->d->hashesFuture, this, [download](HashVerificationResultPtr hashResult) { auto convert = overloaded { diff --git a/src/client/QXmppMamManager.cpp b/src/client/QXmppMamManager.cpp index ca3b307b6..02b1cf02d 100644 --- a/src/client/QXmppMamManager.cpp +++ b/src/client/QXmppMamManager.cpp @@ -15,6 +15,8 @@ #include "QXmppUtils.h" #include "QXmppUtils_p.h" +#include "Algorithms.h" + #include #include @@ -22,16 +24,6 @@ using namespace QXmpp; using namespace QXmpp::Private; -template -auto transform(const T &input, Converter convert) -{ - using Output = std::decay_t; - QVector output; - output.reserve(input.size()); - std::transform(input.begin(), input.end(), std::back_inserter(output), std::move(convert)); - return output; -} - template auto sum(const T &c) { @@ -322,7 +314,7 @@ QXmppTask QXmppMamManager::retrieveMessages(con state.processedMessages.resize(state.messages.size()); // check for encrypted messages (once) - auto messagesEncrypted = transform(state.messages, [&](const auto &m) { + auto messagesEncrypted = transform>(state.messages, [&](const auto &m) { return e2eeExt->isEncrypted(m.element); }); auto encryptedCount = sum(messagesEncrypted); @@ -367,7 +359,7 @@ QXmppTask QXmppMamManager::retrieveMessages(con } // for the case without decryption, finish here - state.processedMessages = transform(state.messages, [](const auto &m) { + state.processedMessages = transform>(state.messages, [](const auto &m) { return parseMamMessage(m, Unencrypted); }); state.finish(); diff --git a/src/client/QXmppPubSubManager.cpp b/src/client/QXmppPubSubManager.cpp index c21e212e7..0cdcc9f04 100644 --- a/src/client/QXmppPubSubManager.cpp +++ b/src/client/QXmppPubSubManager.cpp @@ -17,6 +17,8 @@ #include "QXmppUtils.h" #include "QXmppUtils_p.h" +#include "Algorithms.h" + #include using namespace QXmpp::Private; @@ -1037,14 +1039,10 @@ auto QXmppPubSubManager::publishItems(PubSubIqBase &&request) -> QXmppTasksendIq(std::move(request)), this, [](const PubSubIq<> &iq) -> PublishItemsResult { - const auto itemToId = [](const QXmppPubSubBaseItem &item) { - return item.id(); - }; - const auto items = iq.items(); - QVector ids(items.size()); - std::transform(items.begin(), items.end(), ids.begin(), itemToId); - return ids; + return transform>(items, [](const auto &item) { + return item.id(); + }); }); } /// \endcond diff --git a/tests/qxmpphttpuploadmanager/tst_qxmpphttpuploadmanager.cpp b/tests/qxmpphttpuploadmanager/tst_qxmpphttpuploadmanager.cpp index f7817c59c..51ab59c15 100644 --- a/tests/qxmpphttpuploadmanager/tst_qxmpphttpuploadmanager.cpp +++ b/tests/qxmpphttpuploadmanager/tst_qxmpphttpuploadmanager.cpp @@ -10,12 +10,15 @@ #include "QXmppTlsManager_p.h" #include "QXmppUploadRequestManager.h" +#include "Algorithms.h" #include "IntegrationTesting.h" #include "TestClient.h" #include "util.h" #include +using namespace QXmpp::Private; + static const auto UPLOAD_SERVICE_NAME = QStringLiteral("upload.montague.tld"); constexpr quint64 MAX_FILE_SIZE = 500UL * 1024UL * 1024UL; @@ -378,8 +381,7 @@ void tst_QXmppHttpUploadManager::testUpload() // get server items auto items = expectVariant>(wait(disco->requestDiscoItems(test.configuration().domain()).toFuture(this))); // request disco info for each item - std::vector> infoFutures; - std::transform(items.cbegin(), items.cend(), std::back_inserter(infoFutures), [disco](const auto &item) { + auto infoFutures = transform>>(items, [disco](const auto &item) { return disco->requestDiscoInfo(item.jid(), item.node()); }); auto uploadServiceJid = [&]() {