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, |