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