Implementing ex32 List copy, split, and join
This commit is contained in:
parent
015288d5b6
commit
c4b92572bf
@ -129,7 +129,7 @@ void *List_remove(List *list, ListNode *node)
|
||||
list->first->prev = NULL;
|
||||
} else if(node == list->last) {
|
||||
list->last = node->prev;
|
||||
check(list->last != NULL, "INvalid list, somehow got a next that is NULL.");
|
||||
check(list->last != NULL, "Invalid list, somehow got a next that is NULL.");
|
||||
list->last->next = NULL;
|
||||
} else {
|
||||
ListNode *after = node->next;
|
||||
@ -145,3 +145,68 @@ void *List_remove(List *list, ListNode *node)
|
||||
error:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
List *List_copy(List *list)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
List *out = List_create();
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
List_push(out, cur->value);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
int List_split(List *list, void *split, List *a, List *b)
|
||||
{
|
||||
List_validate(list);
|
||||
|
||||
check(list->first && list->last, "List is empty.");
|
||||
check(split, "split can't be NULL");
|
||||
|
||||
if(split == list->last->value || (split == list->first->value && split == list->last->value)) {
|
||||
(*a) = *List_copy(list);
|
||||
return 0;
|
||||
} else if(split == list->first->value) {
|
||||
(*b) = *List_copy(list);
|
||||
List_push(a, List_shift(b));
|
||||
return 0;
|
||||
} else {
|
||||
int past_split = 0;
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(past_split) {
|
||||
List_push(b, cur->value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cur->value == split) {
|
||||
past_split = 1;
|
||||
}
|
||||
|
||||
List_push(a, cur->value);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void List_join(List *list, List *b)
|
||||
{
|
||||
List_validate(list);
|
||||
List_validate(b);
|
||||
|
||||
List *tail = List_copy(b);
|
||||
|
||||
list->last->next = tail->first;
|
||||
list->count += tail->count;
|
||||
free(tail);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ void *List_shift(List *list);
|
||||
|
||||
void *List_remove(List *list, ListNode *node);
|
||||
|
||||
List *List_copy(List *list);
|
||||
int List_split(List *list, void *split, List *a, List *b);
|
||||
void List_join(List *list, List *b);
|
||||
|
||||
#define List_validate(A) (assert(A != NULL && List_count(A) > -1 &&\
|
||||
(List_count(A) > 0 && List_first(A) != NULL) && "invalid *List"))
|
||||
|
||||
|
@ -6,6 +6,7 @@ static List *list = NULL;
|
||||
char *test1 = "test1 data";
|
||||
char *test2 = "test2 data";
|
||||
char *test3 = "test3 data";
|
||||
char *test4 = "test4 data";
|
||||
|
||||
|
||||
char *test_create()
|
||||
@ -95,6 +96,95 @@ char *test_shift()
|
||||
}
|
||||
|
||||
|
||||
char *test_copy()
|
||||
{
|
||||
list = List_create();
|
||||
|
||||
mu_assert(List_count(list) == 0, "Wrong count before copy.");
|
||||
List_push(list, test1);
|
||||
List_push(list, test2);
|
||||
List_push(list, test3);
|
||||
List_push(list, test4);
|
||||
|
||||
mu_assert(List_count(list) == 4, "Wrong count after push.");
|
||||
|
||||
List *copy = List_copy(list);
|
||||
mu_assert(copy != list, "Copy and list have same address.");
|
||||
mu_assert(List_count(copy) == 4, "Copy has wrong count.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_split()
|
||||
{
|
||||
mu_assert(List_count(list) == 4, "Wrong count before split.");
|
||||
|
||||
List *a = List_create();
|
||||
List *b = List_create();
|
||||
List *tmp = List_copy(list);
|
||||
|
||||
int rc = -1;
|
||||
rc = List_split(tmp, test2, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 2, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 2, "List 'b' has wrong count.");
|
||||
|
||||
List_destroy(a);
|
||||
List_destroy(b);
|
||||
|
||||
a = List_create();
|
||||
b = List_create();
|
||||
tmp = List_copy(list);
|
||||
|
||||
rc = List_split(tmp, test1, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 1, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 3, "List 'b' has wrong count.");
|
||||
|
||||
List_destroy(a);
|
||||
List_destroy(b);
|
||||
|
||||
a = List_create();
|
||||
b = List_create();
|
||||
tmp = List_copy(list);
|
||||
|
||||
rc = List_split(tmp, test3, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 3, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 1, "List 'b' has wrong count.");
|
||||
|
||||
List_destroy(a);
|
||||
List_destroy(b);
|
||||
|
||||
a = List_create();
|
||||
b = List_create();
|
||||
tmp = List_copy(list);
|
||||
|
||||
rc = List_split(tmp, test4, a, b);
|
||||
mu_assert(rc == 0, "Failed to split.");
|
||||
mu_assert(List_count(a) == 4, "List 'a' has wrong count.");
|
||||
mu_assert(List_count(b) == 0, "List 'b' has wrong count.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_join()
|
||||
{
|
||||
mu_assert(List_count(list) == 4, "Wrong count before join.");
|
||||
|
||||
List *b = List_create();
|
||||
List_push(b, test4);
|
||||
mu_assert(List_count(b) == 1, "List 'b' has wrong count.");
|
||||
|
||||
List_join(list, b);
|
||||
mu_assert(List_count(list) == 5, "Wrong count after join.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *all_tests() {
|
||||
mu_suite_start();
|
||||
@ -105,6 +195,9 @@ char *all_tests() {
|
||||
mu_run_test(test_remove);
|
||||
mu_run_test(test_shift);
|
||||
mu_run_test(test_destroy);
|
||||
mu_run_test(test_copy);
|
||||
mu_run_test(test_split);
|
||||
mu_run_test(test_join);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user