// // Created by Antoine Bartuccio on 22/05/2018. // #include "List.h" GETTER(List, Element*, head) GETTER(List, Element*, tail) GETTER(List, int, size) void set_custom_free_List(THIS(List), void (*custom_free)(void *)){ this->custom_free = custom_free; } 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--; } } } else { OUTSIDE_BOUNDS; } 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; } void _free__List(THIS(List)){ this->clear(this); free(this); } void clear_custom_List(THIS(List), void (*custom_free)(void *)){ Element *current = this->head; Element *to_delete = NULL; while (current != NULL){ to_delete = current; current = current->next; to_delete->list = NULL; to_delete->data_free = custom_free; DELETE(to_delete); } this->head = NULL; this->tail = NULL; this->size = 0; } void clear_List(THIS(List)){ this->clear_custom(this, free); } 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); new_element->data_free = this->custom_free; 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); new_element->data_free = this->custom_free; 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); new_element->data_free = this->custom_free; 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; } else { OUTSIDE_BOUNDS; } } /** * Remove element with specified data in the list * @param this THIS(List) * @param data_to_remove pointer to data you want to remove * @param compare a compare function, return true or false and takes two void * pointers * @return true or false, depending on if the element was found in the list */ int remove_inside_List(THIS(List), void * data_to_remove, int (*compare)(void*, void*)){ Element* temp_element = this->head; while(temp_element != NULL){ if(compare(data_to_remove, temp_element->data)){ if(temp_element == this->head){ this->remove_head(this); }else if (temp_element == this->tail){ this->remove_tail(this); }else{ if(temp_element->previous != NULL) temp_element->previous->next = temp_element->next; if(temp_element->next != NULL) temp_element->next->previous = temp_element->previous; DELETE(temp_element); } return 1; } temp_element = temp_element->next; } return 0; } /** * Check if data_to_find exist in list * @param this THIS(List) * @param data_to_find pointer to data you want to find inside * @param compare a compare function, return true or false and takes two void * pointers * @return true or false if the element is within the list or not */ int contains_List(THIS(List), void * data_to_find, int (*compare)(void *, void *)){ Element * current = this->head; while (current != NULL){ if (compare(data_to_find, current->data)){ return 1; } current = current->next; } return 0; } void remove_head_List(THIS(List)){ DELETE(this->head); } void remove_tail_List(THIS(List)){ DELETE(this->tail); } List *_init_List(){ List *l = (List*) malloc_or_die(sizeof(List)); l->size = 0; l->head = NULL; l->tail = NULL; l->custom_free = free; LINK_ALL(List, l, get_head, get_tail, get_size, get_head_data, get_tail_data, get_element, get_element_data, set_custom_free, remove_inside, insert_inside, insert_tail, insert_head, clear_custom, clear, remove_head, remove_tail, contains ) return l; }