2018-06-04 22:26:48 +00:00
|
|
|
//
|
|
|
|
// Created by Antoine Bartuccio on 22/05/2018.
|
|
|
|
//
|
|
|
|
#include "List.h"
|
|
|
|
|
|
|
|
GETTER(List, Element*, head)
|
|
|
|
GETTER(List, Element*, tail)
|
|
|
|
GETTER(List, int, size)
|
|
|
|
|
2018-06-15 09:50:38 +00:00
|
|
|
void set_custom_free_List(THIS(List), void (*custom_free)(void *)){
|
|
|
|
this->custom_free = custom_free;
|
|
|
|
}
|
|
|
|
|
2018-06-05 13:52:48 +00:00
|
|
|
Element * get_element_List(THIS(List), int index){
|
|
|
|
Element * current = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (index < this->size){
|
|
|
|
if (index == this->size - 1)
|
|
|
|
current = this->tail;
|
|
|
|
else if (index == 0)
|
|
|
|
current = this->head;
|
|
|
|
else if (index <= (this->size - 1) / 2){
|
|
|
|
i = 0;
|
|
|
|
current = this->head;
|
|
|
|
while (i < index){
|
|
|
|
current = current->next;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
i = this->size - 1;
|
|
|
|
current = this->tail;
|
|
|
|
while (i > index){
|
|
|
|
current = current->previous;
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
2018-06-15 09:50:38 +00:00
|
|
|
} else {
|
|
|
|
OUTSIDE_BOUNDS;
|
|
|
|
}
|
2018-06-05 13:52:48 +00:00
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
void * get_element_data_List(THIS(List), int index){
|
|
|
|
Element * el = this->get_element(this, index);
|
|
|
|
if (el != NULL)
|
|
|
|
return el->data;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void * get_head_data_List(THIS(List)){
|
|
|
|
if (this->head != NULL)
|
|
|
|
return this->head->data;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void * get_tail_data_List(THIS(List)){
|
|
|
|
if (this->tail != NULL)
|
|
|
|
return this->tail->data;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-06-05 23:15:23 +00:00
|
|
|
void _free__List(THIS(List)){
|
2018-06-05 11:43:45 +00:00
|
|
|
this->clear(this);
|
2018-06-04 22:26:48 +00:00
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
2018-06-06 18:29:02 +00:00
|
|
|
void clear_custom_List(THIS(List), void (*custom_free)(void *)){
|
2018-06-05 13:52:48 +00:00
|
|
|
Element *current = this->head;
|
|
|
|
Element *to_delete = NULL;
|
|
|
|
while (current != NULL){
|
|
|
|
to_delete = current;
|
|
|
|
current = current->next;
|
|
|
|
to_delete->list = NULL;
|
2018-06-06 18:29:02 +00:00
|
|
|
to_delete->data_free = custom_free;
|
2018-06-05 13:52:48 +00:00
|
|
|
DELETE(to_delete);
|
2018-06-05 11:43:45 +00:00
|
|
|
}
|
2018-06-05 13:52:48 +00:00
|
|
|
this->head = NULL;
|
|
|
|
this->tail = NULL;
|
2018-06-05 11:43:45 +00:00
|
|
|
this->size = 0;
|
|
|
|
}
|
|
|
|
|
2018-06-06 18:29:02 +00:00
|
|
|
void clear_List(THIS(List)){
|
|
|
|
this->clear_custom(this, free);
|
|
|
|
}
|
|
|
|
|
2018-06-05 13:52:48 +00:00
|
|
|
void insert_tail_List(THIS(List), void * data, size_t data_size){
|
|
|
|
/* Create a new element */
|
|
|
|
Element *new_element = NEW(Element, data, data_size, this);
|
2018-06-15 09:50:38 +00:00
|
|
|
new_element->data_free = this->custom_free;
|
|
|
|
|
2018-06-05 13:52:48 +00:00
|
|
|
if (this->tail == NULL){
|
|
|
|
this->head = new_element;
|
|
|
|
this->tail = new_element;
|
|
|
|
} else {
|
|
|
|
new_element->previous = this->tail;
|
|
|
|
this->tail->next = new_element;
|
|
|
|
this->tail = new_element;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insert_head_List(THIS(List), void * data, size_t data_size){
|
|
|
|
/* Create a new element */
|
|
|
|
Element *new_element = NEW(Element, data, data_size, this);
|
2018-06-15 09:50:38 +00:00
|
|
|
new_element->data_free = this->custom_free;
|
|
|
|
|
2018-06-05 13:52:48 +00:00
|
|
|
if (this->head != NULL)
|
|
|
|
this->head->previous = new_element;
|
|
|
|
else
|
|
|
|
this->tail = new_element;
|
|
|
|
new_element->next = this->head;
|
|
|
|
|
|
|
|
this->head = new_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
void insert_inside_List(THIS(List), void * data, size_t data_size, int index){
|
|
|
|
Element *new_element = NULL;
|
|
|
|
Element *old_element = NULL;
|
|
|
|
|
|
|
|
if (index == 0)
|
|
|
|
this->insert_head(this, data, data_size);
|
|
|
|
else if (index == this->size)
|
|
|
|
this->insert_tail(this, data, data_size);
|
|
|
|
else if (index < this->size){
|
|
|
|
new_element = NEW(Element, data, data_size, this);
|
2018-06-15 09:50:38 +00:00
|
|
|
new_element->data_free = this->custom_free;
|
|
|
|
|
2018-06-05 13:52:48 +00:00
|
|
|
old_element = this->get_element(this, index);
|
|
|
|
|
|
|
|
new_element->previous = old_element->previous;
|
|
|
|
new_element->next = old_element;
|
|
|
|
|
|
|
|
old_element->previous->next = new_element;
|
|
|
|
old_element->previous = new_element;
|
|
|
|
|
2018-06-18 13:20:19 +00:00
|
|
|
} else {
|
|
|
|
OUTSIDE_BOUNDS;
|
|
|
|
}
|
2018-06-05 13:52:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-06-05 11:43:45 +00:00
|
|
|
void remove_head_List(THIS(List)){
|
|
|
|
DELETE(this->head);
|
|
|
|
}
|
|
|
|
|
|
|
|
void remove_tail_List(THIS(List)){
|
|
|
|
DELETE(this->tail);
|
|
|
|
}
|
|
|
|
|
2018-06-05 23:15:23 +00:00
|
|
|
List *_init_List(){
|
2018-06-04 22:26:48 +00:00
|
|
|
List *l = (List*) malloc_or_die(sizeof(List));
|
|
|
|
l->size = 0;
|
|
|
|
l->head = NULL;
|
|
|
|
l->tail = NULL;
|
2018-06-15 09:50:38 +00:00
|
|
|
l->custom_free = free;
|
2018-06-04 22:26:48 +00:00
|
|
|
|
2018-06-05 11:43:45 +00:00
|
|
|
LINK_ALL(List, l,
|
|
|
|
get_head,
|
|
|
|
get_tail,
|
|
|
|
get_size,
|
2018-06-05 13:52:48 +00:00
|
|
|
get_head_data,
|
|
|
|
get_tail_data,
|
|
|
|
get_element,
|
|
|
|
get_element_data,
|
2018-06-15 09:50:38 +00:00
|
|
|
set_custom_free,
|
2018-06-05 13:52:48 +00:00
|
|
|
insert_inside,
|
|
|
|
insert_tail,
|
|
|
|
insert_head,
|
2018-06-06 18:29:02 +00:00
|
|
|
clear_custom,
|
2018-06-05 11:43:45 +00:00
|
|
|
clear,
|
|
|
|
remove_head,
|
|
|
|
remove_tail
|
|
|
|
)
|
2018-06-04 22:26:48 +00:00
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|