Compare commits

..

No commits in common. "9a36a64c7cbaf7deb7d6fb38f586c7ad5b959c46" and "f88901058f180d17ef93e465f2fdd2f5ddbdd8c5" have entirely different histories.

2 changed files with 156 additions and 199 deletions

View File

@ -248,6 +248,8 @@ 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) 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); elem_t *tmp = linked_list_get_elem(linked_list, index);
if(tmp) linked_list_remove_elem(linked_list, tmp); if(tmp) linked_list_remove_elem(linked_list, tmp);
} }

View File

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