9#ifndef HPP_ALIB_LANG_ALLOCATION
10#define HPP_ALIB_LANG_ALLOCATION 1
19namespace alib {
namespace lang {
34 template<
class TIntegral>
35 static constexpr size_t extSize (TIntegral size)
37 #if !ALIB_DEBUG_ALLOCATIONS
40 return size_t(size) + 4 +
sizeof(size_t);
51 static constexpr void annotate(T* mem,
size_t size,
unsigned char magic)
53 #if ALIB_DEBUG_ALLOCATIONS
55 auto* cMem=
reinterpret_cast<unsigned char*
>(mem);
57 for( ; idx< size + 4; ++idx)
59 for(
size_t i= 0; i<
sizeof(size_t); ++i)
61 cMem[idx++]=
static_cast<unsigned char>( size & 0xFF );
66 (void) mem; (void) size; (void) magic;
77 static constexpr void clearMem(T* mem,
size_t size,
unsigned char magic)
79 #if ALIB_DEBUG_ALLOCATIONS
80 memset(
reinterpret_cast<char*
>(mem), magic,
extSize(size) );
82 (void) mem; (void) size; (void) magic;
96 template<
typename TSize>
98 void checkMem(
void* mem,
const TSize size,
unsigned char magic,
const char* name )
100 #if ALIB_DEBUG_ALLOCATIONS
102 auto* cMem=
reinterpret_cast<unsigned char*
>(mem);
104 while ( idx< size + 4)
105 if( cMem[idx++] != magic )
106 ALIB_ERROR(
"MONOMEM",
"Corrupt memory with allocator ", name )
108 size_t storedSize= 0;
109 idx+=
sizeof(size_t);
113 storedSize|= cMem[--idx];
115 while( idx > size + 4);
117 if( storedSize != size )
118 ALIB_ERROR(
"MONOMEM",
"Given size does not match the allocated size "
119 "(or corrupt memory). Allocator: ", name )
122 (void) mem; (void) size; (void) magic; (void) name;
196 void*
reallocate(
void* mem,
size_t oldSize,
size_t& newSize,
size_t alignment );
202 void free(
void* mem,
size_t size);
254 template<typename TSize>
265 template<typename TSize>
321template<
typename TAllocator>
340 template<
typename TSize,
typename TAlignment>
341 void*
Alloc( TSize size, TAlignment alignment)
343 size_t s= size_t(size);
344 return allocator.allocate( s,
size_t(alignment) );
353 auto size=
sizeof(T);
354 return reinterpret_cast<T*
>( allocator.allocate(size,
alignof(T) ) );
364 template<
typename T,
typename TLength>
367 auto size=
sizeof(T[1]) *
size_t(length);
368 return reinterpret_cast<T*
>( allocator.allocate( size,
alignof(T[]) ) );
377 template<
typename T,
typename... TArgs>
379 T*
New( TArgs&& ... args )
380 {
return new (Alloc<T>()) T( std::forward<TArgs>( args )... ); }
393 template<
typename T,
typename TSize,
typename... TArgs>
397 T* mem= AllocArray<T, TSize>( length );
398 for( TSize i= 0 ; i < length ; ++i )
399 new (mem + i) T(std::forward<TArgs>( args )...);
429 allocator.free(
object,
sizeof(*
object));
437 template<
typename T,
typename TIntegral>
442 for( TIntegral i= 0 ; i < length ; ++i )
444 allocator.free(array,
sizeof(T[1]) *
size_t(length) );
459 allocator.free(
static_cast<void*
>(
const_cast<ATMP_RC(T)*
>(mem)),
sizeof(T) );
471 template<
typename T,
typename TIntegral>
473 void Free(T* mem, TIntegral size)
475 allocator.free(
static_cast<void*
>(
const_cast<ATMP_RC(T)*
>(mem)),
size_t(size) );
485 template<
typename T,
typename TIntegral>
489 allocator.free(
static_cast<void*
>(
const_cast<ATMP_RC(T)*
>(array)),
490 sizeof(T[1]) *
size_t(length) );
524 static constexpr unsigned char MAGIC= 0xA1;
528 static constexpr unsigned char CLEAR= 0xF1;
532 static constexpr size_t MIN_ALIGNMENT =
alignof(std::max_align_t);
536 static constexpr size_t MAX_ALIGNMENT =
alignof(std::max_align_t);
548 inline void*
allocate(
size_t size,
size_t alignment )
const
551 "The HeapAllocator is not designed to provide alignments greater "
552 "than alignof(std::max_align_t). ")
555 void* mem= std::malloc(lang::DbgAlloc::extSize(size));
556 DbgAlloc::annotate(mem, size, MAGIC);
569 inline void*
reallocate(
void* mem,
size_t oldSize,
size_t newSize,
size_t )
571 DbgAlloc::checkMem( mem, oldSize, MAGIC,
"HeapAllocator" );
572 void* newMem= std::realloc(mem, lang::DbgAlloc::extSize(newSize));
573 DbgAlloc::annotate(newMem, newSize, MAGIC);
580 inline void free(
void* mem,
size_t size)
const
582 DbgAlloc::checkMem( mem, size, MAGIC,
"HeapAllocator" );
583 DbgAlloc::clearMem(mem, size, CLEAR);
591 template<
typename TSize>
608 static constexpr const char* DbgName =
"HeapAllocator";
619 template<
typename TSize>
621 { DbgAlloc::checkMem( mem, size, MAGIC,
"HeapAllocator" ); }
657template<
typename TAllocator>
673 : allocator(pAllocator) {}
704 {
return const_cast<HeapAllocator&
>(HEAP_ALLOCATOR_INSTANCE); }
#define ALIB_WARNINGS_RESTORE
#define ALIB_FORCE_INLINE
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
@ Destruct
The main phase of termination that destructs everything.
TAllocator & allocator
The allocator type to use.
ALIB_FORCE_INLINE T * New(TArgs &&... args)
AllocatorInterface(TAllocator &pAllocator)
void FreeArray(T *array, TIntegral length)
void * Alloc(TSize size, TAlignment alignment)
void DeleteArray(T *array, TIntegral length)
T * AllocArray(TLength length)
T * NewArray(TSize length, TArgs &&... args)
void Free(T *mem, TIntegral size)
AllocatorMember()=default
Default Constructor.
AllocatorInterface< HeapAllocator > AI() const noexcept
HeapAllocator & GetAllocator() const noexcept
AllocatorMember(const HeapAllocator &heapAllocator) noexcept
TAllocator AllocatorType
Exposes the allocator type.
AllocatorInterface< TAllocator > AI() const noexcept
AllocatorMember()=delete
Deleted default constructor. (The allocator has to be given with construction)
AllocatorMember(TAllocator &pAllocator) noexcept
TAllocator & GetAllocator() const noexcept
TAllocator & allocator
A reference to the allocator.
void dbgCheckMemory(void *mem, TSize size) const
AllocatorInterface< Allocator > operator()()
void dbgAcknowledgeIncreasedAllocSize(void *mem, TSize allocSize) const
static constexpr size_t MIN_ALIGNMENT
TAllocator ChainedAllocator
void * reallocate(void *mem, size_t oldSize, size_t &newSize, size_t alignment)
static constexpr bool allowsMemSplit() noexcept
void free(void *mem, size_t size)
static constexpr size_t MAX_ALIGNMENT
void * allocate(size_t &size, size_t alignment)
static void checkMem(void *mem, const TSize size, unsigned char magic, const char *name)
static constexpr void clearMem(T *mem, size_t size, unsigned char magic)
static constexpr void annotate(T *mem, size_t size, unsigned char magic)
static constexpr size_t extSize(TIntegral size)
void * allocate(size_t size, size_t alignment) const
void * reallocate(void *mem, size_t oldSize, size_t newSize, size_t)
AllocatorInterface< HeapAllocator > operator()() const noexcept
static constexpr bool allowsMemSplit()
void free(void *mem, size_t size) const
void dbgAcknowledgeIncreasedAllocSize(void *, TSize) const
void dbgCheckMemory(void *mem, TSize size)