memory.allocator

Memory allocators used in containers (but also usable directly).

struct AllocatorAPI;

This is a dummy struct documenting allocator API, which is identical for every Allocator struct.

Note:
Any memory allocated by one of the allocators must NOT be used after main() (in static destructors).

T[] allocArray(T, string file = __FILE__, uint line = __LINE__)(const size_t elems);

Allocate an array of specified type. Arrays allocated with alloc must NOT be resized.

Parameters:
elems Number of objects to allocate space for.
Returns:
Allocated array. Values in the array are default-initialized.
T[] realloc(T, string file = __FILE__, uint line = __LINE__)(T[] array, const size_t elems);

Reallocate an array allocated by alloc() . Contents of the array are preserved but array itself might be moved in memory, invalidating any pointers pointing to it. If the array is shrunk and of non-reference type (e.g. not a class), any extra elements are cleared (if they have destructors, they're called).

Parameters:
array Array to reallocate.
elems Number of objects for the reallocated array to hold.
Returns:
Reallocated array.
void free(T)(T[] array);

Free an array of objects allocated by allocArray(). If the array is of non-reference type (e.g. not a class), array elements are cleared (if they have destructors, they're called).

Parameters:
array Array to free.
template canAllocate(U)

Can the allocator allocate values of specified type?

struct DirectAllocator;

Allocates memory directly through memory.memory.

struct BufferSwappingAllocator(T,uint BufferCount) if (!is(T == class));

An allocator that preserves previously allocated buffers, reusing them later.

We have a fixed number of buffers. When allocating, we look for a free buffer large enough for our allocation. If found, we use it, otherwise we allocate a new buffer and either replace a smaller unused buffer, or, if out of buffers, we just return the new buffer without keeping track of it.
When freeing, if the buffer freed matches one of buffers in the allocator, we mark that buffer as free. Otherwise we just delete it.
When reallocating a buffer matching a buffer in the allocator, we look if we have extra space in the buffer, and try to reuse it. Only if we can't we reallocate the buffer in the allocator and return it. (If not in the allocator, we simply reallocate the buffer).