88 void *next; |
88 void *next; |
89 char payload[]; |
89 char payload[]; |
90 }; |
90 }; |
91 |
91 |
92 typedef struct { |
92 typedef struct { |
|
93 cx_list_s base; |
93 void *begin; |
94 void *begin; |
94 void *end; |
95 void *end; |
95 ptrdiff_t loc_prev; |
96 ptrdiff_t loc_prev; |
96 ptrdiff_t loc_next; |
97 ptrdiff_t loc_next; |
97 } cx_linked_list; |
98 } cx_linked_list; |
98 |
99 |
99 int cx_ll_add(cx_list *list, void *elem) { |
100 int cx_ll_add(cx_list_s *list, void *elem) { |
100 cx_linked_list *listdata = (cx_linked_list *) list->listdata; |
101 cx_linked_list *linkedlist = (cx_linked_list *) list; |
101 CxAllocator allocator = list->allocator; |
102 |
102 |
103 struct cx_linked_list_node *node = cxMalloc(list->allocator, |
103 struct cx_linked_list_node *node = cxMalloc(allocator, |
|
104 sizeof(struct cx_linked_list_node) + list->itemsize); |
104 sizeof(struct cx_linked_list_node) + list->itemsize); |
105 if (node == NULL) |
105 if (node == NULL) |
106 return 1; |
106 return 1; |
107 |
107 |
108 node->next = NULL; |
108 node->next = node->prev = NULL; |
109 memcpy(node->payload, elem, list->itemsize); |
109 memcpy(node->payload, elem, list->itemsize); |
110 |
110 |
111 int ret = cx_linked_list_add( |
111 int ret = cx_linked_list_add( |
112 &listdata->begin, |
112 &linkedlist->begin, |
113 &listdata->end, |
113 &linkedlist->end, |
114 offsetof(struct cx_linked_list_node, prev), |
114 offsetof(struct cx_linked_list_node, prev), |
115 offsetof(struct cx_linked_list_node, next), |
115 offsetof(struct cx_linked_list_node, next), |
116 node |
116 node |
117 ); |
117 ); |
118 if (ret == 0) { |
118 if (ret == 0) { |
121 } else { |
121 } else { |
122 return ret; |
122 return ret; |
123 } |
123 } |
124 } |
124 } |
125 |
125 |
126 int cx_ll_insert(cx_list *list, size_t index, void *elem) { |
126 int cx_ll_insert(cx_list_s *list, size_t index, void *elem) { |
127 cx_linked_list *listdata = (cx_linked_list *) list->listdata; |
127 cx_linked_list *linkedList = (cx_linked_list *) list; |
128 // TODO: implement using low level API |
128 // TODO: implement using low level API |
129 return 1; |
129 return 1; |
130 } |
130 } |
131 |
131 |
132 void *cx_ll_remove(cx_list *list, size_t index) { |
132 void *cx_ll_remove(cx_list_s *list, size_t index) { |
133 cx_linked_list *listdata = (cx_linked_list *) list->listdata; |
133 cx_linked_list *linkedList = (cx_linked_list *) list; |
134 // TODO: implement using low level API |
134 // TODO: implement using low level API |
135 return NULL; |
135 return NULL; |
136 } |
136 } |
137 |
137 |
138 size_t cx_ll_find(cx_list *list, void *elem) { |
138 size_t cx_ll_find(cx_list_s *list, void *elem) { |
139 cx_linked_list *listdata = (cx_linked_list *) list->listdata; |
139 cx_linked_list *linkedList = (cx_linked_list *) list; |
140 // TODO: implement using low level API |
140 // TODO: implement using low level API |
141 return 0; |
141 return 0; |
142 } |
142 } |
143 |
143 |
144 void *cx_ll_last(cx_list *list) { |
144 void *cx_ll_last(cx_list_s *list) { |
145 cx_linked_list *listdata = (cx_linked_list *) list->listdata; |
145 cx_linked_list *linkedList = (cx_linked_list *) list; |
146 struct cx_linked_list_node *last = cx_linked_list_last( |
146 struct cx_linked_list_node *last = cx_linked_list_last( |
147 NULL, &listdata->end, offsetof(struct cx_linked_list_node, next)); |
147 NULL, &linkedList->end, offsetof(struct cx_linked_list_node, next)); |
148 return &last->payload; |
148 return &last->payload; |
149 } |
149 } |
150 |
150 |
151 cx_list_class cx_linked_list_class = { |
151 cx_list_class cx_linked_list_class = { |
152 cx_ll_add, |
152 cx_ll_add, |
155 cx_ll_find, |
155 cx_ll_find, |
156 cx_ll_last |
156 cx_ll_last |
157 }; |
157 }; |
158 |
158 |
159 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { |
159 CxList cxLinkedListCreate(CxAllocator allocator, CxListComparator comparator, size_t item_size) { |
160 CxList list = cxMalloc(allocator, sizeof(cx_list_s) + sizeof(cx_linked_list)); |
160 cx_linked_list* list = cxMalloc(allocator, sizeof(cx_linked_list)); |
161 if (list == NULL) |
161 if (list == NULL) |
162 return NULL; |
162 return NULL; |
163 |
163 |
164 list->cl = &cx_linked_list_class; |
164 list->base.cl = &cx_linked_list_class; |
165 list->data.allocator = allocator; |
165 list->base.allocator = allocator; |
166 list->data.cmpfunc = comparator; |
166 list->base.cmpfunc = comparator; |
167 list->data.itemsize = item_size; |
167 list->base.itemsize = item_size; |
168 list->data.capacity = SIZE_MAX; |
168 list->base.capacity = SIZE_MAX; |
169 |
169 |
170 cx_linked_list *ll = (cx_linked_list *) list->data.listdata; |
170 list->begin = NULL; |
171 ll->begin = NULL; |
171 list->loc_prev = offsetof(struct cx_linked_list_node, prev); |
172 ll->loc_prev = offsetof(struct cx_linked_list_node, prev); |
172 list->loc_next = offsetof(struct cx_linked_list_node, next); |
173 ll->loc_next = offsetof(struct cx_linked_list_node, next); |
173 |
174 cxLinkedListRecalculateSize(list); |
174 CxList result = (CxList) list; |
175 |
175 cxLinkedListRecalculateSize(result); |
176 return list; |
176 return result; |
177 } |
177 } |
178 |
178 |
179 void cxLinkedListDestroy(CxList list) { |
179 void cxLinkedListDestroy(CxList list) { |
180 // TODO: free contents |
180 // TODO: free contents |
181 cxFree(list->data.allocator, list); |
181 cxFree(list->allocator, list); |
182 } |
182 } |
183 |
183 |
184 size_t cxLinkedListRecalculateSize(CxList list) { |
184 size_t cxLinkedListRecalculateSize(CxList list) { |
185 cx_linked_list *ll = (cx_linked_list *) list->data.listdata; |
185 cx_linked_list *ll = (cx_linked_list *) list; |
186 |
186 |
187 if (ll->begin == NULL) { |
187 if (ll->begin == NULL) { |
188 list->data.size = 0; |
188 ll->base.size = 0; |
189 ll->end = NULL; |
189 ll->end = NULL; |
190 return 0; |
190 return 0; |
191 } else { |
191 } else { |
192 void *cur = ll->begin; |
192 void *cur = ll->begin; |
193 void *last; |
193 void *last; |
194 size_t size; |
194 size_t size = 0; |
195 do { |
195 do { |
196 last = cur; |
196 last = cur; |
197 size++; |
197 size++; |
198 } while ((cur = *CX_LL_PTR(cur, ll->loc_next)) != NULL); |
198 } while ((cur = *CX_LL_PTR(cur, ll->loc_next)) != NULL); |
199 ll->end = last; |
199 ll->end = last; |
200 list->data.size = size; |
200 ll->base.size = size; |
201 return size; |
201 return size; |
202 } |
202 } |
203 } |
203 } |