inli.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include "inli.h"
  2. #include <stdlib.h>
  3. /*
  4. Title: Intrusive Linked Lists
  5. */
  6. /**
  7. * Struct: Inli
  8. *
  9. * Intrusive linked lists.
  10. */
  11. /**
  12. * Function: inli_initall
  13. *
  14. * Fully initializes a non-NULL intrusive linked list.
  15. *
  16. * Parameters:
  17. * self - Inli to initialize
  18. * next - Next Inli list node to link to or NULL
  19. * prev - Previous Inli list node to link to or NULL
  20. *
  21. * Returns:
  22. * self
  23. */
  24. Inli * inli_initall(Inli * self, Inli * next, Inli * prev) {
  25. if (!self) return NULL;
  26. self->next = next;
  27. self->prev = prev;
  28. return self;
  29. }
  30. /**
  31. * Function: inli_init
  32. *
  33. * Initializes the intrusive linked list. Next and prev are set to NULL.
  34. *
  35. * Parameters:
  36. * self - Inli to initialize
  37. *
  38. * Returns:
  39. * self
  40. */
  41. Inli * inli_init(Inli * self) {
  42. return inli_initall(self, NULL, NULL);
  43. }
  44. /**
  45. * Function: inli_remove
  46. *
  47. * Removes self from the list it is part of.
  48. * Does NOT clean up any data asssociated with the container of the intrusive
  49. * list and also doesn't free self, since self should be part of the container
  50. * of the intrusive list.
  51. *
  52. * Parameters:
  53. * self - Inli to remove from whole of list
  54. *
  55. * Returns:
  56. * self
  57. */
  58. Inli * inli_remove(Inli * self) {
  59. if(!self) return NULL;
  60. if(self->prev) { self->prev->next = self->next; }
  61. if(self->next) { self->next->prev = self->prev; }
  62. self->prev = NULL;
  63. self->next = NULL;
  64. return self;
  65. }
  66. /**
  67. * Function: inli_add
  68. *
  69. * Appends other after self.
  70. *
  71. * Parameters:
  72. * self - Inli to append to
  73. * other - Inli to append to self.
  74. *
  75. * Returns:
  76. * other if all went OK, NULL on error
  77. */
  78. Inli * inli_add(Inli * self, Inli * other) {
  79. if(!self || !other) return NULL;
  80. self->next = other;
  81. other->prev = self;
  82. return other;
  83. }
  84. /**
  85. * Function: inli_next
  86. *
  87. * Returns the next element in the list
  88. *
  89. * Parameters:
  90. * self - Inli
  91. *
  92. * Returns:
  93. * the next element in the list, or NULL if no next item.
  94. */
  95. Inli * inli_next(Inli * self) {
  96. if(!self) return NULL;
  97. return self->next;
  98. }
  99. /**
  100. * Function: inli_prev
  101. *
  102. * Returns the previous element in the list
  103. *
  104. * Parameters:
  105. * self - Inli
  106. *
  107. * Returns:
  108. * the next element in the list, or NULL if no next item.
  109. */
  110. Inli * inli_prev(Inli * self) {
  111. if(!self) return NULL;
  112. return self->prev;
  113. }
  114. /**
  115. * Function: inli_first
  116. *
  117. * Returns the first element in the list, by dumb iteration.
  118. *
  119. * Parameters:
  120. * self - Inli
  121. *
  122. * Returns:
  123. * the first link in the list, or NULL if self is NULL.
  124. */
  125. Inli * inli_first(Inli * self) {
  126. Inli * aid = self;
  127. if(!aid) return NULL;
  128. while (aid->prev) {
  129. aid = aid->prev;
  130. }
  131. return aid;
  132. }
  133. /**
  134. * Function: inli_last
  135. *
  136. * Returns the last element in the list, by dumb iteration.
  137. *
  138. * Parameters:
  139. * self - Inli
  140. *
  141. * Returns:
  142. * the last link in the list, or NULL if self is NULL.
  143. */
  144. Inli * inli_last(Inli * self) {
  145. Inli * aid = self;
  146. if(!aid) return NULL;
  147. while (aid->next) {
  148. aid = aid->next;
  149. }
  150. return aid;
  151. }
  152. /**
  153. * Function: inli_push
  154. *
  155. * Appends other to the end of the list by dumb iteration.
  156. *
  157. * Parameters:
  158. * self - Inli
  159. *
  160. * Returns:
  161. * other, or NULL if self or other is NULL.
  162. */
  163. Inli * inli_push(Inli * self, Inli * other) {
  164. Inli * aid;
  165. aid = inli_last(self);
  166. return inli_add(aid, other);
  167. }
  168. /**
  169. * Function: inli_unshift
  170. *
  171. * Prepends other to the beginning of the list by dumb iteration.
  172. *
  173. * Parameters:
  174. * self - Inli
  175. *
  176. * Returns:
  177. * other, or NULL if self or other is NULL.
  178. */
  179. Inli * inli_unshift(Inli * self, Inli * other) {
  180. Inli * aid;
  181. aid = inli_first(self);
  182. return inli_add(other, self);
  183. }
  184. /**
  185. * Function: inli_shift
  186. *
  187. * Removes the first element from the list by dumb iteration.
  188. *
  189. * Parameters:
  190. * self - Inli
  191. *
  192. * Returns:
  193. * list node that was removed, or NULL if self is NULL.
  194. */
  195. Inli * inli_shift(Inli * self) {
  196. Inli * aid;
  197. aid = inli_first(self);
  198. return inli_remove(aid);
  199. }
  200. /**
  201. * Function: inli_pop
  202. *
  203. * Removes the last element from the list by dumb iteration.
  204. *
  205. * Parameters:
  206. * self - Inli
  207. *
  208. * Returns:
  209. * list node that was removed, or NULL if self is NULL.
  210. */
  211. Inli * inli_pop(Inli * self) {
  212. Inli * aid;
  213. aid = inli_last(self);
  214. return inli_remove(aid);
  215. }
  216. /**
  217. * Function: inli_data
  218. *
  219. * Parameters:
  220. * self - list node to get the data of.
  221. * offset - Use offsetof to calculate this offset.
  222. *
  223. * Returns:
  224. * the data for this node of the singly linked list.
  225. *
  226. */
  227. void * inli_data(Inli * self, int offset) {
  228. if(!self) return NULL;
  229. return (void *)((char *)self - offset);
  230. }