mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-12-27 08:19:30 +08:00
Prevent possible c++11 range-loop container detach
Explicit or implicit calls to begin() and end() cause a non-const container to detach from shared data, ie. to perform a deep-copy to gain a unique copy of the data. That can be a expensive although unneeded operation. In order to assist the developer a copyAsConst function is added. copyAsConst returns a const copy of the object. For lvalues just use qAsConst. It's only available on Qt 5.7.0. But we added also for earlier versions. The developer can always use qAsConst. Intended uses: QString s = ...; for (const auto &ch : qAsConst(s)) process(ch); for (const auto &ch : copyAsConst(funcReturningQString())) process(ch);
This commit is contained in:
parent
98a1c111b9
commit
1a913c502b
@ -26,5 +26,23 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
const char C_TORRENT_FILE_EXTENSION[] = ".torrent";
|
const char C_TORRENT_FILE_EXTENSION[] = ".torrent";
|
||||||
|
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
|
template <typename T>
|
||||||
|
constexpr typename std::add_const<T>::type &qAsConst(T &t) noexcept { return t; }
|
||||||
|
|
||||||
|
// prevent rvalue arguments:
|
||||||
|
template <typename T>
|
||||||
|
void qAsConst(const T &&) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// returns a const object copy
|
||||||
|
template <typename T>
|
||||||
|
constexpr typename std::add_const<T>::type copyAsConst(T &&t) noexcept { return std::move(t); }
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "../bittorrent/magneturi.h"
|
#include "../bittorrent/magneturi.h"
|
||||||
#include "../bittorrent/session.h"
|
#include "../bittorrent/session.h"
|
||||||
#include "../asyncfilestorage.h"
|
#include "../asyncfilestorage.h"
|
||||||
|
#include "../global.h"
|
||||||
#include "../logger.h"
|
#include "../logger.h"
|
||||||
#include "../profile.h"
|
#include "../profile.h"
|
||||||
#include "../settingsstorage.h"
|
#include "../settingsstorage.h"
|
||||||
@ -239,7 +240,7 @@ void AutoDownloader::importRules(const QByteArray &data, AutoDownloader::RulesFi
|
|||||||
QByteArray AutoDownloader::exportRulesToJSONFormat() const
|
QByteArray AutoDownloader::exportRulesToJSONFormat() const
|
||||||
{
|
{
|
||||||
QJsonObject jsonObj;
|
QJsonObject jsonObj;
|
||||||
for (const auto &rule : rules())
|
for (const auto &rule : copyAsConst(rules()))
|
||||||
jsonObj.insert(rule.name(), rule.toJsonObject());
|
jsonObj.insert(rule.name(), rule.toJsonObject());
|
||||||
|
|
||||||
return QJsonDocument(jsonObj).toJson();
|
return QJsonDocument(jsonObj).toJson();
|
||||||
@ -247,15 +248,14 @@ QByteArray AutoDownloader::exportRulesToJSONFormat() const
|
|||||||
|
|
||||||
void AutoDownloader::importRulesFromJSONFormat(const QByteArray &data)
|
void AutoDownloader::importRulesFromJSONFormat(const QByteArray &data)
|
||||||
{
|
{
|
||||||
const auto rules = rulesFromJSON(data);
|
for (const auto &rule : copyAsConst(rulesFromJSON(data)))
|
||||||
for (const auto &rule : rules)
|
|
||||||
insertRule(rule);
|
insertRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AutoDownloader::exportRulesToLegacyFormat() const
|
QByteArray AutoDownloader::exportRulesToLegacyFormat() const
|
||||||
{
|
{
|
||||||
QVariantHash dict;
|
QVariantHash dict;
|
||||||
for (const auto &rule : rules())
|
for (const auto &rule : copyAsConst(rules()))
|
||||||
dict[rule.name()] = rule.toLegacyDict();
|
dict[rule.name()] = rule.toLegacyDict();
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QJsonValue>
|
#include <QJsonValue>
|
||||||
|
|
||||||
|
#include "base/global.h"
|
||||||
#include "rss_article.h"
|
#include "rss_article.h"
|
||||||
|
|
||||||
using namespace RSS;
|
using namespace RSS;
|
||||||
@ -122,7 +123,7 @@ void Folder::addItem(Item *item)
|
|||||||
connect(item, &Item::articleAboutToBeRemoved, this, &Item::articleAboutToBeRemoved);
|
connect(item, &Item::articleAboutToBeRemoved, this, &Item::articleAboutToBeRemoved);
|
||||||
connect(item, &Item::unreadCountChanged, this, &Folder::handleItemUnreadCountChanged);
|
connect(item, &Item::unreadCountChanged, this, &Folder::handleItemUnreadCountChanged);
|
||||||
|
|
||||||
for (auto article: item->articles())
|
for (auto article: copyAsConst(item->articles()))
|
||||||
emit newArticle(article);
|
emit newArticle(article);
|
||||||
|
|
||||||
if (item->unreadCount() > 0)
|
if (item->unreadCount() > 0)
|
||||||
@ -133,7 +134,7 @@ void Folder::removeItem(Item *item)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_items.contains(item));
|
Q_ASSERT(m_items.contains(item));
|
||||||
|
|
||||||
for (auto article: item->articles())
|
for (auto article: copyAsConst(item->articles()))
|
||||||
emit articleAboutToBeRemoved(article);
|
emit articleAboutToBeRemoved(article);
|
||||||
|
|
||||||
item->disconnect(this);
|
item->disconnect(this);
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrenthandle.h"
|
||||||
|
#include "base/global.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a path to a string suitable for display.
|
* Converts a path to a string suitable for display.
|
||||||
@ -128,7 +129,7 @@ bool Utils::Fs::smartRemoveEmptyFolderTree(const QString &path)
|
|||||||
std::sort(dirList.begin(), dirList.end()
|
std::sort(dirList.begin(), dirList.end()
|
||||||
, [](const QString &l, const QString &r) { return l.count("/") > r.count("/"); });
|
, [](const QString &l, const QString &r) { return l.count("/") > r.count("/"); });
|
||||||
|
|
||||||
for (const QString &p : dirList) {
|
for (const QString &p : qAsConst(dirList)) {
|
||||||
// remove unwanted files
|
// remove unwanted files
|
||||||
for (const QString &f : deleteFilesList) {
|
for (const QString &f : deleteFilesList) {
|
||||||
forceRemove(p + f);
|
forceRemove(p + f);
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
|
|
||||||
|
#include "base/global.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "base/utils/net.h"
|
#include "base/utils/net.h"
|
||||||
#include "ui_ipsubnetwhitelistoptionsdialog.h"
|
#include "ui_ipsubnetwhitelistoptionsdialog.h"
|
||||||
@ -47,7 +48,7 @@ IPSubnetWhitelistOptionsDialog::IPSubnetWhitelistOptionsDialog(QWidget *parent)
|
|||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
QStringList authSubnetWhitelistStringList;
|
QStringList authSubnetWhitelistStringList;
|
||||||
for (const Utils::Net::Subnet &subnet : Preferences::instance()->getWebUiAuthSubnetWhitelist())
|
for (const Utils::Net::Subnet &subnet : copyAsConst(Preferences::instance()->getWebUiAuthSubnetWhitelist()))
|
||||||
authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet);
|
authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet);
|
||||||
m_model = new QStringListModel(authSubnetWhitelistStringList, this);
|
m_model = new QStringListModel(authSubnetWhitelistStringList, this);
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ void IPSubnetWhitelistOptionsDialog::on_buttonWhitelistIPSubnet_clicked()
|
|||||||
|
|
||||||
void IPSubnetWhitelistOptionsDialog::on_buttonDeleteIPSubnet_clicked()
|
void IPSubnetWhitelistOptionsDialog::on_buttonDeleteIPSubnet_clicked()
|
||||||
{
|
{
|
||||||
for (const auto &i : m_ui->whitelistedIPSubnetList->selectionModel()->selectedIndexes())
|
for (const auto &i : copyAsConst(m_ui->whitelistedIPSubnetList->selectionModel()->selectedIndexes()))
|
||||||
m_sortFilter->removeRow(i.row());
|
m_sortFilter->removeRow(i.row());
|
||||||
|
|
||||||
m_modified = true;
|
m_modified = true;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
|
#include "base/global.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
|
||||||
SpeedPlotView::SpeedPlotView(QWidget *parent)
|
SpeedPlotView::SpeedPlotView(QWidget *parent)
|
||||||
@ -257,7 +258,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
|
|
||||||
double legendHeight = 0;
|
double legendHeight = 0;
|
||||||
int legendWidth = 0;
|
int legendWidth = 0;
|
||||||
for (const auto &property : m_properties) {
|
for (const auto &property : qAsConst(m_properties)) {
|
||||||
if (!property.enable)
|
if (!property.enable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -272,7 +273,7 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
painter.fillRect(legendBackgroundRect, legendBackgroundColor);
|
painter.fillRect(legendBackgroundRect, legendBackgroundColor);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const auto &property : m_properties) {
|
for (const auto &property : qAsConst(m_properties)) {
|
||||||
if (!property.enable)
|
if (!property.enable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
|
#include "base/global.h"
|
||||||
#include "base/net/portforwarder.h"
|
#include "base/net/portforwarder.h"
|
||||||
#include "base/net/proxyconfigurationmanager.h"
|
#include "base/net/proxyconfigurationmanager.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
@ -200,7 +201,7 @@ void AppController::preferencesAction()
|
|||||||
data["bypass_local_auth"] = !pref->isWebUiLocalAuthEnabled();
|
data["bypass_local_auth"] = !pref->isWebUiLocalAuthEnabled();
|
||||||
data["bypass_auth_subnet_whitelist_enabled"] = pref->isWebUiAuthSubnetWhitelistEnabled();
|
data["bypass_auth_subnet_whitelist_enabled"] = pref->isWebUiAuthSubnetWhitelistEnabled();
|
||||||
QStringList authSubnetWhitelistStringList;
|
QStringList authSubnetWhitelistStringList;
|
||||||
for (const Utils::Net::Subnet &subnet : pref->getWebUiAuthSubnetWhitelist())
|
for (const Utils::Net::Subnet &subnet : copyAsConst(pref->getWebUiAuthSubnetWhitelist()))
|
||||||
authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet);
|
authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet);
|
||||||
data["bypass_auth_subnet_whitelist"] = authSubnetWhitelistStringList.join("\n");
|
data["bypass_auth_subnet_whitelist"] = authSubnetWhitelistStringList.join("\n");
|
||||||
// Update my dynamic domain name
|
// Update my dynamic domain name
|
||||||
|
Loading…
Reference in New Issue
Block a user