/******************************************************************************* * @file * @brief Single Link List. ******************************************************************************* * # License * Copyright 2019 Silicon Laboratories Inc. www.silabs.com ******************************************************************************* * * SPDX-License-Identifier: Zlib * * The licensor of this software is Silicon Laboratories Inc. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * ******************************************************************************/ #ifndef SL_SLIST_H #define SL_SLIST_H #include #include #include #ifdef __cplusplus extern "C" { #endif /******************************************************************************* * @addtogroup slist Singly-Linked List * @brief Singly-linked List module provides APIs to handle singly-linked list * operations such as insert, push, pop, push back, sort and remove. * * @note The pop operation follows FIFO method. * @n @section slist_usage Singly-Linked List module Usage * @{ ******************************************************************************/ /// List node type typedef struct sl_slist_node sl_slist_node_t; /// List node struct sl_slist_node { sl_slist_node_t *node; ///< List node }; #ifndef DOXYGEN #define container_of(ptr, type, member) (type *)((uintptr_t)(ptr) - ((uintptr_t)(&((type *)0)->member))) #define SL_SLIST_ENTRY container_of #define SL_SLIST_FOR_EACH(list_head, iterator) for ((iterator) = (list_head); (iterator) != NULL; (iterator) = (iterator)->node) #define SL_SLIST_FOR_EACH_ENTRY(list_head, entry, type, member) for ( (entry) = SL_SLIST_ENTRY(list_head, type, member); \ (type *)(entry) != SL_SLIST_ENTRY(NULL, type, member); \ (entry) = SL_SLIST_ENTRY((entry)->member.node, type, member)) #endif // ----------------------------------------------------------------------------- // Prototypes /******************************************************************************* * Initialize a singly-linked list. * * @param head Pointer to pointer of head element of list. ******************************************************************************/ void sl_slist_init(sl_slist_node_t **head); /******************************************************************************* * Add given item at beginning of the list. * * @param head Pointer to pointer of head element of the list. * * @param item Pointer to an item to add. ******************************************************************************/ void sl_slist_push(sl_slist_node_t **head, sl_slist_node_t *item); /******************************************************************************* * Add item at the end of the list. * * @param head Pointer to the pointer of a head element of the list. * * @param item Pointer to the item to add. ******************************************************************************/ void sl_slist_push_back(sl_slist_node_t **head, sl_slist_node_t *item); /******************************************************************************* * Remove and return the first element of the list. * * @param head Pointer to he pointer of the head element of the list. * * @return Pointer to item that was at top of the list. ******************************************************************************/ sl_slist_node_t *sl_slist_pop(sl_slist_node_t **head); /******************************************************************************* * Insert an item after the given item. * * @param item Pointer to an item to add. * * @param pos Pointer to an item after which the item to add will be inserted. ******************************************************************************/ void sl_slist_insert(sl_slist_node_t *item, sl_slist_node_t *pos); /******************************************************************************* * Join two lists together. * * @param head_list_1 Pointer to the pointer of a head element of the list. * * @param head_list_2 Pointer to the pointer of a head element of the list * to be appended. After the call, this pointer will be * invalidated (set to NULL). ******************************************************************************/ void sl_slist_join(sl_slist_node_t **head_list_1, sl_slist_node_t **head_list_2); /******************************************************************************* * Remove an item from the list. * * @param head Pointer to pointer of the head element of list. * * @param item Pointer to the item to remove. ******************************************************************************/ void sl_slist_remove(sl_slist_node_t **head, sl_slist_node_t *item); /******************************************************************************* * Sort list items. * * @param head Pointer to the pointer of the head element of the list. * * @param cmp_fnct Pointer to function to use for sorting the list. * item_l Pointer to left item. * item_r Pointer to right item. * Returns whether the two items are ordered (true) or not (false). ******************************************************************************/ void sl_slist_sort(sl_slist_node_t **head, bool (*cmp_fnct)(sl_slist_node_t *item_l, sl_slist_node_t *item_r)); /******************************************************************************* * Checks if the list is empty. * * @param head Pointer to the head element of the list. ******************************************************************************/ static inline bool sl_slist_is_empty(sl_slist_node_t *head) { return head == NULL; } /** @} (end addtogroup slist) */ #ifdef __cplusplus } #endif #endif /* SL_SLIST_H */