diff --git a/rpcs3/Emu/RSX/Common/simple_array.hpp b/rpcs3/Emu/RSX/Common/simple_array.hpp index 4b5ceac877..69397291f9 100644 --- a/rpcs3/Emu/RSX/Common/simple_array.hpp +++ b/rpcs3/Emu/RSX/Common/simple_array.hpp @@ -50,6 +50,12 @@ namespace rsx { c.size() } -> std::integral; }; + template + concept is_trivially_comparable_v = + requires (T t1, U t2) { + { t1 == t2 } -> std::same_as; + }; + template requires std::is_trivially_destructible_v && std::is_trivially_copyable_v struct simple_array @@ -492,6 +498,50 @@ namespace rsx return false; } + /** + * Note that find and find_if return pointers to objects and not iterators for simplified usage. + * It is functionally equivalent to retrieve a nullptr meaning empty object stored and nullptr meaning not found for all practical uses of this container. + */ + template + requires is_trivially_comparable_v + Ty* find(const T& value) + { + for (auto it = begin(); it != end(); ++it) + { + if (*it == value) + { + return &(*it); + } + } + return nullptr; + } + + // Remove when we switch to C++23 + template + requires is_trivially_comparable_v + const Ty* find(const T& value) const + { + return const_cast*>(this)->find(value); + } + + Ty* find_if(std::predicate auto predicate) + { + for (auto it = begin(); it != end(); ++it) + { + if (std::invoke(predicate, *it)) + { + return &(*it); + } + } + return nullptr; + } + + // Remove with C++23 + const Ty* find_if(std::predicate auto predicate) const + { + return const_cast*>(this)->find_if(predicate); + } + bool erase_if(std::predicate auto predicate) { if (!_size)