geode/loader/include/Geode/utils/map.hpp

123 lines
3.7 KiB
C++
Raw Normal View History

2022-07-30 12:24:03 -04:00
#pragma once
#include "Result.hpp"
2022-10-30 14:59:20 -04:00
#include <Geode/DefaultInclude.hpp>
2022-07-30 12:24:03 -04:00
#include <functional>
2022-10-30 14:59:20 -04:00
#include <string>
2022-07-30 12:24:03 -04:00
#include <unordered_map>
2022-10-30 14:59:20 -04:00
#include <vector>
2022-07-30 12:24:03 -04:00
2022-10-30 14:59:20 -04:00
namespace geode::utils::map {
2022-07-30 12:24:03 -04:00
/**
* Returns true if the map contains
* a value matching `containFunc`.
* @param map Map to check
* @param containFunc Predicate run against each value in map;
* return true if the item matches what is
* beeing looked for, and false if not.
* @returns True if value matching `containFunc` was found,
* false if not.
*/
2024-06-05 16:47:16 -04:00
template <typename T, typename R, typename H>
2024-11-04 12:42:09 -05:00
bool contains(std::unordered_map<T, R, H> const& map, std::function<bool(R)> containFunc) {
2022-07-30 12:24:03 -04:00
for (auto const& [_, r] : map) {
2022-10-30 14:59:20 -04:00
if (containFunc(r)) return true;
2022-07-30 12:24:03 -04:00
}
return false;
}
/**
* Get the first item in a map that
* matches `selectFunc`.
* @param map Map to check
* @param selectFunc Predicate run against each value in map;
* return true if the item matches what is
* beeing looked for, and false if not.
* @returns The value matching `selectFunc` if one was found,
* otherwise the default value for type R or `nullptr` if R is
* a pointer.
*/
2024-06-05 16:47:16 -04:00
template <class T, class R, class H>
2024-11-04 12:42:09 -05:00
R select(std::unordered_map<T, R, H> const& map, std::function<bool(R)> selectFunc) {
2022-07-30 12:24:03 -04:00
for (auto const& [_, r] : map) {
2022-10-30 14:59:20 -04:00
if (selectFunc(r)) return r;
2022-07-30 12:24:03 -04:00
}
if (std::is_pointer<R>::value) {
return nullptr;
}
return R();
}
/**
* Get all items in a map that match `selectFunc`.
* @param map Map to check
* @param selectFunc Predicate run against each value in map;
* return true if the item matches what is
* beeing looked for, and false if not.
* @returns Vector of all values that matched.
*/
2024-06-05 16:47:16 -04:00
template <class T, class R, class H>
2022-07-30 12:24:03 -04:00
std::vector<R> selectAll(
2024-11-04 12:42:09 -05:00
std::unordered_map<T, R, H> const& map, std::function<bool(R)> selectFunc
2022-07-30 12:24:03 -04:00
) {
std::vector<R> res;
for (auto const& [_, r] : map) {
if (selectFunc(r)) {
res.push_back(r);
}
}
return res;
}
/**
* Get all values in a map.
* @param map Map to get values from
* @returns Vector of all values.
*/
2024-06-05 16:47:16 -04:00
template <class T, class R, class H>
std::vector<R> values(std::unordered_map<T, R, H> const& map) {
2022-07-30 12:24:03 -04:00
std::vector<R> res;
for (auto const& [_, r] : map) {
res.push_back(r);
}
return res;
}
/**
* Get all keys in a map.
* @param map Map to get keys from
* @returns Vector of all keys.
*/
2024-06-05 16:47:16 -04:00
template <class T, class R, class H>
std::vector<T> keys(std::unordered_map<T, R, H> const& map) {
2022-07-30 12:24:03 -04:00
std::vector<T> res;
for (auto const& [t, _] : map) {
res.push_back(t);
}
return res;
}
/**
* Transform an unordered_map into
* another unordered_map of a different
* type.
* @param map Map to convert
2022-10-30 14:59:20 -04:00
* @param remapFunc Function that converts
* key-value pairs from the first map to
2022-07-30 12:24:03 -04:00
* the second
* @returns New map
*/
2024-06-05 16:47:16 -04:00
template <class T1, class V1, class H1, class T2, class V2, class H2>
std::unordered_map<T2, V2, H2> remap(
std::unordered_map<T1, V1, H1> const& map,
2024-11-04 12:42:09 -05:00
std::function<std::pair<T2, V2>(std::pair<T1, V1>)> remapFunc
2022-07-30 12:24:03 -04:00
) {
2024-06-05 16:47:16 -04:00
std::unordered_map<T2, V2, H2> res;
2022-07-30 12:24:03 -04:00
for (auto const& [t, v] : map) {
res.insert(remapFunc({ t, v }));
}
return res;
}
}