Mirai's Miscellaneous Misadventures
M35 / core / allocators.c
#include <mimimi/allocators.h>
#include <mimimi/compound-behaviors.h>
struct mimimi_temporary_allocator
{
struct mimimi_allocator *allocator;
int count;
void **allocated;
};
static void *mimimi_temporary_allocate(void *data, unsigned int size)
{
struct mimimi_temporary_allocator *temporary_allocator = data;
struct mimimi_allocator *allocator = temporary_allocator->allocator;
void *value = mimimi_allocate(allocator, size);
temporary_allocator->allocated = mimimi_reallocate(allocator, temporary_allocator->allocated, (temporary_allocator->count + 1) * sizeof *temporary_allocator->allocated);
temporary_allocator->allocated[temporary_allocator->count] = value;
temporary_allocator->count++;
return value;
}
static void *mimimi_temporary_reallocate(void *data, void *value, unsigned int size)
{
struct mimimi_temporary_allocator *temporary_allocator = data;
struct mimimi_allocator *allocator = temporary_allocator->allocator;
if (value == allocator->null)
return mimimi_temporary_allocate(data, size);
int i = 0;
while (temporary_allocator->allocated[i] != value) i++;
value = mimimi_reallocate(allocator, value, size);
temporary_allocator->allocated[i] = value;
return value;
}
static void mimimi_temporary_deallocate(void *data, void *value)
{
struct mimimi_temporary_allocator *temporary_allocator = data;
struct mimimi_allocator *allocator = temporary_allocator->allocator;
int i = 0;
while (temporary_allocator->allocated[i] != value) i++;
for (int j = i + 1 ; j < temporary_allocator->count ; j++)
temporary_allocator->allocated[j - 1] = temporary_allocator->allocated[j];
temporary_allocator->count--;
if (temporary_allocator->count == 0)
mimimi_deallocate(allocator, temporary_allocator->allocated),
temporary_allocator->allocated = allocator->null;
else
temporary_allocator->allocated = mimimi_reallocate(allocator, temporary_allocator->allocated, temporary_allocator->count * sizeof *temporary_allocator->allocated);
mimimi_deallocate(temporary_allocator->allocator, value);
}
struct mimimi_allocator *mimimi_temporary_allocator(struct mimimi_allocator *allocator)
{
struct mimimi_temporary_allocator *temporary_allocator = mimimi_allocate(allocator, sizeof *temporary_allocator);
temporary_allocator->allocator = allocator;
temporary_allocator->count = 0;
temporary_allocator->allocated = allocator->null;
struct mimimi_allocator *result = mimimi_allocate(allocator, sizeof *result);
result->allocate = &mimimi_temporary_allocate;
result->deallocate = &mimimi_temporary_deallocate;
result->reallocate = &mimimi_temporary_reallocate;
result->null = allocator->null;
result->data = temporary_allocator;
return result;
}
void mimimi_finish_temporary_allocator(struct mimimi_allocator *result)
{
struct mimimi_temporary_allocator *temporary_allocator = result->data;
struct mimimi_allocator *allocator = temporary_allocator->allocator;
for (int i = 0 ; i < temporary_allocator->count ; i++)
mimimi_deallocate(allocator, temporary_allocator->allocated[i]);
if (temporary_allocator->count != 0)
mimimi_deallocate(allocator, temporary_allocator->allocated);
mimimi_deallocate(allocator, temporary_allocator);
mimimi_deallocate(allocator, result);
}
static void mimimi_compound_allocator_finish(void *data)
{
mimimi_finish_temporary_allocator(data);
}
struct mimimi_allocator *mimimi_compound_allocator(struct mimimi_behavior *compound, struct mimimi_allocator *allocator)
{
struct mimimi_allocator *temporary_allocator = mimimi_temporary_allocator(allocator);
mimimi_compound(compound, mimimi_finalizer(temporary_allocator, &mimimi_compound_allocator_finish, allocator));
return temporary_allocator;
}