34#ifndef __MEM_GUARDEDALLOC_H__
35#define __MEM_GUARDEDALLOC_H__
65extern short (*MEM_testN)(
void *vmemh);
79extern void *(*MEM_reallocN_id)(
void *vmemh,
87extern void *(*MEM_recallocN_id)(
void *vmemh,
92#define MEM_reallocN(vmemh, len) MEM_reallocN_id(vmemh, len, __func__)
93#define MEM_recallocN(vmemh, len) MEM_recallocN_id(vmemh, len, __func__)
191# define MEM_SAFE_FREE(v) \
193 static_assert(std::is_pointer_v<std::decay_t<decltype(v)>>); \
194 void **_v = (void **)&(v); \
201# define MEM_SAFE_FREE(v) \
203 void **_v = (void **)&(v); \
212#define MEM_SIZE_OVERHEAD sizeof(size_t)
213#define MEM_SIZE_OPTIMAL(size) ((size)-MEM_SIZE_OVERHEAD)
216extern const char *(*MEM_name_ptr)(
void *vmemh);
278# include <type_traits>
288# define MEM_MIN_CPP_ALIGNMENT \
289 (__STDCPP_DEFAULT_NEW_ALIGNMENT__ < alignof(void *) ? __STDCPP_DEFAULT_NEW_ALIGNMENT__ : \
302template<
typename T,
typename... Args>
303inline T *MEM_new(
const char *allocation_name, Args &&...args)
307 return new (buffer)
T(std::forward<Args>(args)...);
319template<
typename T>
inline void MEM_delete(
const T *
ptr)
323 "MEM_delete on a void pointer is not possible, `static_cast` it to the correct type");
324 if (
ptr ==
nullptr) {
340template<
typename T>
inline T *MEM_cnew(
const char *allocation_name)
342 static_assert(std::is_trivial_v<T>,
"For non-trivial types, MEM_new must be used.");
349template<
typename T>
inline T *MEM_cnew_array(
const size_t length,
const char *allocation_name)
351 static_assert(std::is_trivial_v<T>,
"For non-trivial types, MEM_new must be used.");
352 return static_cast<T *
>(
366template<
typename T>
inline T *MEM_cnew(
const char *allocation_name,
const T &other)
368 static_assert(std::is_trivial_v<T>,
"For non-trivial types, MEM_new must be used.");
369 T *new_object =
static_cast<T *
>(
MEM_mallocN_aligned(
sizeof(T),
alignof(T), allocation_name));
371 memcpy(new_object, &other,
sizeof(T));
377# define MEM_CXX_CLASS_ALLOC_FUNCS(_id) \
379 void *operator new(size_t num_bytes) \
381 return mem_guarded::internal::mem_mallocN_aligned_ex( \
383 __STDCPP_DEFAULT_NEW_ALIGNMENT__, \
385 mem_guarded::internal::AllocationType::NEW_DELETE); \
387 void *operator new(size_t num_bytes, std::align_val_t alignment) \
389 return mem_guarded::internal::mem_mallocN_aligned_ex( \
390 num_bytes, size_t(alignment), _id, mem_guarded::internal::AllocationType::NEW_DELETE); \
392 void operator delete(void *mem) \
395 mem_guarded::internal::mem_freeN_ex(mem, \
396 mem_guarded::internal::AllocationType::NEW_DELETE); \
399 void *operator new[](size_t num_bytes) \
401 return mem_guarded::internal::mem_mallocN_aligned_ex( \
403 __STDCPP_DEFAULT_NEW_ALIGNMENT__, \
405 mem_guarded::internal::AllocationType::NEW_DELETE); \
407 void *operator new[](size_t num_bytes, std::align_val_t alignment) \
409 return mem_guarded::internal::mem_mallocN_aligned_ex( \
413 mem_guarded::internal::AllocationType::NEW_DELETE); \
415 void operator delete[](void *mem) \
418 mem_guarded::internal::mem_freeN_ex(mem, \
419 mem_guarded::internal::AllocationType::NEW_DELETE); \
422 void *operator new(size_t , void *ptr) \
431 void operator delete(void *
, void * ) {}
442template<
typename T,
typename... Args> T &MEM_construct_leak_detection_data(Args &&...args)
444 std::shared_ptr<T> data = std::make_shared<T>(std::forward<Args>(args)...);
445 std::any any_data = std::make_any<std::shared_ptr<T>>(
data);
#define ATTR_WARN_UNUSED_RESULT
#define ATTR_ALLOC_SIZE(...)
#define ATTR_NONNULL(...)
void *(* MEM_mallocN)(size_t len, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2)
void MEM_use_guarded_allocator(void)
void MEM_use_memleak_detection(bool enabled)
void(* MEM_reset_peak_memory)(void)
void MEM_enable_fail_on_memleak(void)
size_t(* MEM_get_memory_in_use)(void)
void(* MEM_printmemlist_stats)(void)
void(* MEM_set_memory_debug)(void)
size_t(* MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT
void *(* MEM_calloc_arrayN_aligned)(size_t len, size_t size, size_t alignment, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
void MEM_init_memleak_detection(void)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3)
void(* MEM_set_error_callback)(void(*func)(const char *))
size_t(* MEM_allocN_len)(const void *vmemh) ATTR_WARN_UNUSED_RESULT
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_ALLOC_SIZE(1
void MEM_use_lockfree_allocator(void)
void MEM_freeN(void *vmemh)
bool(* MEM_consistency_check)(void)
unsigned int(* MEM_get_memory_blocks_in_use)(void)
void(* MEM_name_ptr_set)(void *vmemh, const char *str) ATTR_NONNULL()
void(* MEM_printmemlist_pydict)(void)
void(* MEM_callbackmemlist)(void(*func)(void *))
void(* MEM_printmemlist)(void)
void add_memleak_data(std::any data)
void(* mem_freeN_ex)(void *vmemh, AllocationType allocation_type)
void *(* mem_mallocN_aligned_ex)(size_t len, size_t alignment, const char *str, AllocationType allocation_type)