Luna/libluna/include/luna/Alignment.h

72 lines
2.3 KiB
C++

/**
* @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/Types.h>
/**
* @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);
}
/**
* @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;
}
/**
* @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;
}
/**
* @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);
}