/** * @file Alignment.h * @author apio (cloudapio.eu) * @brief Functions to align addresses and sizes to specified boundaries. * * @copyright Copyright (c) 2022-2023, the Luna authors. * */ #pragma once #include /** * @brief Check whether a value is aligned to a specific alignment. * * @tparam alignment The alignment to use. It must be provided as a template parameter to help the compiler with * optimizations. For best results, use a power of two. * @tparam T The type of the value. * @param value The value to check. * @return constexpr bool Whether the value is aligned. */ template constexpr inline bool is_aligned(T value) { return (value % alignment == 0); } /** * @brief Find the closest aligned value that is smaller than the value provided. * * @tparam alignment The alignment to use. It must be provided as a template parameter to help the compiler with * optimizations. For best results, use a power of two. * @tparam T The type of the value. * @param value The value to use. * @return constexpr T The aligned value. */ template constexpr inline T align_down(T value) { return value - value % alignment; } /** * @brief Find the closest aligned value that is bigger than the value provided. * * @tparam alignment The alignment to use. It must be provided as a template parameter to help the compiler with * optimizations. For best results, use a power of two. * @tparam T The type of the value. * @param value The value to use. * @return constexpr T The aligned value. */ template constexpr inline T align_up(T value) { if (is_aligned(value)) return value; return align_down(value) + alignment; } /** * @brief Offset a pointer by exactly bytes, no matter the type. * * Generally only useful for pointers to void (or char), because breaking other pointers' alignments is not a good * idea... * * @tparam T The underlying type of the pointer. * @tparam Offset The type of the offset. * @param ptr The pointer to offset. * @param offset The offset to use (depending on the type, this could be negative). * @return constexpr T* The new pointer. */ template constexpr inline T* offset_ptr(T* ptr, Offset offset) { return (T*)((u8*)ptr + offset); }