123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- #include "inli.h"
- #include <stdlib.h>
- /*
- Title: Intrusive Linked Lists
- */
- /**
- * Struct: Inli
- *
- * Intrusive linked lists.
- */
- /**
- * Function: inli_initall
- *
- * Fully initializes a non-NULL intrusive linked list.
- *
- * Parameters:
- * self - Inli to initialize
- * next - Next Inli list node to link to or NULL
- * prev - Previous Inli list node to link to or NULL
- *
- * Returns:
- * self
- */
- Inli * inli_initall(Inli * self, Inli * next, Inli * prev) {
- if (!self) return NULL;
- self->next = next;
- self->prev = prev;
- return self;
- }
- /**
- * Function: inli_init
- *
- * Initializes the intrusive linked list. Next and prev are set to NULL.
- *
- * Parameters:
- * self - Inli to initialize
- *
- * Returns:
- * self
- */
- Inli * inli_init(Inli * self) {
- return inli_initall(self, NULL, NULL);
- }
- /**
- * Function: inli_remove
- *
- * Removes self from the list it is part of.
- * Does NOT clean up any data asssociated with the container of the intrusive
- * list and also doesn't free self, since self should be part of the container
- * of the intrusive list.
- *
- * Parameters:
- * self - Inli to remove from whole of list
- *
- * Returns:
- * self
- */
- Inli * inli_remove(Inli * self) {
- if(!self) return NULL;
- if(self->prev) { self->prev->next = self->next; }
- if(self->next) { self->next->prev = self->prev; }
- self->prev = NULL;
- self->next = NULL;
- return self;
- }
- /**
- * Function: inli_add
- *
- * Appends other after self.
- *
- * Parameters:
- * self - Inli to append to
- * other - Inli to append to self.
- *
- * Returns:
- * other if all went OK, NULL on error
- */
- Inli * inli_add(Inli * self, Inli * other) {
- if(!self || !other) return NULL;
- self->next = other;
- other->prev = self;
- return other;
- }
- /**
- * Function: inli_next
- *
- * Returns the next element in the list
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * the next element in the list, or NULL if no next item.
- */
- Inli * inli_next(Inli * self) {
- if(!self) return NULL;
- return self->next;
- }
- /**
- * Function: inli_prev
- *
- * Returns the previous element in the list
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * the next element in the list, or NULL if no next item.
- */
- Inli * inli_prev(Inli * self) {
- if(!self) return NULL;
- return self->prev;
- }
- /**
- * Function: inli_first
- *
- * Returns the first element in the list, by dumb iteration.
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * the first link in the list, or NULL if self is NULL.
- */
- Inli * inli_first(Inli * self) {
- Inli * aid = self;
- if(!aid) return NULL;
- while (aid->prev) {
- aid = aid->prev;
- }
- return aid;
- }
- /**
- * Function: inli_last
- *
- * Returns the last element in the list, by dumb iteration.
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * the last link in the list, or NULL if self is NULL.
- */
- Inli * inli_last(Inli * self) {
- Inli * aid = self;
- if(!aid) return NULL;
- while (aid->next) {
- aid = aid->next;
- }
- return aid;
- }
- /**
- * Function: inli_push
- *
- * Appends other to the end of the list by dumb iteration.
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * other, or NULL if self or other is NULL.
- */
- Inli * inli_push(Inli * self, Inli * other) {
- Inli * aid;
- aid = inli_last(self);
- return inli_add(aid, other);
- }
- /**
- * Function: inli_unshift
- *
- * Prepends other to the beginning of the list by dumb iteration.
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * other, or NULL if self or other is NULL.
- */
- Inli * inli_unshift(Inli * self, Inli * other) {
- Inli * aid;
- aid = inli_first(self);
- return inli_add(other, self);
- }
- /**
- * Function: inli_shift
- *
- * Removes the first element from the list by dumb iteration.
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * list node that was removed, or NULL if self is NULL.
- */
- Inli * inli_shift(Inli * self) {
- Inli * aid;
- aid = inli_first(self);
- return inli_remove(aid);
- }
- /**
- * Function: inli_pop
- *
- * Removes the last element from the list by dumb iteration.
- *
- * Parameters:
- * self - Inli
- *
- * Returns:
- * list node that was removed, or NULL if self is NULL.
- */
- Inli * inli_pop(Inli * self) {
- Inli * aid;
- aid = inli_last(self);
- return inli_remove(aid);
- }
- /**
- * Function: inli_data
- *
- * Parameters:
- * self - list node to get the data of.
- * offset - Use offsetof to calculate this offset.
- *
- * Returns:
- * the data for this node of the singly linked list.
- *
- */
- void * inli_data(Inli * self, int offset) {
- if(!self) return NULL;
- return (void *)((char *)self - offset);
- }
|