libluna: Let Alignment.h functions take non-powers-of-two

Since the alignment must be known at compile-time, the compiler will optimize for powers of two and leave an inefficient implementation for other values.
This commit is contained in:
apio 2023-03-07 20:37:30 +01:00
parent 80492f6ad3
commit eaed109fe9
Signed by: apio
GPG Key ID: B8A7D06E42258954

View File

@ -2,10 +2,8 @@
#include <luna/TypeTraits.h>
#include <luna/Types.h>
// Must ALWAYS be called with a power of two as alignment.
template <usize alignment, typename T> constexpr T is_aligned(T value)
template <usize alignment, typename T> constexpr inline T is_aligned(T value)
{
static_assert(IsPowerOfTwo<usize, alignment>);
return (value % alignment == 0);
}
@ -13,10 +11,8 @@ static_assert(is_aligned<512>(1024u));
static_assert(!is_aligned<32>(235u));
static_assert(is_aligned<4096>(40960u));
// Must ALWAYS be called with a power of two as alignment.
template <usize alignment, typename T> constexpr T align_down(T value)
template <usize alignment, typename T> constexpr inline T align_down(T value)
{
static_assert(IsPowerOfTwo<usize, alignment>);
return value - value % alignment;
}
@ -24,8 +20,7 @@ static_assert(align_down<512>(598ul) == 512ul);
static_assert(align_down<64>(194ul) == 192ul);
static_assert(align_down<32>(64ul) == 64ul);
// Must ALWAYS be called with a power of two as alignment.
template <usize alignment, typename T> constexpr T align_up(T value)
template <usize alignment, typename T> constexpr inline T align_up(T value)
{
if (is_aligned<alignment>(value)) return value;
return align_down<alignment>(value) + alignment;
@ -47,7 +42,7 @@ 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)
template <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
{
return (T*)((u8*)ptr + offset);
}