#include "list_ops.h" #include // constructs a new list list_t *new_list(size_t length, list_element_t elements[]) { list_t *newList = malloc(sizeof(list_t) + length * sizeof(list_element_t)); if (newList != NULL) { newList->length = length; if (length > 0 && elements != NULL) { memcpy(newList->elements, elements, length * sizeof(list_element_t)); } } return newList; } // append entries to a list and return the new list list_t *append_list(list_t *list1, list_t *list2) { if (list1 == NULL && list2 == NULL) { return NULL; // Both lists are empty } else if (list1 == NULL) { return list2; // Only list1 is empty, return list2 } else if (list2 == NULL) { return list1; // Only list2 is empty, return list1 } size_t new_length = list1->length + list2->length; list_t *new_list = malloc(sizeof(list_t) + new_length * sizeof(list_element_t)); if (new_list == NULL) { return NULL; // Memory allocation failed } memcpy(new_list->elements, list1->elements, list1->length * sizeof(list_element_t)); memcpy(new_list->elements + list1->length, list2->elements, list2->length * sizeof(list_element_t)); new_list->length = new_length; return new_list; } // filter list returning only values that satisfy the filter function list_t *filter_list(list_t *list, bool (*filter)(list_element_t)) { if (list == NULL) return NULL; size_t filteredLength = 0; for (size_t i = 0; i < list->length; ++i) { if (filter(list->elements[i])) { ++filteredLength; } } list_t *filtered = malloc(sizeof(list_t) + filteredLength * sizeof(list_element_t)); if (filtered != NULL) { filtered->length = filteredLength; size_t j = 0; for (size_t i = 0; i < list->length; ++i) { if (filter(list->elements[i])) { filtered->elements[j++] = list->elements[i]; } } } return filtered; } // returns the length of the list size_t length_list(list_t *list) { return (list != NULL) ? list->length : 0; } // return a list of elements whose values equal the list value transformed by // the mapping function list_t *map_list(list_t *list, list_element_t (*map)(list_element_t)) { if (list == NULL) return NULL; list_t *mappedList = new_list(list->length, list->elements); if (mappedList != NULL) { for (size_t i = 0; i < list->length; ++i) { mappedList->elements[i] = map(list->elements[i]); } } return mappedList; } // folds (reduces) the given list from the left with a function list_element_t foldl_list(list_t *list, list_element_t initial, list_element_t (*foldl)(list_element_t, list_element_t)) { list_element_t accumulator = initial; if (list != NULL) { for (size_t i = 0; i < list->length; ++i) { accumulator = foldl(list->elements[i], accumulator); } } return accumulator; } // folds (reduces) the given list from the right with a function list_element_t foldr_list(list_t *list, list_element_t initial, list_element_t (*foldr)(list_element_t, list_element_t)) { list_element_t accumulator = initial; if (list != NULL) { for (size_t i = list->length; i > 0; --i) { accumulator = foldr(list->elements[i - 1], accumulator); } } return accumulator; } // reverse the elements of the list list_t *reverse_list(list_t *list) { if (list == NULL) return NULL; list_t *reversedList = new_list(list->length, list->elements); if (reversedList != NULL) { for (size_t i = 0; i < list->length / 2; ++i) { list_element_t temp = reversedList->elements[i]; reversedList->elements[i] = reversedList->elements[list->length - i - 1]; reversedList->elements[list->length - i - 1] = temp; } } return reversedList; } // destroy the entire list // list will be a dangling pointer after calling this method on it void delete_list(list_t *list) { free(list); }