164 bool backward |
164 bool backward |
165 ) { |
165 ) { |
166 const cx_kv_list *kv_list = (const cx_kv_list*)list; |
166 const cx_kv_list *kv_list = (const cx_kv_list*)list; |
167 // TODO: cannot really forward, because mutating iterators must be able to remove the element |
167 // TODO: cannot really forward, because mutating iterators must be able to remove the element |
168 return kv_list->list_methods->iterator(list, index, backward); |
168 return kv_list->list_methods->iterator(list, index, backward); |
|
169 } |
|
170 |
|
171 static void cx_kvl_map_deallocate(struct cx_map_s *map) { |
|
172 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
|
173 kv_list->map_methods->deallocate(map); |
|
174 kv_list->list_methods->deallocate(&kv_list->list.list_base); |
|
175 } |
|
176 |
|
177 static void cx_kvl_map_clear(struct cx_map_s *map) { |
|
178 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
|
179 // TODO: iterate through the map elements and remove the key from the referenced list items |
|
180 kv_list->map_methods->clear(map); |
|
181 } |
|
182 |
|
183 static void *cx_kvl_map_put(CxMap *map, CxHashKey key, void *value) { |
|
184 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
|
185 // insert the data into the list first (assume that insertion destroys the sorted property) |
|
186 kv_list->list.list_base.collection.sorted = false; |
|
187 // TODO: use the same trick as above to increase the element size temporarily to add the key to the data |
|
188 void *node_data = kv_list->list_methods->insert_element( |
|
189 &kv_list->list.list_base, kv_list->list.list_base.collection.size, value); |
|
190 if (node_data == NULL) return NULL; // LCOV_EXCL_LINE |
|
191 // then insert the key into the map, referring to the node data |
|
192 // TODO: check if we still get a correct pointer when the list is storing pointers |
|
193 return kv_list->map_methods->put(map, key, node_data); |
|
194 } |
|
195 |
|
196 void *cx_kvl_map_get(const CxMap *map, CxHashKey key) { |
|
197 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
|
198 return kv_list->map_methods->get(map, key); |
|
199 } |
|
200 |
|
201 int cx_kvl_map_remove(CxMap *map, CxHashKey key, void *targetbuf) { |
|
202 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
|
203 // TODO: also remove the item from the list |
|
204 return kv_list->map_methods->remove(map, key, targetbuf); |
|
205 } |
|
206 |
|
207 CxMapIterator cx_kvl_map_iterator(const CxMap *map, enum cx_map_iterator_type type) { |
|
208 cx_kv_list *kv_list = ((struct cx_kv_list_map_s*)map)->list; |
|
209 return kv_list->map_methods->iterator(map, type); |
169 } |
210 } |
170 |
211 |
171 static cx_list_class cx_kv_list_class = { |
212 static cx_list_class cx_kv_list_class = { |
172 cx_kvl_deallocate, |
213 cx_kvl_deallocate, |
173 cx_kvl_insert_element, |
214 cx_kvl_insert_element, |
209 |
259 |
210 // reallocate the map to add memory for the list back-reference |
260 // reallocate the map to add memory for the list back-reference |
211 struct cx_kv_list_map_s *kv_map = cxRealloc(allocator, map, sizeof(struct cx_kv_list_map_s)); |
261 struct cx_kv_list_map_s *kv_map = cxRealloc(allocator, map, sizeof(struct cx_kv_list_map_s)); |
212 |
262 |
213 // reallocate the list to add memory for storing the metadata |
263 // reallocate the list to add memory for storing the metadata |
214 cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(cx_kv_list)); |
264 cx_kv_list *kv_list = cxRealloc(allocator, list, sizeof(struct cx_kv_list_s)); |
215 |
265 |
216 // if any of the reallocations failed, we bail out |
266 // if any of the reallocations failed, we bail out |
217 if (kv_map != NULL && kv_list != NULL) { |
267 if (kv_map != NULL && kv_list != NULL) { |
218 map = (CxMap*) kv_map; |
268 map = (CxMap*) kv_map; |
219 list = (CxList*) kv_list; |
269 list = (CxList*) kv_list; |
227 kv_list->map = kv_map; |
277 kv_list->map = kv_map; |
228 kv_map->list = kv_list; |
278 kv_map->list = kv_list; |
229 |
279 |
230 // remember the base methods and override them |
280 // remember the base methods and override them |
231 kv_list->map_methods = map->cl; |
281 kv_list->map_methods = map->cl; |
|
282 map->cl = &cx_kv_map_class; |
232 if (list->climpl == NULL) { |
283 if (list->climpl == NULL) { |
233 kv_list->list_methods = list->cl; |
284 kv_list->list_methods = list->cl; |
234 list->cl = &cx_kv_list_class; |
285 list->cl = &cx_kv_list_class; |
235 } else { |
286 } else { |
236 kv_list->list_methods = list->climpl; |
287 kv_list->list_methods = list->climpl; |
237 list->climpl = &cx_kv_list_class; |
288 list->climpl = &cx_kv_list_class; |
238 } |
289 } |
239 // TODO: override all map members |
|
240 // and remember to set the sorted flag of the list to false in the put/emplace methods! |
|
241 |
290 |
242 return list; |
291 return list; |
243 } |
292 } |
244 |
293 |
245 CxMap *cxKvListCreateAsMap( |
294 CxMap *cxKvListCreateAsMap( |