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/TypeTraits.h>
#include <luna/Types.h> #include <luna/Types.h>
// Must ALWAYS be called with a power of two as alignment. template <usize alignment, typename T> constexpr inline T is_aligned(T value)
template <usize alignment, typename T> constexpr T is_aligned(T value)
{ {
static_assert(IsPowerOfTwo<usize, alignment>);
return (value % alignment == 0); return (value % alignment == 0);
} }
@ -13,10 +11,8 @@ static_assert(is_aligned<512>(1024u));
static_assert(!is_aligned<32>(235u)); static_assert(!is_aligned<32>(235u));
static_assert(is_aligned<4096>(40960u)); static_assert(is_aligned<4096>(40960u));
// Must ALWAYS be called with a power of two as alignment. template <usize alignment, typename T> constexpr inline T align_down(T value)
template <usize alignment, typename T> constexpr T align_down(T value)
{ {
static_assert(IsPowerOfTwo<usize, alignment>);
return value - value % 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<64>(194ul) == 192ul);
static_assert(align_down<32>(64ul) == 64ul); static_assert(align_down<32>(64ul) == 64ul);
// Must ALWAYS be called with a power of two as alignment. template <usize alignment, typename T> constexpr inline T align_up(T value)
template <usize alignment, typename T> constexpr T align_up(T value)
{ {
if (is_aligned<alignment>(value)) return value; if (is_aligned<alignment>(value)) return value;
return align_down<alignment>(value) + alignment; 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 // Offset a pointer by exactly <offset> bytes, no matter the type. Useful to avoid the quirks that come from C pointer
// arithmetic. // 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); return (T*)((u8*)ptr + offset);
} }