diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 81431e564c..d7262eaa4e 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(common Config/Enums.h Config/Layer.cpp Config/Layer.h + Contains.h CPUDetect.h Crypto/AES.cpp Crypto/AES.h diff --git a/Source/Core/Common/Contains.h b/Source/Core/Common/Contains.h new file mode 100644 index 0000000000..f707cb0f82 --- /dev/null +++ b/Source/Core/Common/Contains.h @@ -0,0 +1,61 @@ +// Copyright 2025 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +namespace Common +{ +struct ContainsFn +{ + template S, class T, class Proj = std::identity> + requires std::indirect_binary_predicate < std::ranges::equal_to, std::projected, + const T* > constexpr bool operator()(I first, S last, const T& value, Proj proj = {}) const + { + return std::ranges::find(std::move(first), last, value, std::move(proj)) != last; + } + + template + requires std::indirect_binary_predicate < std::ranges::equal_to, + std::projected, Proj>, + const T* > constexpr bool operator()(R&& r, const T& value, Proj proj = {}) const + { + return (*this)(std::ranges::begin(r), std::ranges::end(r), value, std::move(proj)); + } +}; + +struct ContainsSubrangeFn +{ + template S1, std::forward_iterator I2, + std::sentinel_for S2, class Pred = std::ranges::equal_to, + class Proj1 = std::identity, class Proj2 = std::identity> + requires std::indirectly_comparable + constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}) const + { + return !std::ranges::search(std::move(first1), std::move(last1), std::move(first2), + std::move(last2), std::move(pred), std::move(proj1), + std::move(proj2)) + .empty(); + } + + template + requires std::indirectly_comparable, std::ranges::iterator_t, + Pred, Proj1, Proj2> + constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, + Proj2 proj2 = {}) const + { + return (*this)(std::ranges::begin(r1), std::ranges::end(r1), std::ranges::begin(r2), + std::ranges::end(r2), std::move(pred), std::move(proj1), std::move(proj2)); + } +}; + +// TODO C++23: Replace with std::ranges::contains. +inline constexpr ContainsFn Contains{}; +// TODO C++23: Replace with std::ranges::contains_subrange. +inline constexpr ContainsSubrangeFn ContainsSubrange{}; +} // namespace Common diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index a61f0d822a..e41e9fc26a 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -38,6 +38,7 @@ +