// vim: set ts=4 sw=4 tw=80 et: #include "./collections.h" size_t dl_list_length(const dl_list_t* self) { size_t length = 0; dl_node_t* i = self->first; while (i != NULL) { length++; i = i->next; } return length; } dl_node_t* dl_list_ith(const dl_list_t* self, const size_t position) { size_t found; dl_node_t* elem = dl_list_ith_or_last(self, position, &found); return found != position ? NULL : elem; } dl_node_t* dl_list_ith_or_last(const dl_list_t* self, const size_t position, size_t* returned) { dl_node_t* to_reach = self->first; size_t i; for (i = 0; i < position && to_reach->next != NULL; i++) { to_reach = to_reach->next; } *returned = i; return to_reach; } inline dl_node_t* dl_list_alloc_node(void* element) { dl_node_t* node = malloc(sizeof(node)); node->element = element; node->next = NULL; node->prev = NULL; } inline void dl_list_free_node(dl_node_t* node) { if (node->element != NULL) { free(node->element); } free(node); } inline void dl_list_init(dl_list_t* self) { self->first = NULL; } inline void dl_list_destroy(dl_list_t* self) { while(self->first != NULL) { free(dl_list_remove(self, 0)); } } size_t dl_list_copy_slice(const dl_list_t* self, dl_list_t* destination, const size_t from, const size_t to) { if (from >= to) { return 0; } dl_list_destroy(destination); size_t start, i; dl_node_t* to_copy = dl_list_ith_or_last(self, to, &start); if (to_copy == NULL) { return 0; } for(i = start; i > from; i--) { dl_node_t* copied = malloc(sizeof(dl_node_t)); memcpy(copied, self, sizeof(dl_node_t)); dl_list_insert(destination, 0, copied); } return start - from; } int dl_list_insert(dl_list_t* self, const size_t position, dl_node_t* node) { if (position == 0) { node->next = self->first; node->prev = NULL; self->first = node; return 0; } dl_node_t* to_reach = dl_list_ith(self, position - 1); if (to_reach == NULL) { return 2; } to_reach->next->prev = node; node->next = to_reach->next; node->prev = to_reach; to_reach->next = node; return 0; } dl_node_t* dl_list_remove(dl_list_t* self, const size_t position) { if(position == 0) { dl_node_t* to_remove = self->first; self->first = to_remove->next; return to_remove; } dl_node_t* to_reach = dl_list_ith(self, position - 1); if (to_reach == NULL || to_reach->next == NULL) { return NULL; } dl_node_t* to_remove = to_reach->next; to_reach->next = to_reach->next->next; to_reach->next->prev = to_reach; return to_remove; }