From c6f3da1097147b1f068bd4b612ca096b9239afb7 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 12 May 2019 13:26:06 +0800 Subject: [PATCH] Improve removeIf() to support set types We can now replace QMutable*Iterator by removeIf() which usage is more consistent with other algorithm functions. --- src/base/algorithm.h | 38 +++++++++++++++++++++++---- src/base/bittorrent/session.cpp | 2 +- src/base/filesystemwatcher.cpp | 2 +- src/base/http/server.cpp | 18 ++++++------- src/base/preferences.cpp | 13 +++++---- src/gui/properties/peerlistwidget.cpp | 4 +-- src/webui/webapplication.cpp | 14 ++++++---- 7 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/base/algorithm.h b/src/base/algorithm.h index 0d2f95679..01aa39324 100644 --- a/src/base/algorithm.h +++ b/src/base/algorithm.h @@ -28,14 +28,42 @@ #pragma once -namespace Dict +#include + +namespace Algorithm { - // To be used with QMap, QHash and it's variants - template - void removeIf(Dictionary &&dict, BinaryPredicate p) + template + using void_t = void; // replace this with std::void_t in C++17 + + template + struct HasMappedType + : std::false_type + { + }; + + template + struct HasMappedType> + : std::true_type + { + }; + + // To be used with associative array types, such as QMap, QHash and it's variants + template ::value, int> = 0> + void removeIf(T &dict, BinaryPredicate p) { auto it = dict.begin(); while (it != dict.end()) - it = (p(it.key(), it.value()) ? dict.erase(it) : it + 1); + it = (p(it.key(), it.value()) ? dict.erase(it) : (it + 1)); + } + + // To be used with set types, such as QSet, std::set + template ::value, int> = 0> + void removeIf(T &set, UnaryPredicate p) + { + auto it = set.begin(); + while (it != set.end()) + it = (p(*it) ? set.erase(it) : (it + 1)); } } diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 2e8df1759..e2ea1d689 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -754,7 +754,7 @@ bool Session::removeCategory(const QString &name) if (isSubcategoriesEnabled()) { // remove subcategories const QString test = name + '/'; - Dict::removeIf(m_categories, [this, &test, &result](const QString &category, const QString &) + Algorithm::removeIf(m_categories, [this, &test, &result](const QString &category, const QString &) { if (category.startsWith(test)) { result = true; diff --git a/src/base/filesystemwatcher.cpp b/src/base/filesystemwatcher.cpp index 2cd7c9a58..b68ac4f4f 100644 --- a/src/base/filesystemwatcher.cpp +++ b/src/base/filesystemwatcher.cpp @@ -122,7 +122,7 @@ void FileSystemWatcher::processPartialTorrents() QStringList noLongerPartial; // Check which torrents are still partial - Dict::removeIf(m_partialTorrents, [&noLongerPartial](const QString &torrentPath, int &value) + Algorithm::removeIf(m_partialTorrents, [&noLongerPartial](const QString &torrentPath, int &value) { if (!QFile::exists(torrentPath)) return true; diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp index 8fb01e655..1d16bf590 100644 --- a/src/base/http/server.cpp +++ b/src/base/http/server.cpp @@ -32,7 +32,6 @@ #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include +#include "base/algorithm.h" #include "base/utils/net.h" #include "connection.h" @@ -119,14 +119,14 @@ void Server::removeConnection(Connection *connection) void Server::dropTimedOutConnection() { - QMutableSetIterator i(m_connections); - while (i.hasNext()) { - Connection *connection = i.next(); - if (connection->hasExpired(KEEP_ALIVE_DURATION)) { - connection->deleteLater(); - i.remove(); - } - } + Algorithm::removeIf(m_connections, [](Connection *connection) + { + if (!connection->hasExpired(KEEP_ALIVE_DURATION)) + return false; + + connection->deleteLater(); + return true; + }); } bool Server::setupHttps(const QByteArray &certificates, const QByteArray &privateKey) diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 69475fad5..a96522f5c 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #ifndef DISABLE_GUI @@ -49,6 +48,7 @@ #include #endif +#include "algorithm.h" #include "global.h" #include "settingsstorage.h" #include "utils/fs.h" @@ -516,13 +516,12 @@ QList Preferences::getWebUiAuthSubnetWhitelist() const void Preferences::setWebUiAuthSubnetWhitelist(QStringList subnets) { - QMutableListIterator i(subnets); - while (i.hasNext()) { + Algorithm::removeIf(subnets, [](const QString &subnet) + { bool ok = false; - const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(i.next().trimmed(), &ok); - if (!ok) - i.remove(); - } + Utils::Net::parseSubnet(subnet.trimmed(), &ok); + return !ok; + }); setValue("Preferences/WebUI/AuthSubnetWhitelist", subnets); } diff --git a/src/gui/properties/peerlistwidget.cpp b/src/gui/properties/peerlistwidget.cpp index eab083c15..f4cc47873 100644 --- a/src/gui/properties/peerlistwidget.cpp +++ b/src/gui/properties/peerlistwidget.cpp @@ -364,9 +364,7 @@ void PeerListWidget::loadPeers(BitTorrent::TorrentHandle *const torrent, bool fo } } // Delete peers that are gone - QSetIterator it(oldPeersSet); - while (it.hasNext()) { - const QString &ip = it.next(); + for (const QString &ip : oldPeersSet) { m_missingFlags.remove(ip); m_peerAddresses.remove(ip); QStandardItem *item = m_peerItems.take(ip); diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index 326ba424c..c0b15b001 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -44,6 +44,7 @@ #include #include +#include "base/algorithm.h" #include "base/global.h" #include "base/http/httperror.h" #include "base/iconprovider.h" @@ -527,11 +528,14 @@ void WebApplication::sessionStart() // remove outdated sessions const qint64 now = QDateTime::currentMSecsSinceEpoch() / 1000; - const QHash sessionsCopy {m_sessions}; - for (const auto session : sessionsCopy) { - if ((now - session->timestamp()) > INACTIVE_TIME) - delete m_sessions.take(session->id()); - } + Algorithm::removeIf(m_sessions, [now](const QString &, const WebSession *session) + { + if ((now - session->timestamp()) <= INACTIVE_TIME) + return false; + + delete session; + return true; + }); m_currentSession = new WebSession(generateSid()); m_sessions[m_currentSession->id()] = m_currentSession;