From e247310dede5ece8b352e87ae9a8977be49cebf2 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 23 Aug 2023 11:04:05 +0200 Subject: [PATCH] libluna: Document Alignment.h --- libluna/include/luna/Alignment.h | 65 ++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/libluna/include/luna/Alignment.h b/libluna/include/luna/Alignment.h index 1f7a65d8..e4b76cd6 100644 --- a/libluna/include/luna/Alignment.h +++ b/libluna/include/luna/Alignment.h @@ -1,37 +1,70 @@ +/** + * @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 #include -template constexpr inline T is_aligned(T value) +/** + * @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); } -static_assert(is_aligned<512>(1024u)); -static_assert(!is_aligned<32>(235u)); -static_assert(is_aligned<4096>(40960u)); - +/** + * @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; } -static_assert(align_down<512>(598ul) == 512ul); -static_assert(align_down<64>(194ul) == 192ul); -static_assert(align_down<32>(64ul) == 64ul); - +/** + * @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; } -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 bytes, no matter the type. Useful to avoid the quirks that come from C pointer -// arithmetic. +/** + * @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);