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
This commit is contained in:
Tony Wasserka 2018-06-16 13:36:08 +02:00
parent 0de99b0006
commit f65983c5a7
3 changed files with 52 additions and 21 deletions

View File

@ -0,0 +1,37 @@
#pragma once
#include <functional>
namespace detail {
template<typename T>
struct class_of;
template<typename Ret, typename C>
struct class_of<Ret C::*> {
using type = C;
};
template<typename T>
using class_of_t = typename class_of<T>::type;
template<typename Mem, typename T, typename C = class_of_t<Mem>>
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<typename Mem, typename T>
auto member_equals_fn(Mem mem, T ref) {
return detail::member_equals_fn_helper<Mem, T>{std::move(ref), std::move(mem)};
}

View File

@ -3,6 +3,7 @@
#include <array>
#include <cstdio>
#include "ldr_launch_queue.hpp"
#include "meta_tools.hpp"
static std::array<LaunchQueue::LaunchItem, LAUNCH_QUEUE_SIZE> 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) {

View File

@ -2,6 +2,7 @@
#include <algorithm>
#include <stratosphere/servicesession.hpp>
#include "sm_registration.hpp"
#include "meta_tools.hpp"
static std::array<Registration::Process, REGISTRATION_LIST_MAX_PROCESS> g_process_list = {0};
static std::array<Registration::Service, REGISTRATION_LIST_MAX_SERVICE> 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) {