1 #ifndef SIPLASPLAS_UTILITY_MEMORY_MANIP_HPP 2 #define SIPLASPLAS_UTILITY_MEMORY_MANIP_HPP 7 #include <siplasplas/utility/export.hpp> 29 SIPLASPLAS_UTILITY_EXPORT
char*
aligned_ptr(
char* pointer, std::size_t alignment);
41 SIPLASPLAS_UTILITY_EXPORT
void*
aligned_ptr(
void* pointer, std::size_t alignment);
53 SIPLASPLAS_UTILITY_EXPORT
const char*
aligned_ptr(
const char* pointer, std::size_t alignment);
65 SIPLASPLAS_UTILITY_EXPORT
const void*
aligned_ptr(
const void* pointer, std::size_t alignment);
77 SIPLASPLAS_UTILITY_EXPORT
bool is_aligned(
char* pointer, std::size_t alignment);
88 SIPLASPLAS_UTILITY_EXPORT
bool is_aligned(
void* pointer, std::size_t alignment);
99 SIPLASPLAS_UTILITY_EXPORT
bool is_aligned(
const char* pointer, std::size_t alignment);
110 SIPLASPLAS_UTILITY_EXPORT
bool is_aligned(
const void* pointer, std::size_t alignment);
122 SIPLASPLAS_UTILITY_EXPORT std::uintptr_t
missalignment(
const char* address, std::size_t alignment);
134 SIPLASPLAS_UTILITY_EXPORT std::uintptr_t
missalignment(
const void* address, std::size_t alignment);
146 SIPLASPLAS_UTILITY_EXPORT std::uintptr_t
missalignment(
char* address, std::size_t alignment);
158 SIPLASPLAS_UTILITY_EXPORT std::uintptr_t
missalignment(
void* address, std::size_t alignment);
176 template<
typename T,
typename U>
179 static_assert(
sizeof(
nullptr) * CHAR_BIT == 64,
"Tagging pointers is only supported in architectures with 64 bit virtual addresses");
181 return reinterpret_cast<T*
>(
static_cast<std::uintptr_t
>(data) << 48 | (reinterpret_cast<std::uintptr_t>(pointer) & 0x0000FFFFFFFFFFFF));
199 template<
typename R,
typename U,
typename... Args>
200 auto tagPointer(R(*pointer)(Args...), U data) -> decltype(pointer)
202 static_assert(
sizeof(
nullptr) * CHAR_BIT == 64,
"Tagging pointers is only supported in architectures with 64 bit virtual addresses");
204 return reinterpret_cast<R(*)(Args...)
>(data << 48 | (reinterpret_cast<std::uintptr_t>(pointer) & 0x0000FFFFFFFFFFFF));
222 static_assert(
sizeof(
nullptr) * CHAR_BIT == 64,
"Tagging pointers is only supported in architectures with 64 bit virtual addresses");
224 return reinterpret_cast<T*
>(
reinterpret_cast<std::uintptr_t
>(pointer) & 0x0000FFFFFFFFFFFF);
239 template<
typename R,
typename... Args>
242 static_assert(
sizeof(
nullptr) * CHAR_BIT == 64,
"Tagging pointers is only supported in architectures with 64 bit virtual addresses");
244 return reinterpret_cast<R(*)(Args...)
>(
reinterpret_cast<std::uintptr_t
>(pointer) & 0x0000FFFFFFFFFFFF);
262 static_assert(
sizeof(
nullptr) * CHAR_BIT == 64,
"Tagging pointers is only supported in architectures with 64 bit virtual addresses");
264 return reinterpret_cast<std::uintptr_t
>(pointer) >> 48;
279 template<
typename R,
typename... Args>
282 static_assert(
sizeof(
nullptr) * CHAR_BIT == 64,
"Tagging pointers is only supported in architectures with 64 bit virtual addresses");
284 return reinterpret_cast<std::uintptr_t
>(pointer) >> 48;
287 #ifndef SIPLASPLAS_UTILITY_ALIGNEDMALLOC_ALIGNOFFSET_BITS 311 SIPLASPLAS_PP_CAT(std::uint,SIPLASPLAS_UTILITY_ALIGNEDMALLOC_ALIGNOFFSET_BITS),
332 SIPLASPLAS_UTILITY_EXPORT
void*
aligned_malloc(std::size_t size, std::size_t alignment, std::size_t offset = 0);
359 SIPLASPLAS_UTILITY_EXPORT
void aligned_free(
void* pointer, std::size_t offset = 0);
362 void write_at(
char* pointer,
const T& value, std::intptr_t offset = 0)
364 *(
reinterpret_cast<T*
>(pointer) + offset) = value;
368 void write_at(
void* pointer,
const T& value, std::intptr_t offset = 0)
370 write_at(reinterpret_cast<char*>(pointer), value, offset);
374 T read_at(
const char* pointer, std::intptr_t offset = 0)
376 return *(
reinterpret_cast<const T*
>(pointer + offset));
380 T read_at(
const void* pointer, std::intptr_t offset = 0)
382 return read_at<T>(
reinterpret_cast<const char*
>(pointer), offset);
386 void write_before(
char* pointer,
const T& value)
388 write_at(pointer, value, -
sizeof(T));
392 void write_before(
void* pointer,
const T& value)
394 write_before(reinterpret_cast<char*>(pointer), value);
398 T read_before(
const char* pointer)
400 return read_at<T>(pointer, -
sizeof(T));
404 T read_before(
const void* pointer)
406 return read_before<T>(
reinterpret_cast<const char*
>(pointer));
410 class RawReaderWriter
413 RawReaderWriter(
void* at) :
414 _at{
reinterpret_cast<char*
>(at)}
419 return detail::read_at<T>(_at);
429 detail::write_at(_at, value);
438 #endif // SIPLASPLAS_UTILITY_MEMORY_MANIP_HPP SIPLASPLAS_UTILITY_EXPORT const void * aligned_ptr(const void *pointer, std::size_t alignment)
Returns an address aligned to an specific boundary.
SIPLASPLAS_UTILITY_EXPORT void * aligned_malloc(std::size_t size, std::size_t alignment, std::size_t offset=0)
Allocates a block of memory of memory aligned to an specific boundary.
auto untagPointer(R(*pointer)(Args...)) -> decltype(pointer)
Untags a pointer.
Definition: memory_manip.hpp:240
Definition: canary_allocator.hpp:7
std::uint8_t AlignedMallocAlingOffset
Type used to store the offset between the aligned pointer returned by aligned_malloc() and the beginn...
Definition: memory_manip.hpp:308
std::uint16_t readTaggedPointer(R(*pointer)(Args...))
Reads the data stored in a tagged pointer.
Definition: memory_manip.hpp:280
SIPLASPLAS_UTILITY_EXPORT std::uintptr_t missalignment(void *address, std::size_t alignment)
Returns the distance between a memory address and the next address aligned to the given boundary...
SIPLASPLAS_UTILITY_EXPORT bool is_aligned(const void *pointer, std::size_t alignment)
Checks if an address is aligned to a given boundary.
SIPLASPLAS_UTILITY_EXPORT void * aligned_malloc_block(void *pointer, std::size_t offset=0)
Returns a pointer to the full block allocated by cpp::aligned_malloc()
auto tagPointer(R(*pointer)(Args...), U data) -> decltype(pointer)
Tags a pointer with the specified data.
Definition: memory_manip.hpp:200
SIPLASPLAS_UTILITY_EXPORT void aligned_free(void *pointer, std::size_t offset=0)
Deallocates a block allocated by cpp::aligned_malloc()