diff --git a/cmake/Modules/CommonConfig.cmake b/cmake/Modules/CommonConfig.cmake index 57072e594..1db86d8a5 100644 --- a/cmake/Modules/CommonConfig.cmake +++ b/cmake/Modules/CommonConfig.cmake @@ -12,11 +12,11 @@ set(CMAKE_AUTORCC_OPTIONS --compress 9 --threshold 5) add_library(qbt_common_cfg INTERFACE) -# Full C++ 17 support is required +# Full C++ 20 support is required # See also https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html # for a breakdown of the features that CMake recognizes for each C++ standard target_compile_features(qbt_common_cfg INTERFACE - cxx_std_17 + cxx_std_20 ) target_compile_definitions(qbt_common_cfg INTERFACE diff --git a/src/app/application.cpp b/src/app/application.cpp index 0fcc14d87..447a35c4f 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -464,8 +464,7 @@ void Application::processMessage(const QString &message) #ifndef DISABLE_GUI if (message.isEmpty()) { - // TODO: use [[likely]] in C++20 - if (Q_LIKELY(BitTorrent::Session::instance()->isRestored())) + if (BitTorrent::Session::instance()->isRestored()) [[likely]] { m_window->activate(); // show UI } diff --git a/src/base/bittorrent/customstorage.cpp b/src/base/bittorrent/customstorage.cpp index 7d746da78..c4957ef07 100644 --- a/src/base/bittorrent/customstorage.cpp +++ b/src/base/bittorrent/customstorage.cpp @@ -118,7 +118,7 @@ void CustomDiskIOThread::async_move_storage(lt::storage_index_t storage, std::st handleCompleteFiles(storage, newSavePath); m_nativeDiskIO->async_move_storage(storage, path, flags - , [=, handler = std::move(handler)](lt::status_t status, const std::string &path, const lt::storage_error &error) + , [=, this, handler = std::move(handler)](lt::status_t status, const std::string &path, const lt::storage_error &error) { #if LIBTORRENT_VERSION_NUM < 20100 if ((status != lt::status_t::fatal_disk_error) && (status != lt::status_t::file_exist)) @@ -153,7 +153,7 @@ void CustomDiskIOThread::async_rename_file(lt::storage_index_t storage, lt::file , std::function handler) { m_nativeDiskIO->async_rename_file(storage, index, name - , [=, handler = std::move(handler)](const std::string &name, lt::file_index_t index, const lt::storage_error &error) + , [=, this, handler = std::move(handler)](const std::string &name, lt::file_index_t index, const lt::storage_error &error) { if (!error) m_storageData[storage].files.rename_file(index, name); @@ -171,7 +171,7 @@ void CustomDiskIOThread::async_set_file_priority(lt::storage_index_t storage, lt , std::function)> handler) { m_nativeDiskIO->async_set_file_priority(storage, std::move(priorities) - , [=, handler = std::move(handler)](const lt::storage_error &error, const lt::aux::vector &priorities) + , [=, this, handler = std::move(handler)](const lt::storage_error &error, const lt::aux::vector &priorities) { m_storageData[storage].filePriorities = priorities; handler(error, priorities); diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 5d36e6e34..4500b11f9 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -2904,7 +2904,7 @@ void SessionImpl::findIncompleteFiles(const TorrentInfo &torrentInfo, const Path const auto searchId = TorrentID::fromInfoHash(torrentInfo.infoHash()); const PathList originalFileNames = (filePaths.isEmpty() ? torrentInfo.filePaths() : filePaths); - QMetaObject::invokeMethod(m_fileSearcher, [=]() + QMetaObject::invokeMethod(m_fileSearcher, [=, this] { m_fileSearcher->search(searchId, originalFileNames, savePath, downloadPath, isAppendExtensionEnabled()); }); diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index c66565409..8ecd1e98a 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1217,7 +1217,7 @@ QVector TorrentImpl::filesProgress() const const int count = m_filesProgress.size(); Q_ASSERT(count == filesCount()); - if (Q_UNLIKELY(count != filesCount())) + if (count != filesCount()) [[unlikely]] return {}; if (m_completedFiles.count(true) == count) @@ -1613,8 +1613,7 @@ TrackerEntry TorrentImpl::updateTrackerEntry(const lt::announce_entry &announceE }); Q_ASSERT(it != m_trackerEntries.end()); - // TODO: use [[unlikely]] in C++20 - if (Q_UNLIKELY(it == m_trackerEntries.end())) + if (it == m_trackerEntries.end()) [[unlikely]] return {}; #ifdef QBT_USES_LIBTORRENT2 @@ -1813,7 +1812,7 @@ void TorrentImpl::moveStorage(const Path &newPath, const MoveStorageContext cont void TorrentImpl::renameFile(const int index, const Path &path) { Q_ASSERT((index >= 0) && (index < filesCount())); - if (Q_UNLIKELY((index < 0) || (index >= filesCount()))) + if ((index < 0) || (index >= filesCount())) [[unlikely]] return; const Path wantedPath = wantedActualPath(index, path); @@ -2276,7 +2275,7 @@ void TorrentImpl::doRenameFile(int index, const Path &path) Q_ASSERT(index >= 0); Q_ASSERT(index < nativeIndexes.size()); - if (Q_UNLIKELY((index < 0) || (index >= nativeIndexes.size()))) + if ((index < 0) || (index >= nativeIndexes.size())) [[unlikely]] return; ++m_renameCount; @@ -2364,11 +2363,11 @@ void TorrentImpl::updateStatus(const lt::torrent_status &nativeStatus) void TorrentImpl::updateProgress() { Q_ASSERT(hasMetadata()); - if (Q_UNLIKELY(!hasMetadata())) + if (!hasMetadata()) [[unlikely]] return; Q_ASSERT(!m_filesProgress.isEmpty()); - if (Q_UNLIKELY(m_filesProgress.isEmpty())) + if (m_filesProgress.isEmpty()) [[unlikely]] m_filesProgress.resize(filesCount()); const QBitArray oldPieces = std::exchange(m_pieces, LT::toQBitArray(m_nativeStatus.pieces)); diff --git a/src/base/http/connection.cpp b/src/base/http/connection.cpp index f6514e365..4a96295e4 100644 --- a/src/base/http/connection.cpp +++ b/src/base/http/connection.cpp @@ -74,12 +74,12 @@ void Connection::read() const qint64 bytesAvailable = m_socket->bytesAvailable(); m_receivedData.resize(previousSize + bytesAvailable); const qint64 bytesRead = m_socket->read((m_receivedData.data() + previousSize), bytesAvailable); - if (Q_UNLIKELY(bytesRead < 0)) + if (bytesRead < 0) [[unlikely]] { m_socket->close(); return; } - if (Q_UNLIKELY(bytesRead < bytesAvailable)) + if (bytesRead < bytesAvailable) [[unlikely]] m_receivedData.chop(bytesAvailable - bytesRead); while (!m_receivedData.isEmpty()) diff --git a/src/base/orderedset.h b/src/base/orderedset.h index 4a7730a6b..e43597a30 100644 --- a/src/base/orderedset.h +++ b/src/base/orderedset.h @@ -51,13 +51,6 @@ public: // The following are custom functions that are in line with Qt API interface, such as `QSet` -#if __cplusplus < 202002L - bool contains(const key_type &value) const - { - return (BaseType::find(value) != BaseType::cend()); - } -#endif - int count() const { return static_cast(BaseType::size()); diff --git a/src/base/rss/rss_feed.cpp b/src/base/rss/rss_feed.cpp index 6110eac7a..e6b2f9b48 100644 --- a/src/base/rss/rss_feed.cpp +++ b/src/base/rss/rss_feed.cpp @@ -524,8 +524,7 @@ void Feed::handleArticleLoadFinished(QVector articles) for (const QVariantHash &articleData : articles) { const auto articleID = articleData.value(Article::KeyId).toString(); - // TODO: use [[unlikely]] in C++20 - if (Q_UNLIKELY(m_articles.contains(articleID))) + if (m_articles.contains(articleID)) [[unlikely]] continue; auto *article = new Article(this, articleData); diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index df3087b0e..88de009e9 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -898,7 +898,7 @@ void AddNewTorrentDialog::setMetadataProgressIndicator(bool visibleIndicator, co void AddNewTorrentDialog::setupTreeview() { Q_ASSERT(hasMetadata()); - if (Q_UNLIKELY(!hasMetadata())) + if (!hasMetadata()) [[unlikely]] return; // Set dialog title diff --git a/src/gui/rss/rsswidget.cpp b/src/gui/rss/rsswidget.cpp index 3e4c6029f..09fb8c7cc 100644 --- a/src/gui/rss/rsswidget.cpp +++ b/src/gui/rss/rsswidget.cpp @@ -434,7 +434,7 @@ void RSSWidget::editSelectedRSSFeedURL() QTreeWidgetItem *item = selectedItems.first(); RSS::Feed *rssFeed = qobject_cast(m_feedListWidget->getRSSItem(item)); Q_ASSERT(rssFeed); - if (Q_UNLIKELY(!rssFeed)) + if (!rssFeed) [[unlikely]] return; bool ok = false; diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 43460a487..d1960afa8 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -212,7 +212,7 @@ void TorrentContentModel::updateFilesProgress() const QVector &filesProgress = m_contentHandler->filesProgress(); Q_ASSERT(m_filesIndex.size() == filesProgress.size()); // XXX: Why is this necessary? - if (Q_UNLIKELY(m_filesIndex.size() != filesProgress.size())) + if (m_filesIndex.size() != filesProgress.size()) [[unlikely]] return; for (int i = 0; i < filesProgress.size(); ++i) @@ -248,7 +248,7 @@ void TorrentContentModel::updateFilesAvailability() Q_ASSERT(m_filesIndex.size() == availableFileFractions.size()); // XXX: Why is this necessary? - if (Q_UNLIKELY(m_filesIndex.size() != availableFileFractions.size())) + if (m_filesIndex.size() != availableFileFractions.size()) [[unlikely]] return; for (int i = 0; i < m_filesIndex.size(); ++i) diff --git a/src/gui/torrentcontentwidget.cpp b/src/gui/torrentcontentwidget.cpp index 594fe76f1..97d4795a8 100644 --- a/src/gui/torrentcontentwidget.cpp +++ b/src/gui/torrentcontentwidget.cpp @@ -454,7 +454,7 @@ void TorrentContentWidget::onItemDoubleClicked(const QModelIndex &index) const auto *contentHandler = m_model->contentHandler(); Q_ASSERT(contentHandler && contentHandler->hasMetadata()); - if (Q_UNLIKELY(!contentHandler || !contentHandler->hasMetadata())) + if (!contentHandler || !contentHandler->hasMetadata()) [[unlikely]] return; if (m_doubleClickAction == DoubleClickAction::Rename) diff --git a/src/gui/transferlistfilters/trackersfilterwidget.cpp b/src/gui/transferlistfilters/trackersfilterwidget.cpp index 8e1ed6355..20c2d914a 100644 --- a/src/gui/transferlistfilters/trackersfilterwidget.cpp +++ b/src/gui/transferlistfilters/trackersfilterwidget.cpp @@ -392,7 +392,7 @@ void TrackersFilterWidget::handleFavicoDownloadFinished(const Net::DownloadResul { const QSet trackerHosts = m_downloadingFavicons.take(result.url); Q_ASSERT(!trackerHosts.isEmpty()); - if (Q_UNLIKELY(trackerHosts.isEmpty())) + if (trackerHosts.isEmpty()) [[unlikely]] return; QIcon icon; @@ -439,7 +439,7 @@ void TrackersFilterWidget::handleFavicoDownloadFinished(const Net::DownloadResul QListWidgetItem *trackerItem = item(rowFromTracker(trackerHost)); Q_ASSERT(trackerItem); - if (Q_UNLIKELY(!trackerItem)) + if (!trackerItem) [[unlikely]] continue; trackerItem->setData(Qt::DecorationRole, icon); diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index ef906b9f0..e737d4cd7 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -880,7 +880,7 @@ void SyncController::onTorrentAboutToBeRemoved(BitTorrent::Torrent *torrent) { auto iter = m_knownTrackers.find(trackerEntry.url); Q_ASSERT(iter != m_knownTrackers.end()); - if (Q_UNLIKELY(iter == m_knownTrackers.end())) + if (iter == m_knownTrackers.end()) [[unlikely]] continue; QSet &torrentIDs = iter.value(); diff --git a/test/testorderedset.cpp b/test/testorderedset.cpp index 2fd190289..52843a75f 100644 --- a/test/testorderedset.cpp +++ b/test/testorderedset.cpp @@ -42,20 +42,6 @@ public: TestOrderedSet() = default; private slots: -#if __cplusplus < 202002L - void testContains() const - { - const OrderedSet set {u"a"_s, u"b"_s, u"c"_s}; - QVERIFY(set.contains(u"a"_s)); - QVERIFY(set.contains(u"b"_s)); - QVERIFY(set.contains(u"c"_s)); - QVERIFY(!set.contains(u"z"_s)); - - const OrderedSet emptySet; - QVERIFY(!emptySet.contains(u"a"_s)); - } -#endif - void testCount() const { const OrderedSet set {u"a"_s, u"b"_s, u"c"_s, u"c"_s};