Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/engine/utility/include/utility.hpp

134 lines
3.8 KiB
C++
Raw Normal View History

2020-08-11 12:07:21 -04:00
#pragma once
#include <magic_enum.hpp>
#include <algorithm>
#include <cmath>
2020-08-11 12:07:21 -04:00
#include <random>
#include <unordered_map>
#include <vector>
2020-08-11 12:07:21 -04:00
#include "vector.hpp"
2020-08-11 12:07:21 -04:00
namespace utility {
template<class Enum> std::string enum_to_string(const Enum e) {
2020-08-11 12:07:21 -04:00
const std::string_view name = magic_enum::enum_name(e);
2020-08-11 12:07:21 -04:00
std::string s = name.data();
return s.substr(0, name.length());
}
template<class T, class F> void erase_if(std::vector<T>& vec, const F& f) {
vec.erase(std::remove_if(vec.begin(), vec.end(), f), vec.end());
2020-08-11 12:07:21 -04:00
}
template<class T, class V> void erase(T& vec, const V& t) {
2020-08-11 12:07:21 -04:00
vec.erase(std::remove(vec.begin(), vec.end(), t), vec.end());
}
template<class T> void erase_at(std::vector<T>& vec, const int index) {
2020-08-11 12:07:21 -04:00
vec.erase(vec.begin() + index);
}
inline int get_random(const int min, const int max) {
std::random_device rd;
std::mt19937 eng(rd());
std::uniform_int_distribution<> distr(min, max);
return distr(eng);
}
inline int get_random(const int max) {
return get_random(0, max);
}
template<class T> inline auto get_random(const std::vector<T>& vec) {
2020-08-11 12:07:21 -04:00
return vec[get_random(static_cast<int>(vec.size() - 1))];
}
template<class T, size_t S> inline auto get_random(const std::array<T, S>& vec) {
2020-08-11 12:07:21 -04:00
return vec[get_random(static_cast<int>(vec.size() - 1))];
}
template<class T, class V> inline auto get_random(const std::unordered_map<T, V>& map) {
2020-08-11 12:07:21 -04:00
const auto item = map.begin();
std::advance(item, get_random(static_cast<int>(map.size() - 1)));
return item;
}
template<
class T,
class TIter = decltype(std::begin(std::declval<T>())),
class = decltype(std::end(std::declval<T>()))>
constexpr auto enumerate(T&& iterable) {
2020-08-11 12:07:21 -04:00
struct iterator {
size_t i;
TIter iter;
bool operator!=(const iterator& other) const {
return iter != other.iter;
}
void operator++() {
++i;
++iter;
}
auto operator*() const {
return std::tie(i, *iter);
}
2020-08-11 12:07:21 -04:00
};
2020-08-11 12:07:21 -04:00
struct iterable_wrapper {
T iterable;
auto begin() {
return iterator{0, std::begin(iterable)};
}
auto end() {
return iterator{0, std::end(iterable)};
}
2020-08-11 12:07:21 -04:00
};
return iterable_wrapper{std::forward<T>(iterable)};
2020-08-11 12:07:21 -04:00
}
template<class T, class V> inline bool contains(const std::vector<T>& vec, const V& val) {
2020-08-11 12:07:21 -04:00
return std::count(vec.begin(), vec.end(), val);
}
/// Packs two 16-bit unsigned ints into one 32 bit unsigned integer.
inline uint32_t pack_u32(const uint16_t a, const uint16_t b) {
return (b << 16) | a;
}
2020-08-11 12:07:21 -04:00
/// Converts a floating-point to a fixed 16-bit unsigned integer.
inline uint16_t to_fixed(const float f) {
return static_cast<uint16_t>(32.0f * f + 0.5f);
}
2021-05-12 09:56:44 -04:00
inline prism::float3 from_srgb_to_linear(const prism::float3 sRGB) {
prism::float3 linear = sRGB;
for (auto& component : linear.data) {
if (component > 0.04045f) {
2021-02-15 15:06:13 -05:00
component = std::pow((component + 0.055) / (1.055), 2.4f);
} else if (component <= 0.04045) {
component /= 12.92f;
}
}
return linear;
}
template<typename T, typename F> inline void move_to_front(std::vector<T>& vec, F func) {
auto result = std::find_if(vec.begin(), vec.end(), func);
if (result != vec.end()) {
auto value = *result;
vec.erase(result);
vec.insert(vec.begin(), value);
}
}
} // namespace utility