src/linked_list.c

changeset 638
eafb45eefc51
parent 630
ac5e7f789048
child 639
309e8b08c60e
equal deleted inserted replaced
637:ceadf0792ded 638:eafb45eefc51
516 // increase the size and return 516 // increase the size and return
517 list->size++; 517 list->size++;
518 return 0; 518 return 0;
519 } 519 }
520 520
521 static size_t cx_ll_insert_array(
522 struct cx_list_s *list,
523 size_t index,
524 void const *array,
525 size_t n
526 ) {
527 // out-of bounds and corner case check
528 if (index > list->size || n == 0) return 0;
529
530 // find position efficiently
531 cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
532
533 // perform first insert
534 if (0 != cx_ll_insert_at(list, node, array)) {
535 return 1;
536 }
537
538 // is there more?
539 if (n == 1) return 1;
540
541 // we now know exactly where we are
542 node = node == NULL ? ((cx_linked_list *) list)->begin : node->next;
543
544 // we can add the remaining nodes and immedately advance to the inserted node
545 char const *source = array;
546 for (size_t i = 1; i < n; i++) {
547 source += list->itemsize;
548 if (0 != cx_ll_insert_at(list, node, source)) {
549 return i;
550 }
551 node = node->next;
552 }
553 return n;
554 }
555
521 static int cx_ll_insert( 556 static int cx_ll_insert(
522 struct cx_list_s *list, 557 struct cx_list_s *list,
523 size_t index, 558 size_t index,
524 void const *elem 559 void const *elem
525 ) { 560 ) {
526 // out-of bounds check 561 return cx_ll_insert_array(list, index, elem, 1) != 1;
527 if (index > list->size) return 1;
528
529 // find position efficiently
530 cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
531
532 // perform insert
533 return cx_ll_insert_at(list, node, elem);
534 } 562 }
535 563
536 static int cx_ll_add( 564 static int cx_ll_add(
537 struct cx_list_s *list, 565 struct cx_list_s *list,
538 void const *elem 566 void const *elem
543 static size_t cx_ll_add_array( 571 static size_t cx_ll_add_array(
544 struct cx_list_s *list, 572 struct cx_list_s *list,
545 void const *array, 573 void const *array,
546 size_t n 574 size_t n
547 ) { 575 ) {
548 // TODO: redirect to cx_ll_insert_array 576 return cx_ll_insert_array(list, list->size, array, n);
549 cx_for_n (i, n) {
550 if (cx_ll_add(list, ((char const *) array) + i * list->itemsize)) {
551 return i;
552 }
553 }
554 return n;
555 } 577 }
556 578
557 static int cx_pll_insert( 579 static int cx_pll_insert(
558 struct cx_list_s *list, 580 struct cx_list_s *list,
559 size_t index, 581 size_t index,
781 static cx_list_class cx_linked_list_class = { 803 static cx_list_class cx_linked_list_class = {
782 cx_ll_destructor, 804 cx_ll_destructor,
783 cx_ll_add, 805 cx_ll_add,
784 cx_ll_add_array, 806 cx_ll_add_array,
785 cx_ll_insert, 807 cx_ll_insert,
808 cx_ll_insert_array,
786 cx_ll_insert_iter, 809 cx_ll_insert_iter,
787 cx_ll_remove, 810 cx_ll_remove,
788 cx_ll_at, 811 cx_ll_at,
789 cx_ll_find, 812 cx_ll_find,
790 cx_ll_sort, 813 cx_ll_sort,
797 static cx_list_class cx_pointer_linked_list_class = { 820 static cx_list_class cx_pointer_linked_list_class = {
798 cx_ll_destructor, 821 cx_ll_destructor,
799 cx_pll_add, 822 cx_pll_add,
800 cx_ll_add_array, 823 cx_ll_add_array,
801 cx_pll_insert, 824 cx_pll_insert,
825 cx_ll_insert_array,
802 cx_pll_insert_iter, 826 cx_pll_insert_iter,
803 cx_ll_remove, 827 cx_ll_remove,
804 cx_pll_at, 828 cx_pll_at,
805 cx_ll_find, 829 cx_ll_find,
806 cx_ll_sort, 830 cx_ll_sort,

mercurial