#pragma once #include <luna/TypeTraits.h> #include <luna/Types.h> template <usize alignment, typename T> constexpr inline T is_aligned(T value) { return (value % alignment == 0); } static_assert(is_aligned<512>(1024u)); static_assert(!is_aligned<32>(235u)); static_assert(is_aligned<4096>(40960u)); template <usize alignment, typename T> constexpr inline T align_down(T value) { return value - value % alignment; } static_assert(align_down<512>(598ul) == 512ul); static_assert(align_down<64>(194ul) == 192ul); static_assert(align_down<32>(64ul) == 64ul); 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; } static_assert(align_up<512>(598ul) == 1024ul); static_assert(align_up<64>(194ul) == 256ul); static_assert(align_up<32>(64ul) == 64ul); // 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 inline T* offset_ptr(T* ptr, Offset offset) { return (T*)((u8*)ptr + offset); }