Compare commits

..

2 Commits

2 changed files with 199 additions and 156 deletions

View File

@ -248,8 +248,6 @@ void linked_list_remove_elem(linked_list_t *linked_list, elem_t *elem)
void linked_list_remove(linked_list_t *linked_list, const size_t index)
{
if(!linked_list_is_in_bound(linked_list, index)) return;
elem_t *tmp = linked_list_get_elem(linked_list, index);
if(tmp) linked_list_remove_elem(linked_list, tmp);
}

View File

@ -5,7 +5,7 @@
/**
* @brief Element struct for linked lists.
* This struct is the base for storing data.
* This struct is the base for storing data in a linked list.
*
* @param data Raw pointer to any type of data
* @param prev Pointer to the prev element in the linked list
@ -25,48 +25,53 @@ typedef struct elem_t {
* You can pass NULL to the initialisation to use the default deleter (kfree(elem->data)).
* Your deleter_t function declaration must look like this :
*
* @example void name_of_your_deleter(void *data);
* void name_of_your_deleter(void *data);
*
* Then do what you need to destroy your data (don't forget to free the data itself...).
* Then do what you need to destroy your data (don't forget to free the data itself...) but not the elements.
* You should always define your function with "inline" if it's no too long.
*/
typedef void (*deleter_t)(void *data);
/**
* @brief A type for condition used for function like linked_list_remove_if
For function like linked_list_remove_if you need a condition.
It have two argument which are "elem_t *" and "va_list", that is because it passes the element on the actual index
and the args passed to the function.
Your condition_t function declaration must look like this :
bool name_of_your_condition(elem_t *elem, va_list);
Then return true if you want the element to be removed from the list or false if not.
You should always define your function with static, and inline if the condition is not too long. */
*
* For function like linked_list_remove_if you need a condition.
* It have two argument which are "elem_t *" and "va_list", that is because it passes the element on the actual index
* and the args passed to the function.
* Your condition_t function declaration must look like this :
*
* bool name_of_your_condition(elem_t *elem, va_list);
*
* Then return true if you want the element to be removed from the list or false if not.
* You should always define your function with "static", and "inline" if the condition is not too long.
*/
typedef bool (*condition_t)(elem_t *elem, va_list args);
/* action_t: A type for action used for function like linked_list_for_each
For function like linked_list_for_each you need an action to do.
It have two argument which are "elem_t *" and "va_list", that is because it passes the element on the actual index
and the args passed to the function.
Your condition_t function declaration must look like this :
void name_of_your_condition(elem_t *elem, va_list);
Then do whatever you want with the element data, just don't remove it lol.
You should alwaus define your function with static, and inline if the action is short. */
/**
* @brief A type for action used for function like linked_list_for_each
*
* For function like linked_list_for_each you need an action to do.
* It have two argument which are "elem_t *" and "va_list", that is because it passes the element on the actual index
* and the args passed to the function.
* Your condition_t function declaration must look like this :
*
* void name_of_your_condition(elem_t *elem, va_list);
*
* Then do whatever you want with the element data, just don't remove it.
* You should always define your function with "static", and "inline" if the action is short.
*/
typedef void (*action_t)(elem_t *elem, va_list args);
/* linked_list_t: Base of linked lists
This struct is the base for creating linked lists.
@data_size Size of the data stored in elements of the linked list
@first Pointer to the first element in the linked list
@last Pointer to the last element in the linked list
@size Size of the linked list
@deleter Deleter of the data when removing an element */
/**
* @brief Base of linked lists.
* This struct is the base for creating linked lists.
*
* @param data_size Size of the data stored in elements of the linked list (used while creating new elements)
* @param first Pointer to the first element in the linked list
* @param last Pointer to the last element in the linked list
* @param size Size of the linked list
* @param deleter Deleter of the data when removing an element
*/
typedef struct linked_list_t {
size_t data_size;
elem_t *first;
@ -75,166 +80,206 @@ typedef struct linked_list_t {
deleter_t elem_deleter;
} linked_list_t;
/* linked_list_init(): Init a linked_list_t
This function is necessary if you create a linked list.
It doesn't allocate the memory for you !
@linked_list Pointer to an linked_list_t
@data_size Data size for elements in the linked list */
/**
* @brief Init a linked list
* This function is necessary if you create a linked list.
*
* WARNING : It doesn't allocate the memory for you !
*
* @param linked_list Pointer to an linked list
* @param data_size Data size for elements in the linked list
* @param deleter The deleter used during destroyement of an elem
*/
void linked_list_init(linked_list_t *linked_list, const size_t data_size, deleter_t deleter);
/* elem_create(): Create an elem to fill with data to insert in a linked list.
This function is usefull when you want to initialise an elem with the proper data_size strored in the linked list.
WARNING : Don't change the "data" ptr after calling this function or it will lead to memory leaks !
Instead do something like this :
*(int *)elem->data = 42;
@linked_list Pointer to an linked_list_t
Return adress of initialised elem, NULL on error. */
/**
* @brief Create an elem to fill with data to insert in a linked list.
* This function is usefull when you want to initialise an elem with the proper data_size strored in the linked list.
*
* WARNING : Don't change the "data" ptr after calling this function or it will lead to memory leaks !
* Instead do something like this : *(int *)elem->data = 42;
*
* @param linked_list Pointer to an linked list
*
* @return Address of initialised elem, NULL on error.
*/
elem_t *elem_create(const linked_list_t *linked_list);
/* destroy_elem(): Destroy the given element and its data.
This function is usefull when you want to free an element.
The deleter is used for the data only.
@elem Pointer to an elem_t
Free the given elem. */
/**
* @brief Destroy the given element and its data.
* This function is usefull when you want to free an element.
* The deleter is used for the data only and you can pass NULL to use the default deleter.
*
* @param elem Pointer to an element
* @param elem_deleter Function to use to free the data
*/
void destroy_elem(elem_t *elem, const deleter_t elem_deleter);
/* linked_list_push_back_elem(): Insert an elem_t from the back in a linked_list_t.
@linked_list Pointer to an linked_list_t
@elem Pointer to an elem_t
Insert elem in the back of the linked list, do nothing on error. */
/**
* @brief Insert an element from the back in a linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param elem Pointer to an element
*/
void linked_list_push_back_elem(linked_list_t *linked_list, elem_t *elem);
/* linked_list_push_front_elem(): Insert an elem_t from the front in a linked_list_t.
@linked_list Pointer to an linked_list_t
@elem Pointer to an elem_t
Insert elem in the front of the linked list, do nothing on error. */
/**
* @brief Insert an element from the front in a linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param elem Pointer to an element
*/
void linked_list_push_front_elem(linked_list_t *linked_list, elem_t *elem);
/* linked_list_push_back_elem(): Insert an elem_t initialised and filled with data from the back in a linked_list_t.
@linked_list Pointer to an linked_list_t
@data Pointer to any data
Insert elem filled with data in the back of the linked list, do nothing on error. */
/**
* @brief Insert an element initialised and filled with data from the back in a linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param data Pointer to any data
*/
void linked_list_push_back(linked_list_t *linked_list, void *data);
/* linked_list_push_front_elem(): Insert an elem_t filled with data from the front in a linked_list_t.
@linked_list Pointer to an linked_list_t
@data Pointer to any data
Insert elem filled with data in the front of the linked list, do nothing on error. */
/**
* @brief Insert an element filled with data from the front in a linked list.
*
* @param linked_list Pointer to a linked list
* @param data Pointer to any data
*/
void linked_list_push_front(linked_list_t *linked_list, void *data);
/* linked_list_pop_back(): Delete the last elem in the given linked list
@linked_list Pointer to an linked_list_t
Delete last elem of the linked list, do nothing on error. */
/**
* @brief Delete the last element in the given linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
*/
void linked_list_pop_back(linked_list_t *linked_list);
/* linked_list_pop_front(): Delete the first elem in the given linked list
@linked_list Pointer to an linked_list_t
Delete first elem of the linked list, do nothing on error. */
/**
* @brief Delete the first element in the given linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
*/
void linked_list_pop_front(linked_list_t *linked_list);
/* linked_list_clear(): Clear the given linked list
@linked_list Pointer to an linked_list_t
Clear linked list. */
/**
* @brief Clear the given linked list, do nothing on error.
*
* @brief linked_list Pointer to a linked list
*/
void linked_list_clear(linked_list_t *linked_list);
/* linked_list_is_empty(): Check if the given linked list is empty
@linked_list Pointer to an linked_list_t
Return true if the given linked list is empty else false. */
/**
* @brief Check if the given linked list is empty.
*
* @param linked_list Pointer to a linked list
*
* @return True if the given linked list is empty else false.
*/
bool linked_list_is_empty(const linked_list_t *linked_list);
/* linked_list_is_in_bound(): Check if the given index is whithin the range of the linked list
@linked_list Pointer to an linked_list_t
Return true if the given linked list is empty else false. */
/**
* @brief Check if the given index is whithin the range of the linked list.
*
* @param linked_list Pointer to an linked_list_t
*
* @return True if index in within the range of the linked list else false.
*/
bool linked_list_is_in_bound(const linked_list_t *linked_list, const size_t index);
/* linked_list_get_elem(): Get element at the given index in the linked list
@linked_list Pointer to an linked_list_t
@index Index of the wanted element
Return the element, NULL on error. */
/**
* @brief Get element at the given index in the linked list.
*
* @param linked_list Pointer to a linked list
* @param index Index of the element
*
* @return Element, NULL on error.
*/
elem_t *linked_list_get_elem(const linked_list_t *linked_list, const size_t index);
/* linked_list_get(): Get data in the element at the given index in the linked list
@linked_list Pointer to an linked_list_t
@index Index of the wanted element
Return the data, NULL on error. */
/**
* @brief Get data in the element at the given index in the linked list.
*
* @param linked_list Pointer to an linked list
* @param index Index of the wanted element
*
* @return Data, NULL on error.
*/
void *linked_list_get(const linked_list_t *linked_list, const size_t index);
/* linked_list_insert_elem(): Insert element at the given index in the linked list
@linked_list Pointer to an linked_list_t
@elem Pointer to an element
@index Index of the wanted element
Insert the element, do nothing on error. */
/**
* @brief Insert element at the given index in the linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param elem Pointer to an element
* @param index Index to insert element
*/
void linked_list_insert_elem(linked_list_t *linked_list, elem_t *elem, const size_t index);
/* linked_list_insert(): Insert element with data at the given index in the linked list
@linked_list Pointer to an linked_list_t
@data Data to put in the new element
@index Index of the wanted element
Return the element, do nothing on error. */
/**
* @brief Insert element with data at the given index in the linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param data Data to put in the new element
* @param index Index to insert the element
*/
void linked_list_insert(linked_list_t *linked_list, void *data, const size_t index);
/* linked_list_remove_elem(): Remove the given elem in the linked list
@linked_list Pointer to an linked_list_t
@elem Element to remove
Remove the element, do nothing on error. */
/**
* @brief Remove the given elem in the linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param elem Element to remove
*/
void linked_list_remove_elem(linked_list_t *linked_list, elem_t *elem);
/* linked_list_remove(): Remove element at the given index in the linked list
@linked_list Pointer to an linked_list_t
@index Index of the element
Remove the element, do nothing on error. */
/**
* @brief Remove element at the given index in the linked list, do nothing on error.
*
* @param linked_list Pointer to a linked list
* @param index Index of the element
*/
void linked_list_remove(linked_list_t *linked_list, const size_t index);
/* linked_list_get_elem_if(): Return first element that the condition verify
@linked_list Pointer to an linked_list_t
@condition Condition to verify
@... Argument to pass to the condition
Return the element, NULL on error. */
/**
* @brief Return first element that the condition verify
*
* @param linked_list Pointer to a linked list
* @param condition Condition to verify
* @param ... Argument to pass to the condition
*
* @return Element, NULL if no element verify the condition or if an error ocurred.
*/
elem_t *linked_list_get_elem_if(const linked_list_t *linked_list, const condition_t condition, ...);
/* linked_list_get_if(): Return data in the first element that the condition verify
@linked_list Pointer to an linked_list_t
@condition Condition to verify
@... Argument to pass to the condition
Return the element data, NULL on error. */
/**
* @brief Return data in the first element that the condition verify
*
* @param linked_list Pointer to a linked list
* @param condition Condition to verify
* @param ... Argument to pass to the condition
*
* @return Element data, NULL if no element verify the condition or if an error ocurred.
*/
void *linked_list_get_if(const linked_list_t *linked_list, const condition_t condition, ...);
/* linked_list_remove_if(): Remove element(s) that the condition verify
@linked_list Pointer to an linked_list_t
@condition Condition to verify
@... Argument to pass to the condition
Remove the element(s), do nothing on error. */
/**
* @brief Remove element(s) that the condition verify, do nothing on error.
*
* @param linked_list Pointer to an linked list
* @param condition Condition to verify
* @param ... Argument to pass to the condition
*/
void linked_list_remove_if(linked_list_t *linked_list, const condition_t condition, ...);
/* linked_list_for_each(): Apply the condition to every elements in the list
Useful for changing a value in every single element data.
The condition can be anything that dont destroy the element.
@linked_list Pointer to an linked_list_t
@condition Condition to apply
@... Argument to pass to the condition */
/**
* @brief Apply an action to every elements in the list.
* Useful for changing a value in every single element data.
* The action can be anything that dont destroy the element.
*
* @param linked_list Pointer to an linked list
* @param action action to apply
* @param ... Argument to pass to the action
*/
void linked_list_for_each(const linked_list_t *linked_list, const action_t action, ...);
#endif // LINKED_LIST_H