diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index 4c595717050..629ca17a1dd 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -241,6 +241,71 @@ struct set_greedy_difference_functor inline constexpr set_greedy_difference_functor set_greedy_difference{}; +struct set_difference_functor +{ + template Sentinel1, + std::input_iterator Iterator2, + std::sentinel_for Sentinel2, + std::invocable &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable + constexpr void operator()(Iterator1 first1, + Sentinel1 last1, + Iterator2 first2, + Sentinel2 last2, + Callable &&callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + while (first1 != last1 && first2 != last2) { + if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) { + std::invoke(callable, *first1); + ++first1; + } else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) { + ++first2; + } else { + ++first1; + ++first2; + } + } + + while (first1 != last1) { + std::invoke(callable, *first1); + ++first1; + } + } + + template &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> + constexpr void operator()(Range1 &&range1, + Range2 &&range2, + Callable &&callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + (*this)(std::ranges::begin(range1), + std::ranges::end(range1), + std::ranges::begin(range2), + std::ranges::end(range2), + std::forward(callable), + std::move(comp), + std::move(proj1), + std::move(proj2)); + } +}; + +inline constexpr set_difference_functor set_difference{}; + struct set_has_common_element_functor { template #include +#include + namespace QmlDesigner { using PropertyName = QByteArray; using PropertyNameView = QByteArrayView; @@ -40,7 +42,7 @@ constexpr bool useProjectStorage() #endif } class SourcePathStorage; -using PathCache = SourcePathCache; +using PathCache = SourcePathCache; #ifdef QDS_MODEL_USE_PROJECTSTORAGEINTERFACE using ProjectStorageType = ProjectStorageInterface; @@ -48,7 +50,7 @@ class SourcePathCacheInterface; using PathCacheType = SourcePathCacheInterface; #else using ProjectStorageType = ProjectStorage; -using PathCacheType = SourcePathCache; +using PathCacheType = SourcePathCache; #endif struct ProjectStorageDependencies diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index 1e6d287abe2..41368208a69 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -284,10 +284,13 @@ private: friend ModuleStorageAdapter; - static bool moduleNameLess(ModuleView first, ModuleView second) noexcept + struct ModuleNameLess { - return first < second; - } + bool operator()(ModuleView first, ModuleView second) const noexcept + { + return first < second; + } + }; class ModuleCacheEntry : public StorageCacheEntry { @@ -314,7 +317,7 @@ private: using ModuleCacheEntries = std::vector; using ModuleCache - = StorageCache; + = StorageCache; ModuleId fetchModuleId(Utils::SmallStringView moduleName, Storage::ModuleKind moduleKind); diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h index cc7d0a89f98..c6808097350 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h @@ -142,27 +142,38 @@ private: Storage &storage; }; - static bool sourceLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept + struct SourceNameLess { - return std::lexicographical_compare(first.rbegin(), - first.rend(), - second.rbegin(), - second.rend()); - } + bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const noexcept + { + return first < second; + } + }; + + struct SourceContextLess + { + bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const noexcept + { + return std::ranges::lexicographical_compare(first.rbegin(), + first.rend(), + second.rbegin(), + second.rend()); + } + }; using SourceContextPathCache = StorageCache; - using SourceNameCache = StorageCache; private: diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h index 1a3e3ec3a05..07ac6ff52f9 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h @@ -33,7 +33,7 @@ template> class StorageCache { @@ -140,17 +140,11 @@ public: { m_entries = m_storage.fetchAll(); - std::sort(m_entries.begin(), m_entries.end(), [](ViewType first, ViewType second) { - return compare(first, second); - }); + std::ranges::sort(m_entries, Compare{}); std::size_t max_id = 0; - auto found = std::max_element(m_entries.begin(), - m_entries.end(), - [](const auto &first, const auto &second) { - return first.id < second.id; - }); + auto found = std::ranges::max_element(m_entries, {}, &CacheEntry::id); if (found != m_entries.end()) max_id = static_cast(found->id); @@ -162,31 +156,25 @@ public: void add(std::vector &&views) { - auto less = [](ViewType first, ViewType second) { return compare(first, second); }; + std::ranges::sort(views, Compare{}); - std::sort(views.begin(), views.end(), less); - - views.erase(std::unique(views.begin(), views.end()), views.end()); + auto removed = std::ranges::unique(views.begin(), views.end()); + views.erase(removed.begin(), removed.end()); CacheEntries newCacheEntries; newCacheEntries.reserve(views.size()); - std::set_difference(views.begin(), - views.end(), - m_entries.begin(), - m_entries.end(), - Utils::make_iterator([&](ViewType newView) { - IndexType index = m_storage.fetchId(newView); - newCacheEntries.emplace_back(newView, index); - }), - less); + Utils::set_difference( + views, + m_entries, + [&](ViewType newView) { + IndexType index = m_storage.fetchId(newView); + newCacheEntries.emplace_back(newView, index); + }, + Compare{}); if (newCacheEntries.size()) { - auto found = std::max_element(newCacheEntries.begin(), - newCacheEntries.end(), - [](const auto &first, const auto &second) { - return first.id < second.id; - }); + auto found = std::ranges::max_element(newCacheEntries, {}, &CacheEntry::id); auto max_id = static_cast(found->id); @@ -196,12 +184,12 @@ public: CacheEntries mergedCacheEntries; mergedCacheEntries.reserve(newCacheEntries.size() + m_entries.size()); - std::merge(std::make_move_iterator(m_entries.begin()), - std::make_move_iterator(m_entries.end()), - std::make_move_iterator(newCacheEntries.begin()), - std::make_move_iterator(newCacheEntries.end()), - std::back_inserter(mergedCacheEntries), - less); + std::ranges::merge(std::make_move_iterator(m_entries.begin()), + std::make_move_iterator(m_entries.end()), + std::make_move_iterator(newCacheEntries.begin()), + std::make_move_iterator(newCacheEntries.end()), + std::back_inserter(mergedCacheEntries), + Compare{}); m_entries = std::move(mergedCacheEntries); @@ -221,7 +209,7 @@ public: sharedLock.unlock(); std::lock_guard exclusiveLock(m_mutex); - if (!std::is_base_of::value) + if constexpr (!std::is_base_of_v) found = find(view); if (found == m_entries.end()) found = insertEntry(found, view, m_storage.fetchId(view)); @@ -235,7 +223,7 @@ public: std::vector ids; ids.reserve(values.size()); - std::transform(values.begin(), values.end(), std::back_inserter(ids), [&](const auto &values) { + std::ranges::transform(values, std::back_inserter(ids), [&](const auto &values) { return this->id(values); }); @@ -252,9 +240,9 @@ public: std::shared_lock sharedLock(m_mutex); if (IndexType::create(static_cast(m_indices.size()) + 1) > id) { - if (StorageCacheIndex indirectionIndex = m_indices.at(static_cast(id) - 1); + if (StorageCacheIndex indirectionIndex = m_indices[static_cast(id) - 1]; indirectionIndex.isValid()) { - return m_entries.at(static_cast(indirectionIndex)).value; + return m_entries[static_cast(indirectionIndex)].value; } } @@ -276,9 +264,7 @@ public: for (IndexType id : ids) { values.emplace_back( - m_entries - .at(static_cast(m_indices.at(static_cast(id) - 1))) - .value); + m_entries[static_cast(m_indices[static_cast(id) - 1])].value); } return values; } @@ -306,19 +292,10 @@ private: template static auto find(Entries &&entries, ViewType view) { - auto begin = entries.begin(); - auto end = entries.end(); - auto found = std::lower_bound(begin, end, view, compare); + auto found = std::ranges::lower_bound(entries, view, Compare{}); - if (found == entries.end()) { - return entries.end(); - } - - const auto &value = *found; - - if (value == view) { + if (found != entries.end() && *found == view) return found; - } return entries.end(); } @@ -329,9 +306,8 @@ private: auto found = find(view); - if (found != m_entries.end()) { + if (found != m_entries.end()) return found->id; - } return IndexType(); } @@ -341,9 +317,9 @@ private: std::shared_lock sharedLock(m_mutex); if (IndexType::create(static_cast(m_indices.size()) + 1) > id) { - if (StorageCacheIndex indirectionIndex = m_indices.at(static_cast(id) - 1); + if (StorageCacheIndex indirectionIndex = m_indices[static_cast(id) - 1]; indirectionIndex.isValid()) { - return m_entries.at(static_cast(indirectionIndex)).value; + return m_entries[static_cast(indirectionIndex)].value; } } @@ -377,7 +353,7 @@ private: auto indirectionIndex = static_cast(id) - 1; ensureSize(indirectionIndex); - m_indices.at(indirectionIndex) = newIndirectionIndex; + m_indices[indirectionIndex] = newIndirectionIndex; return inserted; } diff --git a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h index a74c782f634..4ee78b4fa93 100644 --- a/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h +++ b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h @@ -9,12 +9,6 @@ namespace QmlDesigner { class NonLockingMutex; -template +template class StorageCache; } // namespace QmlDesigner diff --git a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp index 4b4850e26ae..61e2d4efde6 100644 --- a/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp @@ -30,9 +30,12 @@ public: ProjectStorageMock &storage; }; -auto less(Utils::SmallStringView first, Utils::SmallStringView second) -> bool +struct Less { - return Utils::compare(first, second) < 0; + bool operator()(Utils::SmallStringView first, Utils::SmallStringView second) const + { + return Utils::compare(first, second) < 0; + } }; using CacheWithMockLocking = QmlDesigner::StorageCache, - less, + Less, QmlDesigner::Cache::SourceContext>; using CacheWithoutLocking = QmlDesigner::StorageCache, - less, + Less, QmlDesigner::Cache::SourceContext>; template