2022-11-16 19:02:04 +00:00
|
|
|
#pragma once
|
2022-12-17 12:50:27 +00:00
|
|
|
#include <luna/TypeTraits.h>
|
2022-12-18 15:30:27 +00:00
|
|
|
#include <luna/Types.h>
|
2022-11-16 19:02:04 +00:00
|
|
|
|
2023-03-07 19:37:30 +00:00
|
|
|
template <usize alignment, typename T> constexpr inline T is_aligned(T value)
|
2022-11-16 19:02:04 +00:00
|
|
|
{
|
2022-11-18 17:02:38 +00:00
|
|
|
return (value % alignment == 0);
|
2022-11-16 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2022-12-08 14:09:32 +00:00
|
|
|
static_assert(is_aligned<512>(1024u));
|
|
|
|
static_assert(!is_aligned<32>(235u));
|
|
|
|
static_assert(is_aligned<4096>(40960u));
|
2022-11-18 16:59:19 +00:00
|
|
|
|
2023-03-07 19:37:30 +00:00
|
|
|
template <usize alignment, typename T> constexpr inline T align_down(T value)
|
2022-11-16 19:02:04 +00:00
|
|
|
{
|
2022-12-06 18:27:58 +00:00
|
|
|
return value - value % alignment;
|
2022-11-16 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2022-12-08 14:09:32 +00:00
|
|
|
static_assert(align_down<512>(598ul) == 512ul);
|
|
|
|
static_assert(align_down<64>(194ul) == 192ul);
|
|
|
|
static_assert(align_down<32>(64ul) == 64ul);
|
2022-11-18 16:59:19 +00:00
|
|
|
|
2023-03-07 19:37:30 +00:00
|
|
|
template <usize alignment, typename T> constexpr inline T align_up(T value)
|
2022-11-16 19:02:04 +00:00
|
|
|
{
|
2022-12-06 18:27:58 +00:00
|
|
|
if (is_aligned<alignment>(value)) return value;
|
|
|
|
return align_down<alignment>(value) + alignment;
|
2022-11-16 19:02:04 +00:00
|
|
|
}
|
|
|
|
|
2022-12-08 14:09:32 +00:00
|
|
|
static_assert(align_up<512>(598ul) == 1024ul);
|
|
|
|
static_assert(align_up<64>(194ul) == 256ul);
|
|
|
|
static_assert(align_up<32>(64ul) == 64ul);
|
2022-11-18 16:59:19 +00:00
|
|
|
|
2022-11-16 19:02:04 +00:00
|
|
|
template <typename T> constexpr T get_blocks_from_size(T value, T block_size)
|
|
|
|
{
|
|
|
|
return (value + (block_size - 1)) / block_size;
|
2022-11-18 16:59:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static_assert(get_blocks_from_size(40960, 4096) == 10);
|
|
|
|
static_assert(get_blocks_from_size(194, 64) == 4);
|
|
|
|
static_assert(get_blocks_from_size(2, 32) == 1);
|
2022-11-20 14:12:18 +00:00
|
|
|
static_assert(get_blocks_from_size(0, 256) == 0);
|
|
|
|
|
|
|
|
// Offset a pointer by exactly <offset> bytes, no matter the type. Useful to avoid the quirks that come from C pointer
|
|
|
|
// arithmetic.
|
2023-03-07 19:37:30 +00:00
|
|
|
template <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
|
2022-11-20 14:12:18 +00:00
|
|
|
{
|
2023-01-16 18:52:34 +00:00
|
|
|
return (T*)((u8*)ptr + offset);
|
2023-01-02 12:07:29 +00:00
|
|
|
}
|