118 node->next = node->prev = NULL; |
121 node->next = node->prev = NULL; |
119 memcpy(node->payload, elem, list->itemsize); |
122 memcpy(node->payload, elem, list->itemsize); |
120 |
123 |
121 int ret = cx_linked_list_add( |
124 int ret = cx_linked_list_add( |
122 &ll->begin, &ll->end, |
125 &ll->begin, &ll->end, |
123 offsetof(struct cx_linked_list_node, prev), |
126 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, |
124 offsetof(struct cx_linked_list_node, next), |
|
125 node |
127 node |
126 ); |
128 ); |
127 if (ret == 0) { |
129 if (ret == 0) { |
128 list->size++; |
130 list->size++; |
129 return 0; |
131 return 0; |
143 return 1; |
145 return 1; |
144 } |
146 } |
145 cx_linked_list *ll = (cx_linked_list *) list; |
147 cx_linked_list *ll = (cx_linked_list *) list; |
146 // TODO: implement using low level API |
148 // TODO: implement using low level API |
147 return 0; |
149 return 0; |
|
150 } |
|
151 |
|
152 static void *cx_ll_at(cx_list_s *list, size_t index) { |
|
153 cx_linked_list *ll = (cx_linked_list *) list; |
|
154 struct cx_linked_list_node *node; |
|
155 if (index > list->size / 2) { |
|
156 node = cx_linked_list_at(ll->begin, 0, CX_LL_LOC_NEXT, index); |
|
157 } else { |
|
158 node = cx_linked_list_at(ll->end, list->size, CX_LL_LOC_PREV, index); |
|
159 } |
|
160 return &node->payload; |
148 } |
161 } |
149 |
162 |
150 static size_t cx_ll_find(cx_list_s *list, void *elem) { |
163 static size_t cx_ll_find(cx_list_s *list, void *elem) { |
151 CxListComparator cmp = list->cmpfunc; |
164 CxListComparator cmp = list->cmpfunc; |
152 cx_linked_list *ll = (cx_linked_list *) list; |
165 cx_linked_list *ll = (cx_linked_list *) list; |
162 } |
175 } |
163 return index; |
176 return index; |
164 } |
177 } |
165 |
178 |
166 static void *cx_ll_last(cx_list_s *list) { |
179 static void *cx_ll_last(cx_list_s *list) { |
167 cx_linked_list *linkedList = (cx_linked_list *) list; |
180 cx_linked_list *ll = (cx_linked_list *) list; |
168 struct cx_linked_list_node *last = cx_linked_list_last( |
181 struct cx_linked_list_node *last = cx_linked_list_last(NULL, &ll->end, CX_LL_LOC_NEXT); |
169 NULL, &linkedList->end, offsetof(struct cx_linked_list_node, next)); |
|
170 return &last->payload; |
182 return &last->payload; |
171 } |
183 } |
172 |
184 |
173 cx_list_class cx_linked_list_class = { |
185 cx_list_class cx_linked_list_class = { |
174 cx_ll_add, |
186 cx_ll_add, |
175 cx_ll_insert, |
187 cx_ll_insert, |
176 cx_ll_remove, |
188 cx_ll_remove, |
|
189 cx_ll_at, |
177 cx_ll_find, |
190 cx_ll_find, |
178 cx_ll_last |
191 cx_ll_last |
179 }; |
192 }; |
180 |
193 |
181 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { |
194 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { |
188 list->base.cmpfunc = comparator; |
201 list->base.cmpfunc = comparator; |
189 list->base.itemsize = item_size; |
202 list->base.itemsize = item_size; |
190 list->base.capacity = SIZE_MAX; |
203 list->base.capacity = SIZE_MAX; |
191 |
204 |
192 list->begin = NULL; |
205 list->begin = NULL; |
193 list->loc_prev = offsetof(struct cx_linked_list_node, prev); |
206 list->loc_prev = CX_LL_LOC_PREV; |
194 list->loc_next = offsetof(struct cx_linked_list_node, next); |
207 list->loc_next = CX_LL_LOC_NEXT; |
195 |
208 |
196 CxList result = (CxList) list; |
209 CxList result = (CxList) list; |
197 cxLinkedListRecalculateSize(result); |
210 cxLinkedListRecalculateSize(result); |
198 return result; |
211 return result; |
199 } |
212 } |