comparison lib/gl_array_list.c @ 12421:e8d2c6fc33ad

Use spaces for indentation, not tabs.
author Bruno Haible <bruno@clisp.org>
date Thu, 10 Dec 2009 20:28:30 +0100
parents 25f7280c9cf0
children a8c91b846640
comparison
equal deleted inserted replaced
12420:5850b9a81029 12421:e8d2c6fc33ad
51 #define INDEX_TO_NODE(index) (gl_list_node_t)(uintptr_t)(size_t)((index) + 1) 51 #define INDEX_TO_NODE(index) (gl_list_node_t)(uintptr_t)(size_t)((index) + 1)
52 #define NODE_TO_INDEX(node) ((uintptr_t)(node) - 1) 52 #define NODE_TO_INDEX(node) ((uintptr_t)(node) - 1)
53 53
54 static gl_list_t 54 static gl_list_t
55 gl_array_create_empty (gl_list_implementation_t implementation, 55 gl_array_create_empty (gl_list_implementation_t implementation,
56 gl_listelement_equals_fn equals_fn, 56 gl_listelement_equals_fn equals_fn,
57 gl_listelement_hashcode_fn hashcode_fn, 57 gl_listelement_hashcode_fn hashcode_fn,
58 gl_listelement_dispose_fn dispose_fn, 58 gl_listelement_dispose_fn dispose_fn,
59 bool allow_duplicates) 59 bool allow_duplicates)
60 { 60 {
61 struct gl_list_impl *list = XMALLOC (struct gl_list_impl); 61 struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
62 62
63 list->base.vtable = implementation; 63 list->base.vtable = implementation;
64 list->base.equals_fn = equals_fn; 64 list->base.equals_fn = equals_fn;
72 return list; 72 return list;
73 } 73 }
74 74
75 static gl_list_t 75 static gl_list_t
76 gl_array_create (gl_list_implementation_t implementation, 76 gl_array_create (gl_list_implementation_t implementation,
77 gl_listelement_equals_fn equals_fn, 77 gl_listelement_equals_fn equals_fn,
78 gl_listelement_hashcode_fn hashcode_fn, 78 gl_listelement_hashcode_fn hashcode_fn,
79 gl_listelement_dispose_fn dispose_fn, 79 gl_listelement_dispose_fn dispose_fn,
80 bool allow_duplicates, 80 bool allow_duplicates,
81 size_t count, const void **contents) 81 size_t count, const void **contents)
82 { 82 {
83 struct gl_list_impl *list = XMALLOC (struct gl_list_impl); 83 struct gl_list_impl *list = XMALLOC (struct gl_list_impl);
84 84
85 list->base.vtable = implementation; 85 list->base.vtable = implementation;
86 list->base.equals_fn = equals_fn; 86 list->base.equals_fn = equals_fn;
176 return INDEX_TO_NODE (position); 176 return INDEX_TO_NODE (position);
177 } 177 }
178 178
179 static size_t 179 static size_t
180 gl_array_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index, 180 gl_array_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index,
181 const void *elt) 181 const void *elt)
182 { 182 {
183 size_t count = list->count; 183 size_t count = list->count;
184 184
185 if (!(start_index <= end_index && end_index <= count)) 185 if (!(start_index <= end_index && end_index <= count))
186 /* Invalid arguments. */ 186 /* Invalid arguments. */
188 188
189 if (start_index < end_index) 189 if (start_index < end_index)
190 { 190 {
191 gl_listelement_equals_fn equals = list->base.equals_fn; 191 gl_listelement_equals_fn equals = list->base.equals_fn;
192 if (equals != NULL) 192 if (equals != NULL)
193 { 193 {
194 size_t i; 194 size_t i;
195 195
196 for (i = start_index;;) 196 for (i = start_index;;)
197 { 197 {
198 if (equals (elt, list->elements[i])) 198 if (equals (elt, list->elements[i]))
199 return i; 199 return i;
200 i++; 200 i++;
201 if (i == end_index) 201 if (i == end_index)
202 break; 202 break;
203 } 203 }
204 } 204 }
205 else 205 else
206 { 206 {
207 size_t i; 207 size_t i;
208 208
209 for (i = start_index;;) 209 for (i = start_index;;)
210 { 210 {
211 if (elt == list->elements[i]) 211 if (elt == list->elements[i])
212 return i; 212 return i;
213 i++; 213 i++;
214 if (i == end_index) 214 if (i == end_index)
215 break; 215 break;
216 } 216 }
217 } 217 }
218 } 218 }
219 return (size_t)(-1); 219 return (size_t)(-1);
220 } 220 }
221 221
222 static gl_list_node_t 222 static gl_list_node_t
223 gl_array_search_from_to (gl_list_t list, size_t start_index, size_t end_index, 223 gl_array_search_from_to (gl_list_t list, size_t start_index, size_t end_index,
224 const void *elt) 224 const void *elt)
225 { 225 {
226 size_t index = gl_array_indexof_from_to (list, start_index, end_index, elt); 226 size_t index = gl_array_indexof_from_to (list, start_index, end_index, elt);
227 return INDEX_TO_NODE (index); 227 return INDEX_TO_NODE (index);
228 } 228 }
229 229
399 gl_array_list_free (gl_list_t list) 399 gl_array_list_free (gl_list_t list)
400 { 400 {
401 if (list->elements != NULL) 401 if (list->elements != NULL)
402 { 402 {
403 if (list->base.dispose_fn != NULL) 403 if (list->base.dispose_fn != NULL)
404 { 404 {
405 size_t count = list->count; 405 size_t count = list->count;
406 406
407 if (count > 0) 407 if (count > 0)
408 { 408 {
409 gl_listelement_dispose_fn dispose = list->base.dispose_fn; 409 gl_listelement_dispose_fn dispose = list->base.dispose_fn;
410 const void **elements = list->elements; 410 const void **elements = list->elements;
411 411
412 do 412 do
413 dispose (*elements++); 413 dispose (*elements++);
414 while (--count > 0); 414 while (--count > 0);
415 } 415 }
416 } 416 }
417 free (list->elements); 417 free (list->elements);
418 } 418 }
419 free (list); 419 free (list);
420 } 420 }
421 421
460 return result; 460 return result;
461 } 461 }
462 462
463 static bool 463 static bool
464 gl_array_iterator_next (gl_list_iterator_t *iterator, 464 gl_array_iterator_next (gl_list_iterator_t *iterator,
465 const void **eltp, gl_list_node_t *nodep) 465 const void **eltp, gl_list_node_t *nodep)
466 { 466 {
467 gl_list_t list = iterator->list; 467 gl_list_t list = iterator->list;
468 if (iterator->count != list->count) 468 if (iterator->count != list->count)
469 { 469 {
470 if (iterator->count != list->count + 1) 470 if (iterator->count != list->count + 1)
471 /* Concurrent modifications were done on the list. */ 471 /* Concurrent modifications were done on the list. */
472 abort (); 472 abort ();
473 /* The last returned element was removed. */ 473 /* The last returned element was removed. */
474 iterator->count--; 474 iterator->count--;
475 iterator->p = (const void **) iterator->p - 1; 475 iterator->p = (const void **) iterator->p - 1;
476 iterator->q = (const void **) iterator->q - 1; 476 iterator->q = (const void **) iterator->q - 1;
477 } 477 }
478 if (iterator->p < iterator->q) 478 if (iterator->p < iterator->q)
479 { 479 {
480 const void **p = (const void **) iterator->p; 480 const void **p = (const void **) iterator->p;
481 *eltp = *p; 481 *eltp = *p;
482 if (nodep != NULL) 482 if (nodep != NULL)
483 *nodep = INDEX_TO_NODE (p - list->elements); 483 *nodep = INDEX_TO_NODE (p - list->elements);
484 iterator->p = p + 1; 484 iterator->p = p + 1;
485 return true; 485 return true;
486 } 486 }
487 else 487 else
488 return false; 488 return false;
495 495
496 /* ---------------------- Sorted gl_list_t Data Type ---------------------- */ 496 /* ---------------------- Sorted gl_list_t Data Type ---------------------- */
497 497
498 static size_t 498 static size_t
499 gl_array_sortedlist_indexof_from_to (gl_list_t list, 499 gl_array_sortedlist_indexof_from_to (gl_list_t list,
500 gl_listelement_compar_fn compar, 500 gl_listelement_compar_fn compar,
501 size_t low, size_t high, 501 size_t low, size_t high,
502 const void *elt) 502 const void *elt)
503 { 503 {
504 if (!(low <= high && high <= list->count)) 504 if (!(low <= high && high <= list->count))
505 /* Invalid arguments. */ 505 /* Invalid arguments. */
506 abort (); 506 abort ();
507 if (low < high) 507 if (low < high)
508 { 508 {
509 /* At each loop iteration, low < high; for indices < low the values 509 /* At each loop iteration, low < high; for indices < low the values
510 are smaller than ELT; for indices >= high the values are greater 510 are smaller than ELT; for indices >= high the values are greater
511 than ELT. So, if the element occurs in the list, it is at 511 than ELT. So, if the element occurs in the list, it is at
512 low <= position < high. */ 512 low <= position < high. */
513 do 513 do
514 { 514 {
515 size_t mid = low + (high - low) / 2; /* low <= mid < high */ 515 size_t mid = low + (high - low) / 2; /* low <= mid < high */
516 int cmp = compar (list->elements[mid], elt); 516 int cmp = compar (list->elements[mid], elt);
517 517
518 if (cmp < 0) 518 if (cmp < 0)
519 low = mid + 1; 519 low = mid + 1;
520 else if (cmp > 0) 520 else if (cmp > 0)
521 high = mid; 521 high = mid;
522 else /* cmp == 0 */ 522 else /* cmp == 0 */
523 { 523 {
524 /* We have an element equal to ELT at index MID. But we need 524 /* We have an element equal to ELT at index MID. But we need
525 the minimal such index. */ 525 the minimal such index. */
526 high = mid; 526 high = mid;
527 /* At each loop iteration, low <= high and 527 /* At each loop iteration, low <= high and
528 compar (list->elements[high], elt) == 0, 528 compar (list->elements[high], elt) == 0,
529 and we know that the first occurrence of the element is at 529 and we know that the first occurrence of the element is at
530 low <= position <= high. */ 530 low <= position <= high. */
531 while (low < high) 531 while (low < high)
532 { 532 {
533 size_t mid2 = low + (high - low) / 2; /* low <= mid2 < high */ 533 size_t mid2 = low + (high - low) / 2; /* low <= mid2 < high */
534 int cmp2 = compar (list->elements[mid2], elt); 534 int cmp2 = compar (list->elements[mid2], elt);
535 535
536 if (cmp2 < 0) 536 if (cmp2 < 0)
537 low = mid2 + 1; 537 low = mid2 + 1;
538 else if (cmp2 > 0) 538 else if (cmp2 > 0)
539 /* The list was not sorted. */ 539 /* The list was not sorted. */
540 abort (); 540 abort ();
541 else /* cmp2 == 0 */ 541 else /* cmp2 == 0 */
542 { 542 {
543 if (mid2 == low) 543 if (mid2 == low)
544 break; 544 break;
545 high = mid2 - 1; 545 high = mid2 - 1;
546 } 546 }
547 } 547 }
548 return low; 548 return low;
549 } 549 }
550 } 550 }
551 while (low < high); 551 while (low < high);
552 /* Here low == high. */ 552 /* Here low == high. */
553 } 553 }
554 return (size_t)(-1); 554 return (size_t)(-1);
555 } 555 }
556 556
557 static size_t 557 static size_t
558 gl_array_sortedlist_indexof (gl_list_t list, gl_listelement_compar_fn compar, 558 gl_array_sortedlist_indexof (gl_list_t list, gl_listelement_compar_fn compar,
559 const void *elt) 559 const void *elt)
560 { 560 {
561 return gl_array_sortedlist_indexof_from_to (list, compar, 0, list->count, 561 return gl_array_sortedlist_indexof_from_to (list, compar, 0, list->count,
562 elt); 562 elt);
563 } 563 }
564 564
565 static gl_list_node_t 565 static gl_list_node_t
566 gl_array_sortedlist_search_from_to (gl_list_t list, 566 gl_array_sortedlist_search_from_to (gl_list_t list,
567 gl_listelement_compar_fn compar, 567 gl_listelement_compar_fn compar,
568 size_t low, size_t high, 568 size_t low, size_t high,
569 const void *elt) 569 const void *elt)
570 { 570 {
571 size_t index = 571 size_t index =
572 gl_array_sortedlist_indexof_from_to (list, compar, low, high, elt); 572 gl_array_sortedlist_indexof_from_to (list, compar, low, high, elt);
573 return INDEX_TO_NODE (index); 573 return INDEX_TO_NODE (index);
574 } 574 }
575 575
576 static gl_list_node_t 576 static gl_list_node_t
577 gl_array_sortedlist_search (gl_list_t list, gl_listelement_compar_fn compar, 577 gl_array_sortedlist_search (gl_list_t list, gl_listelement_compar_fn compar,
578 const void *elt) 578 const void *elt)
579 { 579 {
580 size_t index = 580 size_t index =
581 gl_array_sortedlist_indexof_from_to (list, compar, 0, list->count, elt); 581 gl_array_sortedlist_indexof_from_to (list, compar, 0, list->count, elt);
582 return INDEX_TO_NODE (index); 582 return INDEX_TO_NODE (index);
583 } 583 }
584 584
585 static gl_list_node_t 585 static gl_list_node_t
586 gl_array_sortedlist_add (gl_list_t list, gl_listelement_compar_fn compar, 586 gl_array_sortedlist_add (gl_list_t list, gl_listelement_compar_fn compar,
587 const void *elt) 587 const void *elt)
588 { 588 {
589 size_t count = list->count; 589 size_t count = list->count;
590 size_t low = 0; 590 size_t low = 0;
591 size_t high = count; 591 size_t high = count;
592 592
596 { 596 {
597 size_t mid = low + (high - low) / 2; /* low <= mid < high */ 597 size_t mid = low + (high - low) / 2; /* low <= mid < high */
598 int cmp = compar (list->elements[mid], elt); 598 int cmp = compar (list->elements[mid], elt);
599 599
600 if (cmp < 0) 600 if (cmp < 0)
601 low = mid + 1; 601 low = mid + 1;
602 else if (cmp > 0) 602 else if (cmp > 0)
603 high = mid; 603 high = mid;
604 else /* cmp == 0 */ 604 else /* cmp == 0 */
605 { 605 {
606 low = mid; 606 low = mid;
607 break; 607 break;
608 } 608 }
609 } 609 }
610 return gl_array_add_at (list, low, elt); 610 return gl_array_add_at (list, low, elt);
611 } 611 }
612 612
613 static bool 613 static bool
614 gl_array_sortedlist_remove (gl_list_t list, gl_listelement_compar_fn compar, 614 gl_array_sortedlist_remove (gl_list_t list, gl_listelement_compar_fn compar,
615 const void *elt) 615 const void *elt)
616 { 616 {
617 size_t index = gl_array_sortedlist_indexof (list, compar, elt); 617 size_t index = gl_array_sortedlist_indexof (list, compar, elt);
618 if (index == (size_t)(-1)) 618 if (index == (size_t)(-1))
619 return false; 619 return false;
620 else 620 else