Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #define list_empty(plist) ((plist)->head ? 0 : 1)
- struct ListNode {
- struct ListNode *next;
- struct ListNode *prev;
- void *data;
- };
- struct List {
- struct ListNode *head;
- struct ListNode *tail;
- };
- struct ListNode *list_node_new(void *data, size_t size) {
- struct ListNode *result = malloc(sizeof(struct ListNode));
- memset(result, 0, sizeof(struct ListNode));
- result->data = malloc(size);
- memcpy(result->data, data, size);
- return result;
- }
- void list_init(struct List *plist) {
- memset(plist, 0, sizeof(struct List));
- }
- void list_destroy(struct List *plist) {
- struct ListNode *itr = plist->head;
- for (; itr; itr = itr->next) {
- free(itr->data);
- if (itr->prev) {
- free(itr->prev);
- }
- }
- free(plist->tail);
- list_init(plist);
- }
- size_t list_size(struct List *plist) {
- size_t result = 0;
- struct ListNode *itr = plist->head;
- for (; itr; itr = itr->next) {
- ++result;
- }
- return result;
- }
- void *list_at(struct List *plist, size_t pos) {
- struct ListNode *itr = plist->head;
- for (; pos && itr; itr = itr->next) {
- --pos;
- }
- return pos ? NULL : itr->data;
- }
- void *list_next(struct ListNode **pitr, void *buffer, size_t size) {
- if (*pitr) {
- void *pdata = (*pitr)->data;
- memcpy(buffer, pdata, size);
- *pitr = (*pitr)->next;
- return pdata;
- }
- return NULL;
- }
- void *list_prev(struct ListNode **pitr, void *buffer, size_t size) {
- if (*pitr) {
- void *pdata = (*pitr)->data;
- memcpy(buffer, pdata, size);
- *pitr = (*pitr)->prev;
- return pdata;
- }
- return NULL;
- }
- void list_push_front(struct List *plist, void *data, size_t size) {
- if (plist->head == NULL) {
- plist->head = list_node_new(data, size);
- plist->tail = plist->head;
- } else {
- plist->head->prev = list_node_new(data, size);
- plist->head->prev->next = plist->head;
- plist->head = plist->head->prev;
- }
- }
- void list_push_back(struct List *plist, void *data, size_t size) {
- if (plist->head == NULL) {
- plist->head = list_node_new(data, size);
- plist->tail = plist->head;
- } else {
- plist->tail->next = list_node_new(data, size);
- plist->tail->next->prev = plist->tail;
- plist->tail = plist->tail->next;
- }
- }
- void list_insert(struct List *plist, size_t pos, void* data, size_t size) {
- struct ListNode *itr = plist->head;
- for (; pos && itr; itr = itr->next) {
- --pos;
- }
- if (itr && pos == 0) {
- if (plist->head == plist->tail) {
- list_push_front(plist, data, size);
- } else {
- if (itr == plist->head) {
- list_push_front(plist, data, size);
- } else if (itr == plist->tail) {
- list_push_back(plist, data, size);
- } else {
- struct ListNode *plnode = list_node_new(data, size);
- plnode->next = itr;
- plnode->prev = itr->prev;
- itr->prev->next = plnode;
- itr->prev = plnode;
- }
- }
- } else if (pos == 0) {
- list_push_back(plist, data, size);
- }
- }
- void list_pop_front(struct List *plist) {
- if (plist->head) {
- struct ListNode *temp = plist->head;
- plist->head = plist->head->next;
- if (plist->head) {
- plist->head->prev = NULL;
- } else {
- plist->tail = NULL;
- }
- free(temp->data);
- free(temp);
- }
- }
- void list_pop_back(struct List *plist) {
- if (plist->head) {
- struct ListNode *temp = plist->tail;
- plist->tail = plist->tail->prev;
- if (plist->tail) {
- plist->tail->next = NULL;
- } else {
- plist->head = NULL;
- }
- free(temp->data);
- free(temp);
- }
- }
- void list_remove(struct List *plist, size_t pos) {
- struct ListNode *itr = plist->head;
- for (; pos && itr; itr = itr->next) {
- --pos;
- }
- if (itr && pos == 0) {
- if (plist->head == plist->tail) {
- list_pop_back(plist);
- } else {
- if (itr == plist->head) {
- plist->head = plist->head->next;
- plist->head->prev = NULL;
- } else if (itr == plist->tail) {
- plist->tail = plist->tail->prev;
- plist->tail->next = NULL;
- } else {
- struct ListNode *prev = itr->prev;
- prev->next = itr->next;
- itr->next->prev = prev;
- }
- free(itr->data);
- free(itr);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment