/* SPDX-License-Identifier: Zlib */ #ifndef GIRARA_DATASTRUCTURES_H #define GIRARA_DATASTRUCTURES_H #include #include #include #include "macros.h" #include "types.h" /** * Create a new list. * * @return The girara list object or NULL if an error occurred */ girara_list_t* girara_list_new(void) GIRARA_VISIBLE; /** * Create a new list. * * @param gfree Pointer to the free function * @return The girara list object or NULL if an error occurred. */ girara_list_t* girara_list_new2(girara_free_function_t gfree) GIRARA_VISIBLE; /** * Create a new (sorted) list. * * @param cmp Pointer to the compare function. * @return The girara list object or NULL if an error occurred. */ girara_list_t* girara_sorted_list_new(girara_compare_function_t cmp) GIRARA_VISIBLE; /** * Create a new (sorted) list. * * @param cmp Pointer to the compare function. * @param gfree Pointer to the free function * @return The girara list object or NULL if an error occurred. */ girara_list_t* girara_sorted_list_new2(girara_compare_function_t cmp, girara_free_function_t gfree) GIRARA_VISIBLE; /** * Set the function which should be called if the stored data should be freed. * * @param list The girara list object * @param gfree Pointer to the free function */ void girara_list_set_free_function(girara_list_t* list, girara_free_function_t gfree) GIRARA_VISIBLE; /** * Remove all elements from a list. * * @param list The girara list object */ void girara_list_clear(girara_list_t* list) GIRARA_VISIBLE; /** * Destroy list. * * @param list The girara list object */ void girara_list_free(girara_list_t* list) GIRARA_VISIBLE; /** * Append an element to the list. * * @param list The girara list object * @param data The element */ void girara_list_append(girara_list_t* list, void* data) GIRARA_VISIBLE; /** * Prepend an element to the list. * * @param list The girara list object * @param data The element */ void girara_list_prepend(girara_list_t* list, void* data) GIRARA_VISIBLE; /** * Remove an element of the list * * @param list The girara list object * @param data The element */ void girara_list_remove(girara_list_t* list, void* data) GIRARA_VISIBLE; /** * Returns nth entry * * @param list The girara list object * @param n Index of the entry * @return The nth element or NULL if an error occurred */ void* girara_list_nth(girara_list_t* list, size_t n) GIRARA_VISIBLE; /** * Checks if the list contains the given element * * @param list The girara list object * @param data The element * @return true if the list contains the element */ bool girara_list_contains(girara_list_t* list, void* data) GIRARA_VISIBLE; /** * Get size of the list. * * @param list The girara list object * @return The size of the list */ size_t girara_list_size(girara_list_t* list) GIRARA_VISIBLE; /** * Returns the position of the element in the list * * @param list The girara list object * @param data The element * @return The position or -1 if the data is not found */ ssize_t girara_list_position(girara_list_t* list, void* data) GIRARA_VISIBLE; /** * Sort a list * * @param list The list to sort * @param compare compare function */ void girara_list_sort(girara_list_t* list, girara_compare_function_t compare) GIRARA_VISIBLE; /** * Find an element * * @param list The list * @param compare compare function * @param data data passed as the second argument to the compare function * @return the element if found or NULL */ void* girara_list_find(girara_list_t* list, girara_compare_function_t compare, const void* data) GIRARA_VISIBLE; /** * Create an iterator pointing at the start of list. * * @param list The girara list object * @return The list iterator or NULL if an error occurred */ girara_list_iterator_t* girara_list_iterator(girara_list_t* list) GIRARA_VISIBLE; /** * Create an iterator pointing to the same element as iter. * * @param iter The girara list iterator to be copied * @return The list iterator or NULL if an error occurred */ girara_list_iterator_t* girara_list_iterator_copy(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Move iterator to next element. * * @param iter The list iterator * @return The moved iterator or NULL if an error occurred */ girara_list_iterator_t* girara_list_iterator_next(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Check if iterator has next element. * * @param iter The list iterator * @return true if iterator has a next element, false otherwise */ bool girara_list_iterator_has_next(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Move iterator to previous element. * * @param iter The list iterator * @return The moved iterator or NULL if an error occurred */ girara_list_iterator_t* girara_list_iterator_previous(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Check if iterator has previous element. * * @param iter The list iterator * @return true if iterator has a previous element, false otherwise */ bool girara_list_iterator_has_previous(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Remove element pointed by the iterator, and updates the iterator * to the next element * * @param iter The list iterator */ void girara_list_iterator_remove(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Check if iterator is valid * * @param iter The list iterator * @return true if iterator is valid, false otherwise */ bool girara_list_iterator_is_valid(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Get data from the element pointed to by the iterator. * * @param iter The list iterator * @return The data of the current element */ void* girara_list_iterator_data(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Set data from the element pointed to by the iterator. * * @param iter The list iterator * @param data Sets the list iterator to a specific element */ void girara_list_iterator_set(girara_list_iterator_t* iter, void *data) GIRARA_VISIBLE; /** * Destroy the iterator. * * @param iter The list iterator */ void girara_list_iterator_free(girara_list_iterator_t* iter) GIRARA_VISIBLE; /** * Call function for each element in the list. * * @param list The list * @param callback The function to call. * @param data Passed to the callback as second argument. */ void girara_list_foreach(girara_list_t* list, girara_list_callback_t callback, void* data) GIRARA_VISIBLE; #define GIRARA_LIST_FOREACH(list, type, iter, data) \ do { \ girara_list_iterator_t* iter = girara_list_iterator(list); \ while (girara_list_iterator_is_valid(iter)) { \ type data = (type)girara_list_iterator_data(iter); #define GIRARA_LIST_FOREACH_END(list, type, iter, data) \ girara_list_iterator_next(iter); \ } \ girara_list_iterator_free(iter); \ } while(0) #define GIRARA_LIST_FOREACH_BODY_WITH_ITER(list, type, iter, data, ...) \ GIRARA_LIST_FOREACH(list, type, iter, data) \ __VA_ARGS__ \ GIRARA_LIST_FOREACH_END(list, type, iter, data) #define GIRARA_LIST_FOREACH_BODY(list, type, data, ...) \ GIRARA_LIST_FOREACH(list, type, girara_list_foreach_iterator, data) \ __VA_ARGS__ \ GIRARA_LIST_FOREACH_END(list, type, girara_list_foreach_iterator, data) /** * Merge a list into another one. Both lists need to have the same free * function. If other has a source free function set it will be set to NULL as * the elements then belong to list. * @param list the target list * @param other the source list * @returns list with the elements from other. */ girara_list_t* girara_list_merge(girara_list_t* list, girara_list_t* other) GIRARA_VISIBLE; /** * Create a new node. * * @param data Data of the new node * @return A girara node object or NULL if an error occurred */ girara_tree_node_t* girara_node_new(void* data) GIRARA_VISIBLE; /** * Set the function which should be called if the stored data should be freed. * * @param node The girara node object * @param gfree Pointer to the free function */ void girara_node_set_free_function(girara_tree_node_t* node, girara_free_function_t gfree) GIRARA_VISIBLE; /** * Free a node. This will remove the node from its' parent and will destroy all * its' children. * * @param node The girara node object */ void girara_node_free(girara_tree_node_t* node) GIRARA_VISIBLE; /** * Append a node to another node. * * @param parent The parent node * @param child The child node */ void girara_node_append(girara_tree_node_t* parent, girara_tree_node_t* child) GIRARA_VISIBLE; /** * Append data as new node to another node. * * @param parent The parent node * @param data The data of the node * @return The node object or NULL if an error occurred */ girara_tree_node_t* girara_node_append_data(girara_tree_node_t* parent, void* data) GIRARA_VISIBLE; /** * Get parent node. * * @param node The girara node object * @return The parent node or NULL if an error occurred or no parent exists */ girara_tree_node_t* girara_node_get_parent(girara_tree_node_t* node) GIRARA_VISIBLE; /** * Get root node. * * @param node The girara node object * @return The root node or NULL if an error occurred */ girara_tree_node_t* girara_node_get_root(girara_tree_node_t* node) GIRARA_VISIBLE; /** * Get list of children. * * @param node The girara node object * @return List object containing all child nodes or NULL if an error occurred */ girara_list_t* girara_node_get_children(girara_tree_node_t* node) GIRARA_VISIBLE; /** * Get number of children. * * @param node The girara node object * @return The number of child nodes */ size_t girara_node_get_num_children(girara_tree_node_t* node) GIRARA_VISIBLE; /** * Get data. * * @param node The girara node object * @return The data of the node */ void* girara_node_get_data(girara_tree_node_t* node) GIRARA_VISIBLE; /** * Set data. * * @param node The girara node object * @param data The new data of the object */ void girara_node_set_data(girara_tree_node_t* node, void* data) GIRARA_VISIBLE; #endif