RetroArch/runahead/mylist.c

169 lines
3.2 KiB
C
Raw Normal View History

2018-03-29 15:52:49 +02:00
#include <stdlib.h>
2018-03-28 14:22:07 -05:00
#include <string.h>
2018-03-29 15:52:49 +02:00
#include "mylist.h"
2018-03-28 14:22:07 -05:00
#include "mem_util.h"
2019-07-09 17:02:10 +02:00
void mylist_resize(MyList *list, int new_size, bool run_constructor)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
int new_capacity;
int old_size;
2018-03-28 14:22:07 -05:00
int i;
void *element = NULL;
2019-07-09 17:02:10 +02:00
if (new_size < 0)
new_size = 0;
if (!list)
return;
2019-07-09 17:02:10 +02:00
new_capacity = new_size;
old_size = list->size;
2019-07-09 17:02:10 +02:00
if (new_size == old_size)
return;
2019-07-09 17:02:10 +02:00
if (new_size > list->capacity)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
if (new_capacity < list->capacity * 2)
new_capacity = list->capacity * 2;
2018-03-28 14:22:07 -05:00
/* try to realloc */
2019-07-09 17:02:10 +02:00
list->data = (void**)realloc(
(void*)list->data, new_capacity * sizeof(void*));
2019-07-09 17:02:10 +02:00
for (i = list->capacity; i < new_capacity; i++)
2018-03-28 14:22:07 -05:00
list->data[i] = NULL;
2019-07-09 17:02:10 +02:00
list->capacity = new_capacity;
2018-03-28 14:22:07 -05:00
}
2019-07-09 17:02:10 +02:00
if (new_size <= list->size)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
for (i = new_size; i < list->size; i++)
2018-03-28 14:22:07 -05:00
{
element = list->data[i];
if (element)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
list->destructor(element);
2018-03-28 14:22:07 -05:00
list->data[i] = NULL;
}
}
}
else
{
2019-07-09 17:02:10 +02:00
for (i = list->size; i < new_size; i++)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
if (run_constructor)
list->data[i] = list->constructor();
2018-03-28 14:22:07 -05:00
else
list->data[i] = NULL;
}
}
2019-07-09 17:02:10 +02:00
list->size = new_size;
2018-03-28 14:22:07 -05:00
}
void *mylist_add_element(MyList *list)
{
2019-07-09 17:02:10 +02:00
int old_size;
if (!list)
return NULL;
2019-07-09 17:02:10 +02:00
old_size = list->size;
mylist_resize(list, old_size + 1, true);
return list->data[old_size];
2018-03-28 14:22:07 -05:00
}
2019-07-09 17:02:10 +02:00
void mylist_create(MyList **list_p, int initial_capacity,
constructor_t constructor, destructor_t destructor)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
MyList *list = NULL;
if (!list_p)
return;
2019-07-09 17:02:10 +02:00
if (initial_capacity < 0)
initial_capacity = 0;
list = *list_p;
if (list)
2018-03-28 14:22:07 -05:00
mylist_destroy(list_p);
list = (MyList*)malloc(sizeof(MyList));
*list_p = list;
list->size = 0;
2019-07-09 17:02:10 +02:00
list->constructor = constructor;
list->destructor = destructor;
2019-07-09 17:02:10 +02:00
if (initial_capacity > 0)
2018-03-28 14:22:07 -05:00
{
2019-07-09 17:02:10 +02:00
list->data = (void**)calloc(initial_capacity, sizeof(void*));
list->capacity = initial_capacity;
2018-03-28 14:22:07 -05:00
}
else
{
list->data = NULL;
list->capacity = 0;
2018-03-28 14:22:07 -05:00
}
}
void mylist_destroy(MyList **list_p)
{
MyList *list = NULL;
if (!list_p)
return;
2018-03-28 14:22:07 -05:00
list = *list_p;
if (list)
2018-03-28 14:22:07 -05:00
{
mylist_resize(list, 0, false);
free(list->data);
free(list);
*list_p = NULL;
}
}
void mylist_assign(MyList *list, int index, void *value)
{
2019-07-09 17:02:10 +02:00
void *old_element = NULL;
2018-03-28 14:22:07 -05:00
if (index < 0 || index >= list->size)
return;
2019-07-09 17:02:10 +02:00
old_element = list->data[index];
list->destructor(old_element);
2018-03-28 14:22:07 -05:00
list->data[index] = value;
}
void mylist_remove_at(MyList *list, int index)
{
int i;
if (index < 0 || index >= list->size)
return;
2018-03-28 14:22:07 -05:00
mylist_assign(list, index, NULL);
2018-03-28 14:22:07 -05:00
for (i = index + 1; i < list->size; i++)
list->data[i - 1] = list->data[i];
2018-03-28 14:22:07 -05:00
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)
{
2019-07-09 17:02:10 +02:00
int old_size;
if (!list)
return;
2019-07-09 17:02:10 +02:00
old_size = list->size;
mylist_resize(list, old_size + 1, false);
list->data[old_size] = value;
2018-03-28 14:22:07 -05:00
}