src/linked_list.c

changeset 456
227c2eabbef8
parent 453
bb144d08cd44
child 457
8f7d3fe9ca40
equal deleted inserted replaced
455:8168e16cd1e9 456:227c2eabbef8
43 i < index ? i++ : i--; 43 i < index ? i++ : i--;
44 } 44 }
45 return cur; 45 return cur;
46 } 46 }
47 47
48 void *cx_linked_list_last(void **begin, void **end, ptrdiff_t loc_next) { 48 void *cx_linked_list_last(void *begin, ptrdiff_t loc_next) {
49 if (end != NULL) { 49 if (begin == NULL)
50 return *end; 50 return NULL;
51 } else { 51
52 if (begin == NULL || *begin == NULL) 52 void *cur = begin;
53 return NULL; 53 void *last;
54 54 do {
55 void *cur = *begin; 55 last = cur;
56 void *last; 56 } while ((cur = *CX_LL_PTR(cur, loc_next)) != NULL);
57 do { 57
58 last = cur; 58 return last;
59 } while ((cur = *CX_LL_PTR(cur, loc_next)) != NULL);
60
61 return last;
62 }
63 } 59 }
64 60
65 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { 61 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) {
66 void *last = cx_linked_list_last(begin, end, loc_next); 62 void *last;
63 if (end == NULL) {
64 assert(begin != NULL);
65 last = cx_linked_list_last(*begin, loc_next);
66 } else {
67 last = *end;
68 }
67 if (last == NULL) { 69 if (last == NULL) {
68 assert(begin != NULL); 70 assert(begin != NULL);
69 *begin = new_node; 71 *begin = new_node;
70 } else { 72 } else {
71 // if there is a last node, update its next pointer 73 // if there is a last node, update its next pointer
73 *next = new_node; 75 *next = new_node;
74 } 76 }
75 77
76 // if there is an end pointer, update it 78 // if there is an end pointer, update it
77 if (end != NULL) { 79 if (end != NULL) {
78 *end = cx_linked_list_last(&new_node, NULL, loc_next); 80 *end = cx_linked_list_last(new_node, loc_next);
79 } 81 }
80 82
81 // if the nodes use a prev pointer, update it 83 // if the nodes use a prev pointer, update it
82 if (loc_prev >= 0) { 84 if (loc_prev >= 0) {
83 void **prev = CX_LL_PTR(new_node, loc_prev); 85 void **prev = CX_LL_PTR(new_node, loc_prev);
222 return index; 224 return index;
223 } 225 }
224 226
225 static void *cx_ll_last(cx_list_s *list) { 227 static void *cx_ll_last(cx_list_s *list) {
226 cx_linked_list *ll = (cx_linked_list *) list; 228 cx_linked_list *ll = (cx_linked_list *) list;
227 cx_linked_list_node *last = cx_linked_list_last(NULL, (void **) &ll->end, CX_LL_LOC_NEXT); 229 cx_linked_list_node *last = ll->end;
228 return &last->payload; 230 return last == NULL ? NULL : &last->payload;
229 } 231 }
230 232
231 static cx_list_class cx_linked_list_class = { 233 static cx_list_class cx_linked_list_class = {
232 cx_ll_add, 234 cx_ll_add,
233 cx_ll_insert, 235 cx_ll_insert,

mercurial