45 return cx_pl_cmpfunc_impl(left, right); |
45 return cx_pl_cmpfunc_impl(left, right); |
46 } |
46 } |
47 |
47 |
48 static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) { |
48 static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) { |
49 // cast away const - this is the hacky thing |
49 // cast away const - this is the hacky thing |
50 struct cx_collection_s *l = (struct cx_collection_s*) &list->base; |
50 struct cx_collection_s *l = (struct cx_collection_s*) &list->collection; |
51 cx_pl_cmpfunc_impl = l->cmpfunc; |
51 cx_pl_cmpfunc_impl = l->cmpfunc; |
52 l->cmpfunc = cx_pl_cmpfunc; |
52 l->cmpfunc = cx_pl_cmpfunc; |
53 } |
53 } |
54 |
54 |
55 static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) { |
55 static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) { |
56 // cast away const - this is the hacky thing |
56 // cast away const - this is the hacky thing |
57 struct cx_collection_s *l = (struct cx_collection_s*) &list->base; |
57 struct cx_collection_s *l = (struct cx_collection_s*) &list->collection; |
58 l->cmpfunc = cx_pl_cmpfunc_impl; |
58 l->cmpfunc = cx_pl_cmpfunc_impl; |
59 } |
59 } |
60 |
60 |
61 static void cx_pl_destructor(struct cx_list_s *list) { |
61 static void cx_pl_destructor(struct cx_list_s *list) { |
62 list->climpl->destructor(list); |
62 list->climpl->destructor(list); |
178 cx_pl_reverse, |
178 cx_pl_reverse, |
179 cx_pl_iterator, |
179 cx_pl_iterator, |
180 }; |
180 }; |
181 |
181 |
182 void cxListStoreObjects(CxList *list) { |
182 void cxListStoreObjects(CxList *list) { |
183 list->base.store_pointer = false; |
183 list->collection.store_pointer = false; |
184 if (list->climpl != NULL) { |
184 if (list->climpl != NULL) { |
185 list->cl = list->climpl; |
185 list->cl = list->climpl; |
186 list->climpl = NULL; |
186 list->climpl = NULL; |
187 } |
187 } |
188 } |
188 } |
189 |
189 |
190 void cxListStorePointers(CxList *list) { |
190 void cxListStorePointers(CxList *list) { |
191 list->base.elem_size = sizeof(void *); |
191 list->collection.elem_size = sizeof(void *); |
192 list->base.store_pointer = true; |
192 list->collection.store_pointer = true; |
193 list->climpl = list->cl; |
193 list->climpl = list->cl; |
194 list->cl = &cx_pointer_list_class; |
194 list->cl = &cx_pointer_list_class; |
195 } |
195 } |
196 |
196 |
197 // </editor-fold> |
197 // </editor-fold> |
219 |
219 |
220 static int cx_emptyl_compare( |
220 static int cx_emptyl_compare( |
221 __attribute__((__unused__)) struct cx_list_s const *list, |
221 __attribute__((__unused__)) struct cx_list_s const *list, |
222 struct cx_list_s const *other |
222 struct cx_list_s const *other |
223 ) { |
223 ) { |
224 if (other->base.size == 0) return 0; |
224 if (other->collection.size == 0) return 0; |
225 return -1; |
225 return -1; |
226 } |
226 } |
227 |
227 |
228 static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) { |
228 static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) { |
229 return false; |
229 return false; |
284 CxList const *list, |
284 CxList const *list, |
285 CxList const *other |
285 CxList const *other |
286 ) { |
286 ) { |
287 if ( |
287 if ( |
288 // if one is storing pointers but the other is not |
288 // if one is storing pointers but the other is not |
289 (list->base.store_pointer ^ other->base.store_pointer) || |
289 (list->collection.store_pointer ^ other->collection.store_pointer) || |
290 |
290 |
291 // if one class is wrapped but the other is not |
291 // if one class is wrapped but the other is not |
292 ((list->climpl == NULL) ^ (other->climpl == NULL)) || |
292 ((list->climpl == NULL) ^ (other->climpl == NULL)) || |
293 |
293 |
294 // if the resolved compare functions are not the same |
294 // if the resolved compare functions are not the same |
295 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) != |
295 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) != |
296 (other->climpl != NULL ? other->climpl->compare : other->cl->compare)) |
296 (other->climpl != NULL ? other->climpl->compare : other->cl->compare)) |
297 ) { |
297 ) { |
298 // lists are definitely different - cannot use internal compare function |
298 // lists are definitely different - cannot use internal compare function |
299 if (list->base.size == other->base.size) { |
299 if (list->collection.size == other->collection.size) { |
300 CxIterator left = list->cl->iterator(list, 0, false); |
300 CxIterator left = list->cl->iterator(list, 0, false); |
301 CxIterator right = other->cl->iterator(other, 0, false); |
301 CxIterator right = other->cl->iterator(other, 0, false); |
302 for (size_t i = 0; i < list->base.size; i++) { |
302 for (size_t i = 0; i < list->collection.size; i++) { |
303 void *leftValue = cxIteratorCurrent(left); |
303 void *leftValue = cxIteratorCurrent(left); |
304 void *rightValue = cxIteratorCurrent(right); |
304 void *rightValue = cxIteratorCurrent(right); |
305 int d = list->base.cmpfunc(leftValue, rightValue); |
305 int d = list->collection.cmpfunc(leftValue, rightValue); |
306 if (d != 0) { |
306 if (d != 0) { |
307 return d; |
307 return d; |
308 } |
308 } |
309 cxIteratorNext(left); |
309 cxIteratorNext(left); |
310 cxIteratorNext(right); |
310 cxIteratorNext(right); |
311 } |
311 } |
312 return 0; |
312 return 0; |
313 } else { |
313 } else { |
314 return list->base.size < other->base.size ? -1 : 1; |
314 return list->collection.size < other->collection.size ? -1 : 1; |
315 } |
315 } |
316 } else { |
316 } else { |
317 // lists are compatible |
317 // lists are compatible |
318 return list->cl->compare(list, other); |
318 return list->cl->compare(list, other); |
319 } |
319 } |