libluna: Document Alignment.h
This commit is contained in:
parent
a35ca0b367
commit
e247310ded
@ -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 <luna/TypeTraits.h>
|
||||
#include <luna/Types.h>
|
||||
|
||||
template <usize alignment, typename T> 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 <usize alignment, typename T> 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 <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);
|
||||
|
||||
/**
|
||||
* @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 <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.
|
||||
/**
|
||||
* @brief Offset a pointer by exactly <offset> 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 <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
|
||||
{
|
||||
return (T*)((u8*)ptr + offset);
|
||||
|
Loading…
Reference in New Issue
Block a user