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, |