mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 18:32:44 +00:00
152 lines
3.1 KiB
C
152 lines
3.1 KiB
C
|
#include "mylist.h"
|
||
|
#include <malloc.h>
|
||
|
#include <string.h>
|
||
|
#include "mem_util.h"
|
||
|
|
||
|
void mylist_resize(MyList *list, int newSize, bool runConstructor)
|
||
|
{
|
||
|
int newCapacity;
|
||
|
int oldSize;
|
||
|
int i;
|
||
|
void *element;
|
||
|
if (newSize < 0) newSize = 0;
|
||
|
if (list == NULL) return;
|
||
|
newCapacity = newSize;
|
||
|
oldSize = list->size;
|
||
|
if (newSize == oldSize) return;
|
||
|
if (newSize > list->capacity)
|
||
|
{
|
||
|
if (newCapacity < list->capacity * 2)
|
||
|
{
|
||
|
newCapacity = list->capacity * 2;
|
||
|
}
|
||
|
/* try to realloc */
|
||
|
list->data = (void**)realloc((void*)list->data, newCapacity * sizeof(void*));
|
||
|
for (i = list->capacity; i < newCapacity; i++)
|
||
|
{
|
||
|
list->data[i] = NULL;
|
||
|
}
|
||
|
list->capacity = newCapacity;
|
||
|
}
|
||
|
if (newSize <= list->size)
|
||
|
{
|
||
|
for (i = newSize; i < list->size; i++)
|
||
|
{
|
||
|
element = list->data[i];
|
||
|
if (element != NULL)
|
||
|
{
|
||
|
list->Destructor(element);
|
||
|
list->data[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (i = list->size; i < newSize; i++)
|
||
|
{
|
||
|
if (runConstructor)
|
||
|
{
|
||
|
list->data[i] = list->Constructor();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
list->data[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
list->size = newSize;
|
||
|
}
|
||
|
|
||
|
void *mylist_add_element(MyList *list)
|
||
|
{
|
||
|
int oldSize;
|
||
|
if (list == NULL) return NULL;
|
||
|
oldSize = list->size;
|
||
|
mylist_resize(list, oldSize + 1, true);
|
||
|
return list->data[oldSize];
|
||
|
}
|
||
|
|
||
|
void mylist_create(MyList **list_p, int initialCapacity, constructor_t constructor, destructor_t destructor)
|
||
|
{
|
||
|
MyList *list;
|
||
|
if (list_p == NULL) return;
|
||
|
if (initialCapacity < 0) initialCapacity = 0;
|
||
|
list = *list_p;
|
||
|
if (list != NULL)
|
||
|
{
|
||
|
mylist_destroy(list_p);
|
||
|
}
|
||
|
list = (MyList*)malloc(sizeof(MyList));
|
||
|
*list_p = list;
|
||
|
list->size = 0;
|
||
|
list->Constructor = constructor;
|
||
|
list->Destructor = destructor;
|
||
|
if (initialCapacity > 0)
|
||
|
{
|
||
|
list->data = (void**)malloc_zero(initialCapacity * sizeof(void*));
|
||
|
list->capacity = initialCapacity;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
list->data = NULL;
|
||
|
list->capacity = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void mylist_destroy(MyList **list_p)
|
||
|
{
|
||
|
if (list_p == NULL) return;
|
||
|
MyList *list;
|
||
|
list = *list_p;
|
||
|
if (list != NULL)
|
||
|
{
|
||
|
mylist_resize(list, 0, false);
|
||
|
free(list->data);
|
||
|
free(list);
|
||
|
*list_p = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void mylist_assign(MyList *list, int index, void *value)
|
||
|
{
|
||
|
void *oldElement;
|
||
|
if (index < 0 || index >= list->size)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
oldElement = list->data[index];
|
||
|
list->Destructor(oldElement);
|
||
|
list->data[index] = value;
|
||
|
}
|
||
|
|
||
|
void mylist_remove_at(MyList *list, int index)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if (index < 0 || index >= list->size)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
mylist_assign(list, index, NULL);
|
||
|
for (i = index + 1; i < list->size; i++)
|
||
|
{
|
||
|
list->data[i - 1] = list->data[i];
|
||
|
}
|
||
|
list->size--;
|
||
|
list->data[list->size] = NULL;
|
||
|
}
|
||
|
|
||
|
void mylist_pop_front(MyList *list)
|
||
|
{
|
||
|
mylist_remove_at(list, 0);
|
||
|
}
|
||
|
|
||
|
void mylist_push_back(MyList *list, void *value)
|
||
|
{
|
||
|
int oldSize;
|
||
|
if (list == NULL) return;
|
||
|
oldSize = list->size;
|
||
|
mylist_resize(list, oldSize + 1, false);
|
||
|
list->data[oldSize] = value;
|
||
|
}
|