81 lines
2.5 KiB
C++
81 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <optional>
|
|
#include <bit>
|
|
|
|
namespace utility {
|
|
|
|
// This is a base class for a generic store for some value that can be represented by
|
|
// type T but should not be type checked as type T, but rather some more constrained class.
|
|
template <class T>
|
|
struct Store {
|
|
static_assert(std::is_trivial_v<T>);
|
|
T value;
|
|
friend constexpr auto operator<=>(const Store &, const Store &) noexcept = default;
|
|
};
|
|
|
|
// Convert a fourcc literal (e.g. "LITR" to a uint32_t)
|
|
constexpr uint32_t fourcc_lit_to_val(const char(&a)[5]) noexcept
|
|
{
|
|
char temp[4] = { a[0], a[1], a[2], a[3] };
|
|
return std::bit_cast<uint32_t, char[4]>(temp);
|
|
}
|
|
|
|
// Convert a builtin array to a std::array
|
|
template <typename T, std::size_t N>
|
|
constexpr std::array<T, N> array_builtin_to_std(const T(&builtin)[N]) noexcept
|
|
{
|
|
std::array<T, N> array;
|
|
std::copy(std::cbegin(builtin), std::cend(builtin), array.begin());
|
|
return array;
|
|
}
|
|
|
|
template <typename First, typename Second, std::size_t N>
|
|
constexpr std::pair<std::array<First, N>, std::array<Second, N>> map_to_soa(std::array<std::pair<First, Second>, N> map) noexcept
|
|
{
|
|
std::array<First, N> first;
|
|
std::array<Second, N> second;
|
|
for (std::size_t i = 0; i != N; ++i) {
|
|
first[i] = map[i].first;
|
|
second[i] = map[i].second;
|
|
}
|
|
return std::make_pair(first, second);
|
|
}
|
|
|
|
template <typename First, typename Second, std::size_t N>
|
|
constexpr std::optional<Second> soa_first_to_second(const std::pair<std::array<First, N>, std::array<Second, N>> &soa, const First &first) noexcept
|
|
{
|
|
auto lhs = std::find(soa.first.cbegin(), soa.first.cend(), first);
|
|
if (lhs == soa.first.cend())
|
|
return {};
|
|
auto index = std::distance(soa.first.cbegin(), lhs);
|
|
return { soa.second[index] };
|
|
}
|
|
|
|
template <typename First, typename Second, std::size_t N>
|
|
constexpr std::optional<First> soa_second_to_first(const std::pair<std::array<First, N>, std::array<Second, N>> &soa, const Second &second) noexcept
|
|
{
|
|
auto lhs = std::find(soa.second.cbegin(), soa.second.cend(), second);
|
|
if (lhs == soa.second.cend())
|
|
return {};
|
|
auto index = std::distance(soa.second.cbegin(), lhs);
|
|
return { soa.first[index] };
|
|
}
|
|
|
|
// Used to inspect type sizes and values at compile time. Example:
|
|
//
|
|
// TS<sizeof(Type)> x = 0;
|
|
//
|
|
// or
|
|
//
|
|
// TD<Type> x = 0;
|
|
template<size_t X>
|
|
class TS;
|
|
|
|
template<typename T>
|
|
class TD;
|
|
|
|
}
|
|
|