X_EXTERN x_list * X_PFX (list_copy) (x_list *lst) { x_list *copy = NULL; for (; lst != NULL; lst = lst->next) { copy = X_PFX (list_prepend) (copy, lst->data); } return X_PFX (list_reverse) (copy); }
X_EXTERN x_list * X_PFX (list_map) (x_list *lst, void *(*fun) (void *item, void *data), void *data) { x_list *ret = NULL, *node; for (node = lst; node != NULL; node = node->next) { X_PFX (list_prepend) (ret, fun (node->data, data)); } return X_PFX (list_reverse) (ret); }
X_EXTERN x_list * X_PFX (list_filter) (x_list *lst, int (*pred) (void *item, void *data), void *data) { x_list *ret = NULL, *node; for (node = lst; node != NULL; node = node->next) { if ((*pred) (node->data, data)) ret = X_PFX (list_prepend) (ret, node->data); } return X_PFX (list_reverse) (ret); }
X_EXTERN x_list * X_PFX (list_append) (x_list *lst, void *data) { x_list *head = lst; if (lst == NULL) return X_PFX (list_prepend) (NULL, data); while (lst->next != NULL) lst = lst->next; lst->next = X_PFX (list_prepend) (NULL, data); return head; }
X_EXTERN x_list * X_PFX (list_sort) (x_list *lst, int (*less) (const void *, const void *)) { int length; length = X_PFX (list_length) (lst); return list_sort_1 (lst, length, less); }
X_EXTERN void X_PFX (hook_free) (x_list *lst) { x_list *node; for (node = lst; node != NULL; node = node->next) { CELL_FREE (node->data); } X_PFX (list_free) (lst); }
X_EXTERN x_list * X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data) { x_list *node, *cell; x_list *to_delete = NULL; for (node = lst; node != NULL; node = node->next) { cell = node->data; if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data) to_delete = X_PFX (list_prepend) (to_delete, cell); } for (node = to_delete; node != NULL; node = node->next) { cell = node->data; lst = X_PFX (list_remove) (lst, cell); CELL_FREE (cell); } X_PFX (list_free) (to_delete); }
X_EXTERN x_list * X_PFX (list_pop) (x_list *lst, void **data_ret) { void *data = NULL; if (lst != NULL) { x_list *tem = lst; data = lst->data; lst = lst->next; X_PFX (list_free_1) (tem); } if (data_ret != NULL) *data_ret = data; return lst; }
X_EXTERN x_list * X_PFX (list_remove) (x_list *lst, void *data) { x_list **ptr, *node; for (ptr = &lst; *ptr != NULL;) { node = *ptr; if (node->data == data) { *ptr = node->next; X_PFX (list_free_1) (node); } else ptr = &((*ptr)->next); } return lst; }
X_EXTERN void X_PFX (hook_run) (x_list *lst, void *arg) { x_list *node, *cell; x_hook_function **fun; void **data; int length, i; length = X_PFX (list_length) (lst); fun = alloca (sizeof (x_hook_function *) * length); data = alloca (sizeof (void *) * length); for (i = 0, node = lst; node != NULL; node = node->next, i++) { cell = node->data; fun[i] = CELL_FUN (cell); data[i] = CELL_DATA (cell); } for (i = 0; i < length; i++) { (*fun[i]) (arg, data[i]); } }
X_EXTERN x_list * X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data) { return X_PFX (list_prepend) (lst, CELL_NEW (fun, data)); }