src/list.c

changeset 854
fe0d69d72bcd
parent 853
d4baf4dd55c3
child 855
35bcb3216c0d
equal deleted inserted replaced
853:d4baf4dd55c3 854:fe0d69d72bcd
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_list_s *l = (struct cx_list_s *) list; 50 struct cx_collection_s *l = (struct cx_collection_s*) &list->base;
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_list_s *l = (struct cx_list_s *) list; 57 struct cx_collection_s *l = (struct cx_collection_s*) &list->base;
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);
146 list->climpl->reverse(list); 146 list->climpl->reverse(list);
147 } 147 }
148 148
149 static void *cx_pl_iter_current(void const *it) { 149 static void *cx_pl_iter_current(void const *it) {
150 struct cx_iterator_s const *iter = it; 150 struct cx_iterator_s const *iter = it;
151 void **ptr = iter->current_impl(it); 151 void **ptr = iter->base.current_impl(it);
152 return ptr == NULL ? NULL : *ptr; 152 return ptr == NULL ? NULL : *ptr;
153 } 153 }
154 154
155 static struct cx_iterator_s cx_pl_iterator( 155 static struct cx_iterator_s cx_pl_iterator(
156 struct cx_list_s const *list, 156 struct cx_list_s const *list,
157 size_t index, 157 size_t index,
158 bool backwards 158 bool backwards
159 ) { 159 ) {
160 struct cx_iterator_s iter = list->climpl->iterator(list, index, backwards); 160 struct cx_iterator_s iter = list->climpl->iterator(list, index, backwards);
161 iter.current_impl = iter.current; 161 iter.base.current_impl = iter.base.current;
162 iter.current = cx_pl_iter_current; 162 iter.base.current = cx_pl_iter_current;
163 return iter; 163 return iter;
164 } 164 }
165 165
166 static cx_list_class cx_pointer_list_class = { 166 static cx_list_class cx_pointer_list_class = {
167 cx_pl_destructor, 167 cx_pl_destructor,
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->store_pointer = false; 183 list->base.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->item_size = sizeof(void *); 191 list->base.item_size = sizeof(void *);
192 list->store_pointer = true; 192 list->base.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->size == 0) return 0; 224 if (other->base.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;
235 __attribute__((__unused__)) bool backwards 235 __attribute__((__unused__)) bool backwards
236 ) { 236 ) {
237 CxIterator iter = {0}; 237 CxIterator iter = {0};
238 iter.src_handle.c = list; 238 iter.src_handle.c = list;
239 iter.index = index; 239 iter.index = index;
240 iter.valid = cx_emptyl_iter_valid; 240 iter.base.valid = cx_emptyl_iter_valid;
241 return iter; 241 return iter;
242 } 242 }
243 243
244 static cx_list_class cx_empty_list_class = { 244 static cx_list_class cx_empty_list_class = {
245 cx_emptyl_noop, 245 cx_emptyl_noop,
256 cx_emptyl_noop, 256 cx_emptyl_noop,
257 cx_emptyl_iterator, 257 cx_emptyl_iterator,
258 }; 258 };
259 259
260 CxList cx_empty_list = { 260 CxList cx_empty_list = {
261 NULL, 261 {
262 NULL, 262 NULL,
263 0, 263 NULL,
264 0, 264 0,
265 NULL, 265 0,
266 NULL, 266 NULL,
267 NULL, 267 NULL,
268 false, 268 NULL,
269 false
270 },
269 &cx_empty_list_class, 271 &cx_empty_list_class,
270 NULL 272 NULL
271 }; 273 };
272 274
273 CxList *const cxEmptyList = &cx_empty_list; 275 CxList *const cxEmptyList = &cx_empty_list;
282 CxList const *list, 284 CxList const *list,
283 CxList const *other 285 CxList const *other
284 ) { 286 ) {
285 if ( 287 if (
286 // if one is storing pointers but the other is not 288 // if one is storing pointers but the other is not
287 (list->store_pointer ^ other->store_pointer) || 289 (list->base.store_pointer ^ other->base.store_pointer) ||
288 290
289 // if one class is wrapped but the other is not 291 // if one class is wrapped but the other is not
290 ((list->climpl == NULL) ^ (other->climpl == NULL)) || 292 ((list->climpl == NULL) ^ (other->climpl == NULL)) ||
291 293
292 // if the resolved compare functions are not the same 294 // if the resolved compare functions are not the same
293 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) != 295 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) !=
294 (other->climpl != NULL ? other->climpl->compare : other->cl->compare)) 296 (other->climpl != NULL ? other->climpl->compare : other->cl->compare))
295 ) { 297 ) {
296 // lists are definitely different - cannot use internal compare function 298 // lists are definitely different - cannot use internal compare function
297 if (list->size == other->size) { 299 if (list->base.size == other->base.size) {
298 CxIterator left = list->cl->iterator(list, 0, false); 300 CxIterator left = list->cl->iterator(list, 0, false);
299 CxIterator right = other->cl->iterator(other, 0, false); 301 CxIterator right = other->cl->iterator(other, 0, false);
300 for (size_t i = 0; i < list->size; i++) { 302 for (size_t i = 0; i < list->base.size; i++) {
301 void *leftValue = cxIteratorCurrent(left); 303 void *leftValue = cxIteratorCurrent(left);
302 void *rightValue = cxIteratorCurrent(right); 304 void *rightValue = cxIteratorCurrent(right);
303 int d = list->cmpfunc(leftValue, rightValue); 305 int d = list->base.cmpfunc(leftValue, rightValue);
304 if (d != 0) { 306 if (d != 0) {
305 return d; 307 return d;
306 } 308 }
307 cxIteratorNext(left); 309 cxIteratorNext(left);
308 cxIteratorNext(right); 310 cxIteratorNext(right);
309 } 311 }
310 return 0; 312 return 0;
311 } else { 313 } else {
312 return list->size < other->size ? -1 : 1; 314 return list->base.size < other->base.size ? -1 : 1;
313 } 315 }
314 } else { 316 } else {
315 // lists are compatible 317 // lists are compatible
316 return list->cl->compare(list, other); 318 return list->cl->compare(list, other);
317 } 319 }
320 CxIterator cxListMutIteratorAt( 322 CxIterator cxListMutIteratorAt(
321 CxList *list, 323 CxList *list,
322 size_t index 324 size_t index
323 ) { 325 ) {
324 CxIterator it = list->cl->iterator(list, index, false); 326 CxIterator it = list->cl->iterator(list, index, false);
325 it.mutating = true; 327 it.base.mutating = true;
326 return it; 328 return it;
327 } 329 }
328 330
329 CxIterator cxListMutBackwardsIteratorAt( 331 CxIterator cxListMutBackwardsIteratorAt(
330 CxList *list, 332 CxList *list,
331 size_t index 333 size_t index
332 ) { 334 ) {
333 CxIterator it = list->cl->iterator(list, index, true); 335 CxIterator it = list->cl->iterator(list, index, true);
334 it.mutating = true; 336 it.base.mutating = true;
335 return it; 337 return it;
336 } 338 }

mercurial