From f65983c5a73e25dcea9370cfa5779c628ca61324 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 16 Jun 2018 13:36:08 +0200 Subject: [PATCH] Stratosphere: Add a utility predicate function to test for equality with a reference element This can be used to rewrite some common raw loops using algorithms instead --- .../libstratosphere/include/meta_tools.hpp | 37 +++++++++++++++++++ .../loader/source/ldr_launch_queue.cpp | 10 ++--- stratosphere/sm/source/sm_registration.cpp | 26 +++++-------- 3 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 stratosphere/libstratosphere/include/meta_tools.hpp diff --git a/stratosphere/libstratosphere/include/meta_tools.hpp b/stratosphere/libstratosphere/include/meta_tools.hpp new file mode 100644 index 000000000..27da96a58 --- /dev/null +++ b/stratosphere/libstratosphere/include/meta_tools.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace detail { + +template +struct class_of; + +template +struct class_of { + using type = C; +}; + +template +using class_of_t = typename class_of::type; + +template> +struct member_equals_fn_helper { + T ref; + Mem mem_fn; + + bool operator()(const C& val) const { + return (std::mem_fn(mem_fn)(val) == ref); + } + + bool operator()(C&& val) const { + return (std::mem_fn(mem_fn)(std::move(val)) == ref); + } +}; + +} // namespace detail + +template +auto member_equals_fn(Mem mem, T ref) { + return detail::member_equals_fn_helper{std::move(ref), std::move(mem)}; +} diff --git a/stratosphere/loader/source/ldr_launch_queue.cpp b/stratosphere/loader/source/ldr_launch_queue.cpp index cf0cd4fc5..b43e061b4 100644 --- a/stratosphere/loader/source/ldr_launch_queue.cpp +++ b/stratosphere/loader/source/ldr_launch_queue.cpp @@ -3,6 +3,7 @@ #include #include #include "ldr_launch_queue.hpp" +#include "meta_tools.hpp" static std::array g_launch_queue = {0}; @@ -46,12 +47,11 @@ Result LaunchQueue::add_item(const LaunchItem *item) { } int LaunchQueue::get_index(u64 tid) { - for(unsigned int i = 0; i < LAUNCH_QUEUE_SIZE; i++) { - if(g_launch_queue[i].tid == tid) { - return i; - } + auto it = std::find_if(g_launch_queue.begin(), g_launch_queue.end(), member_equals_fn(&LaunchQueue::LaunchItem::tid, tid)); + if (it == g_launch_queue.end()) { + return LAUNCH_QUEUE_FULL; } - return LAUNCH_QUEUE_FULL; + return std::distance(g_launch_queue.begin(), it); } int LaunchQueue::get_free_index(u64 tid) { diff --git a/stratosphere/sm/source/sm_registration.cpp b/stratosphere/sm/source/sm_registration.cpp index 21ba9b674..226a7b192 100644 --- a/stratosphere/sm/source/sm_registration.cpp +++ b/stratosphere/sm/source/sm_registration.cpp @@ -2,6 +2,7 @@ #include #include #include "sm_registration.hpp" +#include "meta_tools.hpp" static std::array g_process_list = {0}; static std::array g_service_list = {0}; @@ -21,12 +22,11 @@ u64 GetServiceNameLength(u64 service) { /* Utilities. */ Registration::Process *Registration::GetProcessForPid(u64 pid) { - for (auto &process : g_process_list) { - if (process.pid == pid) { - return &process; - } + auto process_it = std::find_if(g_process_list.begin(), g_process_list.end(), member_equals_fn(&Process::pid, pid)); + if (process_it == g_process_list.end()) { + return nullptr; } - return NULL; + return &*process_it; } Registration::Process *Registration::GetFreeProcess() { @@ -34,12 +34,11 @@ Registration::Process *Registration::GetFreeProcess() { } Registration::Service *Registration::GetService(u64 service_name) { - for (auto &service : g_service_list) { - if (service.service_name == service_name) { - return &service; - } + auto service_it = std::find_if(g_service_list.begin(), g_service_list.end(), member_equals_fn(&Service::service_name, service_name)); + if (service_it == g_service_list.end()) { + return nullptr; } - return NULL; + return &*service_it; } Registration::Service *Registration::GetFreeService() { @@ -168,12 +167,7 @@ Result Registration::UnregisterProcess(u64 pid) { /* Service management. */ bool Registration::HasService(u64 service) { - for (unsigned int i = 0; i < REGISTRATION_LIST_MAX_SERVICE; i++) { - if (g_service_list[i].service_name == service) { - return true; - } - } - return false; + return std::any_of(g_service_list.begin(), g_service_list.end(), member_equals_fn(&Service::service_name, service)); } Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {