Merge commit '74b13b4d7049f9181b1241195324e85af2d9653a'

This commit is contained in:
2026-05-18 23:28:07 +02:00
5 changed files with 232 additions and 138 deletions
+56
View File
@@ -0,0 +1,56 @@
---
Language: Cpp
BasedOnStyle: LLVM
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: false
AlignTrailingComments: false
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: true
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: true
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakConstructorInitializers: AfterColon
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: false
IndentAccessModifiers: false
AccessModifierOffset: 0
ContinuationIndentWidth: 0
IncludeCategories:
- Regex: '^<.*'
Priority: 1
- Regex: '^".*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseBlocks: true
InsertNewlineAtEOF: true
MacroBlockBegin: ''
MacroBlockEnd: ''
SortIncludes: Never
MaxEmptyLinesToKeep: 2
NamespaceIndentation: Inner
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
TabWidth: 4
IndentWidth: 4
...
+25 -25
View File
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <types.hpp> #include "types.hpp"
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <filesystem> #include <filesystem>
@@ -7,37 +7,37 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
namespace ircolib { namespace ircolib {
static inline std::vector<u8> ReadFileBinary(const std::string &path) { static inline std::vector<u8> read_file_binary(const std::string &path) {
std::ifstream file(path, std::ios::binary); std::ifstream file(path, std::ios::binary);
return {std::istreambuf_iterator{file}, {}}; return {std::istreambuf_iterator{file}, {}};
} }
static inline void WriteFileBinary(const std::vector<u8> &data, const std::string &path) { static inline void write_file_binary(const std::vector<u8> &data, const std::string &path) {
std::ofstream file(path, std::ios::binary); std::ofstream file(path, std::ios::binary);
std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file}); std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file});
} }
static inline void WriteFileBinary(const u8 *data, const size_t size, const std::string &path) { static inline void write_file_binary(const u8 *data, const size_t size, const std::string &path) {
FILE *out = fopen(path.c_str(), "wb"); FILE *out = fopen(path.c_str(), "wb");
fwrite(data, size, 1, out); fwrite(data, size, 1, out);
fclose(out); fclose(out);
} }
template <size_t Size> template <size_t Size>
static inline void WriteFileBinary(const std::array<u8, Size> &data, const std::string &path) { static inline void write_file_binary(const std::array<u8, Size> &data, const std::string &path) {
std::ofstream file(path, std::ios::binary); std::ofstream file(path, std::ios::binary);
std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file}); std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file});
} }
static inline size_t NextPow2(size_t num) { static inline size_t next_pow2(size_t num) {
// Taken from "Bit Twiddling Hacks" by Sean Anderson: // Taken from "Bit Twiddling Hacks" by Sean Anderson:
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--num; --num;
num |= num >> 1; num |= num >> 1;
num |= num >> 2; num |= num >> 2;
num |= num >> 4; num |= num >> 4;
num |= num >> 8; num |= num >> 8;
num |= num >> 16; num |= num >> 16;
return num + 1; return num + 1;
} }
} // namespace Util } // namespace ircolib
+42 -42
View File
@@ -1,106 +1,106 @@
#pragma once #pragma once
#include <cmath> #include <cmath>
#include <types.hpp> #include "types.hpp"
namespace ircolib { namespace ircolib {
static inline auto roundCeil(float f) { static inline auto roundCeil(float f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f); __m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_POS_INF); t = _mm_round_ss(t, t, _MM_FROUND_TO_POS_INF);
return _mm_cvtss_f32(t); return _mm_cvtss_f32(t);
#else #else
return ceilf(f); return ceilf(f);
#endif #endif
} }
static inline auto roundCeil(double f) { static inline auto roundCeil(double f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f); __m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_POS_INF); t = _mm_round_sd(t, t, _MM_FROUND_TO_POS_INF);
return _mm_cvtsd_f64(t); return _mm_cvtsd_f64(t);
#else #else
return ceil(f); return ceil(f);
#endif #endif
} }
static inline auto roundNearest(float f) { static inline auto roundNearest(float f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f); __m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_NEAREST_INT); t = _mm_round_ss(t, t, _MM_FROUND_TO_NEAREST_INT);
return _mm_cvtss_f32(t); return _mm_cvtss_f32(t);
#else #else
return roundf(f); return roundf(f);
#endif #endif
} }
static inline auto roundNearest(double f) { static inline auto roundNearest(double f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f); __m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_NEAREST_INT); t = _mm_round_sd(t, t, _MM_FROUND_TO_NEAREST_INT);
return _mm_cvtsd_f64(t); return _mm_cvtsd_f64(t);
#else #else
return round(f); return round(f);
#endif #endif
} }
static inline auto roundCurrent(float f) { static inline auto roundCurrent(float f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
auto t = _mm_set_ss(f); auto t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_CUR_DIRECTION); t = _mm_round_ss(t, t, _MM_FROUND_CUR_DIRECTION);
return _mm_cvtss_f32(t); return _mm_cvtss_f32(t);
#else #else
return rint(f); return rint(f);
#endif #endif
} }
static inline auto roundCurrent(double f) { static inline auto roundCurrent(double f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
auto t = _mm_set_sd(f); auto t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_CUR_DIRECTION); t = _mm_round_sd(t, t, _MM_FROUND_CUR_DIRECTION);
return _mm_cvtsd_f64(t); return _mm_cvtsd_f64(t);
#else #else
return rint(f); return rint(f);
#endif #endif
} }
static inline auto roundFloor(float f) { static inline auto roundFloor(float f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f); __m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_NEG_INF); t = _mm_round_ss(t, t, _MM_FROUND_TO_NEG_INF);
return _mm_cvtss_f32(t); return _mm_cvtss_f32(t);
#else #else
return floor(f); return floor(f);
#endif #endif
} }
static inline auto roundFloor(double f) { static inline auto roundFloor(double f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f); __m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_NEG_INF); t = _mm_round_sd(t, t, _MM_FROUND_TO_NEG_INF);
return _mm_cvtsd_f64(t); return _mm_cvtsd_f64(t);
#else #else
return floor(f); return floor(f);
#endif #endif
} }
static inline auto roundTrunc(float f) { static inline auto roundTrunc(float f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128 t = _mm_set_ss(f); __m128 t = _mm_set_ss(f);
t = _mm_round_ss(t, t, _MM_FROUND_TO_ZERO); t = _mm_round_ss(t, t, _MM_FROUND_TO_ZERO);
return _mm_cvtss_f32(t); return _mm_cvtss_f32(t);
#else #else
return trunc(f); return trunc(f);
#endif #endif
} }
static inline auto roundTrunc(double f) { static inline auto roundTrunc(double f) {
#ifdef SIMD_SUPPORT #ifdef SIMD_SUPPORT
__m128d t = _mm_set_sd(f); __m128d t = _mm_set_sd(f);
t = _mm_round_sd(t, t, _MM_FROUND_TO_ZERO); t = _mm_round_sd(t, t, _MM_FROUND_TO_ZERO);
return _mm_cvtsd_f64(t); return _mm_cvtsd_f64(t);
#else #else
return trunc(f); return trunc(f);
#endif #endif
} }
} // namespace Util } // namespace ircolib
+84 -70
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <types.hpp> #include "types.hpp"
#include <cstddef>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <bit> #include <bit>
@@ -8,128 +9,143 @@
#include <concepts> #include <concepts>
namespace ircolib { namespace ircolib {
static inline std::vector<u8> IntegralToBuffer(const std::integral auto &val) { static inline std::vector<u8> integral_to_buffer(const std::integral auto &val) {
std::vector<u8> ret{}; std::vector<u8> ret{};
ret.resize(sizeof(val)); ret.resize(sizeof(val));
memcpy(ret.data(), &val, sizeof(val)); memcpy(ret.data(), &val, sizeof(val));
return ret; return ret;
} }
static inline constexpr bool IsInsideRange(const std::integral auto& addr, static inline auto integral_to_slice(const std::integral auto &val) -> std::array<u8, sizeof(val)> {
const std::integral auto& start, std::array<u8, sizeof(val)> ret{};
const std::integral auto& end) {
return addr >= start && addr <= end; memcpy(ret.data(), &val, sizeof(val));
return ret;
}
static inline constexpr bool is_inside_range(const std::integral auto &addr, const std::integral auto &start,
const std::integral auto &end) {
return addr >= start && addr <= end;
} }
template <typename T> template <typename T>
static constexpr inline T ReadAccess(const u8 *data, const u32 index); static constexpr inline T read_access(const u8 *data, const u32 index);
template <typename T> template <typename T>
static constexpr inline T ReadAccess(const std::vector<u8> &data, const u32 index); static constexpr inline T read_access(const std::vector<u8> &data, const u32 index);
template <typename T, size_t Size> template <typename T, size_t Size>
static constexpr inline T ReadAccess(const std::array<u8, Size> &data, const u32 index); static constexpr inline T read_access(const std::array<u8, Size> &data, const u32 index);
template <typename T> template <typename T>
static constexpr inline void WriteAccess(u8 *data, const u32 index, const T val); static constexpr inline void write_access(u8 *data, const u32 index, const T val);
template <typename T> template <typename T>
static constexpr inline void WriteAccess(std::vector<u8> &data, const u32 index, const T val); static constexpr inline void write_access(std::vector<u8> &data, const u32 index, const T val);
template <typename T, size_t Size> template <typename T, size_t Size>
static constexpr inline void WriteAccess(std::array<u8, Size> &data, const u32 index, const T val); static constexpr inline void write_access(std::array<u8, Size> &data, const u32 index, const T val);
template <> template <>
constexpr inline u64 ReadAccess(const u8 *data, const u32 index) { constexpr inline u64 read_access(const u8 *data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]); u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]); u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
const auto& result = static_cast<u64>(hi) << 32 | static_cast<u64>(lo); const auto &result = static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
return result; return result;
} }
template <typename T> template <typename T>
static constexpr inline T ReadAccess(const u8 *data, const u32 index) { static constexpr inline T read_access(const u8 *data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]); return *reinterpret_cast<const T *>(&data[index]);
} }
template <> template <>
constexpr inline u64 ReadAccess(const std::vector<u8> &data, const u32 index) { constexpr inline u64 read_access(const std::vector<u8> &data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]); u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]); u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return (static_cast<u64>(hi) << 32) | static_cast<u64>(lo); return (static_cast<u64>(hi) << 32) | static_cast<u64>(lo);
} }
template <typename T> template <typename T>
static constexpr inline T ReadAccess(const std::vector<u8> &data, const u32 index) { static constexpr inline T read_access(const std::vector<u8> &data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]); return *reinterpret_cast<const T *>(&data[index]);
} }
template <size_t Size> template <size_t Size>
constexpr inline u64 ReadAccess(const std::array<u8, Size> &data, const u32 index) { constexpr inline u64 read_access(const std::array<u8, Size> &data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]); u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]); u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return static_cast<u64>(hi) << 32 | static_cast<u64>(lo); return static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
} }
template <typename T, size_t Size> template <typename T, size_t Size>
static constexpr inline T ReadAccess(const std::array<u8, Size> &data, const u32 index) { static constexpr inline T read_access(const std::array<u8, Size> &data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]); return *reinterpret_cast<const T *>(&data[index]);
} }
template <size_t Size> template <size_t Size>
constexpr inline void WriteAccess(std::array<u8, Size> &data, const u32 index, const u64 val) { constexpr inline void write_access(std::array<u8, Size> &data, const u32 index, const u64 val) {
const u32 hi = val >> 32; const u32 hi = val >> 32;
const u32 lo = val; const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi; *reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo; *reinterpret_cast<u32 *>(&data[index + 4]) = lo;
} }
template <typename T, size_t Size> template <typename T, size_t Size>
static constexpr inline void WriteAccess(std::array<u8, Size> &data, const u32 index, const T val) { static constexpr inline void write_access(std::array<u8, Size> &data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val; *reinterpret_cast<T *>(&data[index]) = val;
} }
template <> template <>
constexpr inline void WriteAccess(std::vector<u8> &data, const u32 index, const u64 val) { constexpr inline void write_access(std::vector<u8> &data, const u32 index, const u64 val) {
const u32 hi = val >> 32; const u32 hi = val >> 32;
const u32 lo = val; const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi; *reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo; *reinterpret_cast<u32 *>(&data[index + 4]) = lo;
} }
template <typename T> template <typename T>
static constexpr inline void WriteAccess(std::vector<u8> &data, const u32 index, const T val) { static constexpr inline void write_access(std::vector<u8> &data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val; *reinterpret_cast<T *>(&data[index]) = val;
} }
template <> template <>
constexpr inline void WriteAccess(u8 *data, const u32 index, const u64 val) { constexpr inline void write_access(u8 *data, const u32 index, const u64 val) {
const u32 hi = val >> 32; const u32 hi = val >> 32;
const u32 lo = val; const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi; *reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo; *reinterpret_cast<u32 *>(&data[index + 4]) = lo;
} }
template <typename T> template <typename T>
static constexpr inline void WriteAccess(u8 *data, const u32 index, const T val) { static constexpr inline void write_access(u8 *data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val; *reinterpret_cast<T *>(&data[index]) = val;
} }
template <typename T> template <typename T>
static constexpr inline void SwapBuffer(std::vector<u8> &data) { static constexpr inline void swap_buffer(std::vector<u8> &data) {
for (size_t i = 0; i < data.size(); i += sizeof(T)) { for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]); const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original); *reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
} }
} }
template <typename T, size_t Size> template <typename T, size_t Size>
static constexpr inline void SwapBuffer(std::array<u8, Size> &data) { static constexpr inline void swap_buffer(std::array<u8, Size> &data) {
for (size_t i = 0; i < data.size(); i += sizeof(T)) { for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]); const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original); *reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
} }
}
template <typename T>
static constexpr inline void swap_buffer(u8 *data, size_t size) {
for (size_t i = 0; i < size; i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
} }
#ifdef _WIN32 #ifdef _WIN32
@@ -137,10 +153,8 @@ inline void *aligned_alloc(const size_t alignment, const size_t size) { return _
inline void aligned_free(void *ptr) { _aligned_free(ptr); } inline void aligned_free(void *ptr) { _aligned_free(ptr); }
#else #else
inline void *aligned_alloc(const size_t alignment, const size_t size) { inline void *aligned_alloc(const size_t alignment, const size_t size) { return std::aligned_alloc(alignment, size); }
return std::aligned_alloc(alignment, size);
}
inline void aligned_free(void *ptr) { std::free(ptr); } inline void aligned_free(void *ptr) { std::free(ptr); }
#endif #endif
} // namespace Util } // namespace ircolib
+25 -1
View File
@@ -10,4 +10,28 @@ using s8 = int8_t;
using s16 = int16_t; using s16 = int16_t;
using s32 = int32_t; using s32 = int32_t;
using s64 = int64_t; using s64 = int64_t;
}
template <typename T, std::size_t bit>
static constexpr bool is_bit_set(const T &val) {
return val & (1 << bit);
}
template <typename T, std::size_t bit>
static constexpr void set_bit(T &val) {
val |= 1 << bit;
}
template <typename T>
inline bool is_bit_set(const T &val, const std::size_t &bit) {
return val & (1 << bit);
}
template <typename T>
inline void set_bit(T &val, const std::size_t &bit) {
val |= 1 << bit;
}
} // namespace ircolib
constexpr ircolib::u32 operator""_kib(const unsigned long long v) { return v * 1024; }
constexpr ircolib::u32 operator""_mib(const unsigned long long v) { return v * 1024 * 1024; }
constexpr ircolib::u32 operator""_gib(const unsigned long long v) { return v * 1024 * 1024 * 1024; }