Luna/luna/Alignment.h

46 lines
1.3 KiB
C
Raw Normal View History

#pragma once
2022-11-18 17:02:38 +00:00
template <typename T> constexpr T is_aligned(T value, T alignment)
{
2022-11-18 17:02:38 +00:00
return (value % alignment == 0);
}
static_assert(is_aligned(1024, 512));
static_assert(!is_aligned(235, 32));
static_assert(is_aligned(40960, 4096));
2022-11-18 17:02:38 +00:00
template <typename T> constexpr T align_down(T value, T alignment)
{
2022-11-18 17:02:38 +00:00
return value - (value % alignment);
}
static_assert(align_down(598, 512) == 512);
static_assert(align_down(194, 64) == 192);
static_assert(align_down(62, 31) == 62);
2022-11-18 17:02:38 +00:00
template <typename T> constexpr T align_up(T value, T alignment)
{
2022-11-18 17:02:38 +00:00
if (is_aligned(value, alignment)) return value;
return align_down(value, alignment) + alignment;
}
static_assert(align_up(598, 512) == 1024);
static_assert(align_up(194, 64) == 256);
static_assert(align_up(62, 31) == 62);
template <typename T> constexpr T get_blocks_from_size(T value, T block_size)
{
return (value + (block_size - 1)) / block_size;
}
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);
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.
template <typename T, typename Offset> constexpr T* offset_ptr(T* ptr, Offset offset)
{
return (T*)((char*)ptr + offset);
}