p2p/stingray_sdk/plugin_foundation/memory_utilities.h
Lucas Schwiderski 2c9ce46dd2
chore: Rework project structure
There likely won't be much need for multiple separate crates.
2023-05-26 23:42:01 +02:00

94 lines
2.3 KiB
C++

#pragma once
namespace stingray_plugin_foundation {
namespace memory_utilities {
// Rounds size up to the specified alignment
template <class T>
inline T round_up_to(T size, unsigned align)
{
return ((size + align - 1) / align) * align;
}
// Returns true if p is aligned to the specified alignment
inline bool is_aligned(const void *p, unsigned align)
{
uintptr_t pi = (uintptr_t)p;
return pi % align == 0;
}
// Returns the result of advancing p by the specified number of bytes
inline void *pointer_add(void *p, size_t bytes)
{
return (void*)((char *)p + bytes);
}
inline const void *pointer_add(const void *p, size_t bytes)
{
return (const void*)((const char *)p + bytes);
}
// Returns the result of moving p back by the specified number of bytes
inline void *pointer_sub(void *p, size_t bytes)
{
return (void*)((char *)p - bytes);
}
inline const void *pointer_sub(const void *p, size_t bytes)
{
return (const void*)((const char *)p - bytes);
}
inline size_t pointer_sub(const void *p1, const void *p2)
{
return (const char *)p1 - (const char *)p2;
}
// The number of bytes p must be moved forward to align
inline unsigned bytes_to_aligned_address(const void *p, unsigned align)
{
uintptr_t pi = (uintptr_t)p;
return (unsigned)(((pi + align - 1)/align)*align - pi);
}
// The number of bytes p must be moved backward to align
inline unsigned bytes_from_aligned_address(const void *p, unsigned align)
{
uintptr_t pi = (uintptr_t)p;
return pi % align;
}
// Moves p forward to align
inline void *round_up_to_aligned_address(void *p, unsigned align)
{
return pointer_add(p, bytes_to_aligned_address(p, align));
}
inline const void *round_up_to_aligned_address(const void *p, unsigned align)
{
return pointer_add(p, bytes_to_aligned_address(p, align));
}
// Moves p backward to align
inline void *round_down_to_aligned_address(void *p, unsigned align)
{
return pointer_sub(p, bytes_from_aligned_address(p, align));
}
inline const void *round_down_to_aligned_address(const void *p, unsigned align)
{
return pointer_sub(p, bytes_from_aligned_address(p, align));
}
// Interprets data at address p as an object of type T.
template<class T>
inline T& object_at_address(void *p)
{
return *(T *)p;
}
template<class T>
inline const T& object_at_address(const void *p)
{
return *(T *)p;
}
}
}