45 i < index ? i++ : i--; |
45 i < index ? i++ : i--; |
46 } |
46 } |
47 return cur; |
47 return cur; |
48 } |
48 } |
49 |
49 |
50 void *cx_linked_list_last(void *begin, ptrdiff_t loc_next) { |
50 void *cx_linked_list_first(void *node, ptrdiff_t loc_prev) { |
51 assert(loc_next >= 0); |
51 return cx_linked_list_last(node, loc_prev); |
52 if (begin == NULL) |
52 } |
|
53 |
|
54 void *cx_linked_list_last(void *node, ptrdiff_t loc_next) { |
|
55 assert(loc_next >= 0); |
|
56 if (node == NULL) |
53 return NULL; |
57 return NULL; |
54 |
58 |
55 void *cur = begin; |
59 void *cur = node; |
56 void *last; |
60 void *last; |
57 do { |
61 do { |
58 last = cur; |
62 last = cur; |
59 } while ((cur = CX_LL_PTR(cur, loc_next)) != NULL); |
63 } while ((cur = CX_LL_PTR(cur, loc_next)) != NULL); |
60 |
64 |
74 } |
78 } |
75 } |
79 } |
76 |
80 |
77 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { |
81 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { |
78 assert(loc_next >= 0); |
82 assert(loc_next >= 0); |
|
83 assert(CX_LL_PTR(new_node, loc_next) == NULL); |
79 void *last; |
84 void *last; |
80 if (end == NULL) { |
85 if (end == NULL) { |
81 assert(begin != NULL); |
86 assert(begin != NULL); |
82 last = cx_linked_list_last(*begin, loc_next); |
87 last = cx_linked_list_last(*begin, loc_next); |
83 } else { |
88 } else { |
84 last = *end; |
89 last = *end; |
85 } |
90 } |
86 if (last == NULL) { |
91 if (last == NULL) { |
87 assert(begin != NULL); |
92 if (begin != NULL) { |
88 *begin = new_node; |
93 *begin = new_node; |
|
94 } |
89 } else { |
95 } else { |
90 // if there is a last node, update its next pointer |
96 // if there is a last node, update its next pointer |
91 CX_LL_PTR(last, loc_next) = new_node; |
97 CX_LL_PTR(last, loc_next) = new_node; |
92 } |
98 } |
93 |
99 |
94 // if there is an end pointer, update it |
100 // if there is an end pointer, update it |
95 if (end != NULL) { |
101 if (end != NULL) { |
96 *end = cx_linked_list_last(new_node, loc_next); |
102 *end = new_node; |
97 } |
103 } |
98 |
104 |
99 // if the nodes use a prev pointer, update it |
105 // if the nodes use a prev pointer, update it |
100 if (loc_prev >= 0) { |
106 if (loc_prev >= 0) { |
|
107 assert(CX_LL_PTR(new_node, loc_prev) == NULL); |
101 CX_LL_PTR(new_node, loc_prev) = last; |
108 CX_LL_PTR(new_node, loc_prev) = last; |
|
109 } |
|
110 } |
|
111 |
|
112 void cx_linked_list_prepend(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { |
|
113 assert(loc_next >= 0); |
|
114 assert(CX_LL_PTR(new_node, loc_next) == NULL); |
|
115 void *first; |
|
116 if (begin == NULL) { |
|
117 assert(end != NULL); |
|
118 assert(loc_prev >= 0); |
|
119 first = cx_linked_list_first(*end, loc_prev); |
|
120 } else { |
|
121 first = *begin; |
|
122 } |
|
123 if (first == NULL) { |
|
124 if (end != NULL) { |
|
125 *end = new_node; |
|
126 } |
|
127 } else { |
|
128 CX_LL_PTR(new_node, loc_next) = first; |
|
129 if (loc_prev >= 0) { |
|
130 CX_LL_PTR(first, loc_prev) = new_node; |
|
131 } |
|
132 } |
|
133 |
|
134 if (begin != NULL) { |
|
135 assert(loc_prev < 0 || CX_LL_PTR(new_node, loc_prev) == NULL); |
|
136 *begin = new_node; |
102 } |
137 } |
103 } |
138 } |
104 |
139 |
105 void *cx_linked_list_remove(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node) { |
140 void *cx_linked_list_remove(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node) { |
106 assert(loc_next >= 0); |
141 assert(loc_next >= 0); |