Simple data structures / objects in plain C Snapshot
|
Single linked list data structure; where each list element can be of different length. More...
Classes | |
struct | SLIST |
Defines | |
#define | SLIST_FOREACH(loopvarname, list) |
Macro for iterate over all elements of a list, the list is traversed in forward direction from first element to the last element. | |
#define | SLIST_FOREACH_SAVE(loopvarname, loopvarnamenext, list) |
Macro for iterate over all elements of a list, the list is traversed in forward direction from first element to the last element. | |
Typedefs | |
typedef void(* | SLIST_VISITOR_V )(SLIST *list, SLIST_entry *entry, void *context) |
typedef int32_t(* | SLIST_VISITOR )(SLIST *list, SLIST_entry *entry, void *context) |
typedef int32_t(* | SLIST_COMPARE )(SLIST_entry *, SLIST_entry *) |
Functions | |
M_INLINE void | SLIST_init (SLIST *head) |
initialises an empty list head | |
M_INLINE int | SLIST_isempty (SLIST *head) |
checks if argument list is empty | |
M_INLINE void | SLIST_insert_after (SLIST *list, SLIST_entry *pos, SLIST_entry *newentry) |
insert new entry after a given entry. | |
M_INLINE SLIST_entry * | SLIST_unlink_after (SLIST *list, SLIST_entry *link) |
delete an element from a list. | |
M_INLINE void | SLIST_push_back (SLIST *list, SLIST_entry *newentry) |
insert element as last in list. | |
M_INLINE void | SLIST_push_front (SLIST *list, SLIST_entry *newentry) |
insert element as first in list (used to maintain queue) | |
M_INLINE void | SLIST_append (SLIST *dest, SLIST *src) |
append contents of one list onto the other | |
M_INLINE SLIST_entry * | SLIST_pop_front (SLIST *list) |
remove the first element from list (used to maintain queue) | |
M_INLINE SLIST_entry * | SLIST_get_first (SLIST *list) |
M_INLINE SLIST_entry * | SLIST_get_last (SLIST *list) |
M_INLINE SLIST_entry * | SLIST_get_next (SLIST_entry *cur) |
M_INLINE size_t | SLIST_size (SLIST *list) |
: return number of elements in list if we don't have element count in list (SLIST_NO_ELMCOUNT defined), then the whole list structure is traversed. | |
M_INLINE SLIST_entry * | SLIST_get_nth (SLIST *list, size_t nth) |
M_INLINE SLIST_entry * | SLIST_get_nth_reverse (SLIST *list, size_t nth) |
get the nth element of a list as counted from the end of the list. | |
M_INLINE void | SLIST_foreach (SLIST *lst, SLIST_VISITOR_V eval, void *context) |
iterate over all elements of a list, callback is invoked for either element of the list. | |
M_INLINE SLIST_entry * | SLIST_findif (SLIST *lst, SLIST_VISITOR eval, void *context, int32_t *retval) |
find an element within the linked list. callback is invoked for each element of the list, in forward direction from first element to last element; when the callback returns non zero value the iteration stops as we have found what we searched for. | |
M_INLINE void | SLIST_insert_sorted (SLIST *list, SLIST_COMPARE compare, SLIST_entry *newentry) |
insert new element into sorted list; Maintains ordering relationship between elements of linked list (sort by ascending order) A sorting algorithm based on this function is not very efficient; it is of complexity O(n^2); nevertheless usefull if a list is modified and has to be always maintained in sorted order. | |
M_INLINE void | SLIST_deleteif (SLIST *list, SLIST_VISITOR check_if, void *context, int offset_of_link) |
iterate over all entries of the list and delete entries that match predicate from the list, and frees the memory (optionally) | |
M_INLINE void | SLIST_deleteall (SLIST *list, SLIST_VISITOR_V on_delete, void *context, int offset_of_link) |
iterate over all entries of the list and delete them. | |
M_INLINE void | SLIST_reverse (SLIST *lst) |
Reverse a list This function turns the first element into the last element, the second element into the one before the last, and so on and on. | |
M_INLINE int | SLIST_check (SLIST *header) |
check consistency of list This function checks for loops in the list, and if count of elements in list is the same as counter of elements in list header. |
Single linked list data structure; where each list element can be of different length.
This single linked list has a list header (SLIST). The list header points to the first and last element in the list. last elements next pointer is NULL.
Usage: If the user wants to link his struct(ure) into a list, then he must embed a SLIST_entry into his structure. Access to user defined structure is via embedded SLIST_entry.
The list header contains a counter of elements (feature can be surpressed by defining #define SLIST_NO_ELMCOUNT
#define SLIST_FOREACH | ( | loopvarname, | |
list | |||
) |
for((loopvarname) = (list)->prev;\
(loopvarname) != 0;\
(loopvarname) = (loopvarname)->next )
Macro for iterate over all elements of a list, the list is traversed in forward direction from first element to the last element.
loopvarname | (type SLIST_entry *) pointer to the current element |
list | (type SLIST *) pointer to the list that is traversed |
#define SLIST_FOREACH_SAVE | ( | loopvarname, | |
loopvarnamenext, | |||
list | |||
) |
for((loopvarname) = (list)->prev, (loopvarnamenext) = (loopvarname) ? (loopvarname)->next : 0;\
(loopvarname) != 0;\
(loopvarname) = (loopvarnamenext), (loopvarnamenext) = (loopvarname) ? (loopvarname)->next : 0 )
Macro for iterate over all elements of a list, the list is traversed in forward direction from first element to the last element.
loopvsarname | (type SLIST_entry *) pointer to the current element |
list | (type SLIST *) pointer to the list that is traversed |
typedef int32_t(* SLIST_COMPARE)(SLIST_entry *, SLIST_entry *) |
typedef int32_t(* SLIST_VISITOR)(SLIST *list, SLIST_entry *entry, void *context) |
typedef void(* SLIST_VISITOR_V)(SLIST *list, SLIST_entry *entry, void *context) |
append contents of one list onto the other
dest | |
src | content of this list is appended onto dest list. postcondition: src list is empty |
Definition at line 183 of file slist.h.
{ if (SLIST_isempty(dest)) { if (!SLIST_isempty(src)) { dest->prev = src->prev; dest->next = src->next; #ifndef SLIST_NO_ELMCOUNT dest->elmcount = src->elmcount; #endif //SLIST_init(src); } } else { if (!SLIST_isempty(src)) { dest->next->next = src->prev; dest->next = src->next; #ifndef SLIST_NO_ELMCOUNT dest->elmcount += src->elmcount; #endif //SLIST_init(src); } } }
M_INLINE int SLIST_check | ( | SLIST * | header | ) |
check consistency of list This function checks for loops in the list, and if count of elements in list is the same as counter of elements in list header.
header | (in) the object |
Definition at line 499 of file slist.h.
{ SLIST_entry *cur,*prev = 0,*fast= 0; #ifndef SLIST_NO_ELMCOUNT size_t count = 0; #endif if (!header->prev || !header->next) { if (header->prev || header->next) { return 0; } return 1; } fast = header->prev; SLIST_FOREACH( cur, header ) { #ifndef SLIST_NO_ELMCOUNT count += 1; #endif prev = fast; fast = fast->next; if (!fast) { break; } if (fast == cur) { return 0; } #ifndef SLIST_NO_ELMCOUNT count += 1; #endif prev = fast; fast = fast->next; if (!fast) { break; } if (fast == cur) { return 0; } } if (header->next != prev) { return 0; } #ifndef SLIST_NO_ELMCOUNT if (header->elmcount != count) { return 0; } #endif return 1; }
M_INLINE void SLIST_deleteall | ( | SLIST * | list, |
SLIST_VISITOR_V | on_delete, | ||
void * | context, | ||
int | offset_of_link | ||
) |
iterate over all entries of the list and delete them.
list | (in) the object |
on_delete(in) | if not NULL then this callback is called prior to deleting each list element. |
context | (in) if on_delete is not NULL then this pointer is passed as argument to on_delete. |
free_ctx | (in) allocation interface used to free data of entry. |
offset_of_link | (in) offset of SRING in embedded structure. |
Definition at line 445 of file slist.h.
{ SLIST_entry *cur,*del; for(cur = list->prev; cur;) { if (on_delete) { on_delete( list, cur, context ); } cur = cur->next; del = SLIST_unlink_after( list, 0 ); if (offset_of_link != -1) { free( _MEMBEROF(del, offset_of_link) ); } } }
M_INLINE void SLIST_deleteif | ( | SLIST * | list, |
SLIST_VISITOR | check_if, | ||
void * | context, | ||
int | offset_of_link | ||
) |
iterate over all entries of the list and delete entries that match predicate from the list, and frees the memory (optionally)
list | (in) the object. |
check_if | (in) predicate function; the function returns 1 then inspected argument element will be deleted; if argument pointer is NULL then all entries will be deleted. |
context | (in) data pointer passed to every invocation of check_if |
free_ctx | (in) interface used to free data of entry, is argument pointer is NULL then nothing is freed. |
offset_of_link | (in) offset of DLIST_entry in embedded structure. |
Definition at line 410 of file slist.h.
{ SLIST_entry *cur,*prev,*del; prev = 0; for(cur = list->prev; cur;) { if (!check_if || check_if( list, cur, context)) { cur = cur->next; del = SLIST_unlink_after( list, prev ); if (offset_of_link != -1) { free( _MEMBEROF(del, offset_of_link) ); } } else { prev = cur; cur = cur->next; } } }
M_INLINE SLIST_entry* SLIST_findif | ( | SLIST * | lst, |
SLIST_VISITOR | eval, | ||
void * | context, | ||
int32_t * | retval | ||
) |
find an element within the linked list. callback is invoked for each element of the list, in forward direction from first element to last element; when the callback returns non zero value the iteration stops as we have found what we searched for.
lst | (in) the object. |
eval | (in) callback that is called to visit each set (or cleared) bit. |
context | (in) pointer that is passed as context on each invocation of callback. |
retval | (out) optional - the first non zero value returned by eval callback, if NULL then ignored. |
Definition at line 349 of file slist.h.
{ int ret; SLIST_entry *cur; if (retval) { *retval = 0; } if (!eval) { return 0; } SLIST_FOREACH( cur, lst ) { ret = eval( lst, cur, context); if (ret) { if (retval) { *retval = ret; } return cur; } } return 0; }
M_INLINE void SLIST_foreach | ( | SLIST * | lst, |
SLIST_VISITOR_V | eval, | ||
void * | context | ||
) |
iterate over all elements of a list, callback is invoked for either element of the list.
lst | (in) the object. |
eval | (in) callback that is called to visit each set (or cleared) bit. |
context | (in) pointer that is passed as context on each invocation of callback. |
Definition at line 326 of file slist.h.
{ SLIST_entry *cur; if (!eval) { return; } SLIST_FOREACH( cur, lst) { eval( lst, cur, context); } }
M_INLINE SLIST_entry* SLIST_get_first | ( | SLIST * | list | ) |
M_INLINE SLIST_entry* SLIST_get_last | ( | SLIST * | list | ) |
M_INLINE SLIST_entry* SLIST_get_next | ( | SLIST_entry * | cur | ) |
M_INLINE SLIST_entry* SLIST_get_nth | ( | SLIST * | list, |
size_t | nth | ||
) |
Definition at line 290 of file slist.h.
{ SLIST_entry *elm; #ifndef SLIST_NO_ELMCOUNT if (nth >= list->elmcount) { return 0; } for(elm = SLIST_get_first(list); nth > 0; nth -= 1, elm = SLIST_get_next(elm)); #else for(elm = SLIST_get_first(list); elm != 0 && nth > 0; nth -= 1, elm = SLIST_get_next(elm)); #endif return elm; }
M_INLINE SLIST_entry* SLIST_get_nth_reverse | ( | SLIST * | list, |
size_t | nth | ||
) |
get the nth element of a list as counted from the end of the list.
list (IN) the object nth (IN) index of element to retrieve (null based).
Definition at line 313 of file slist.h.
{ return SLIST_get_nth( list, SLIST_size( list ) - nth ); }
M_INLINE void SLIST_init | ( | SLIST * | head | ) |
M_INLINE void SLIST_insert_after | ( | SLIST * | list, |
SLIST_entry * | pos, | ||
SLIST_entry * | newentry | ||
) |
insert new entry after a given entry.
list | pointer to list head |
pos | current posision (newentry inserted after this one). |
newentry | pointer to new list entry (to be inserted). |
Definition at line 88 of file slist.h.
{ if (list->next) { if (pos){ newentry->next = pos->next; pos->next = newentry; if (!newentry->next) { list->next = newentry; } } else { newentry->next = list->prev; list->prev = newentry; } } else { list->next = list->prev = newentry; newentry->next = 0; } #ifndef SLIST_NO_ELMCOUNT list->elmcount ++; #endif }
M_INLINE void SLIST_insert_sorted | ( | SLIST * | list, |
SLIST_COMPARE | compare, | ||
SLIST_entry * | newentry | ||
) |
insert new element into sorted list; Maintains ordering relationship between elements of linked list (sort by ascending order) A sorting algorithm based on this function is not very efficient; it is of complexity O(n^2); nevertheless usefull if a list is modified and has to be always maintained in sorted order.
list | (in) the object |
compare | (in) comparison function. |
newentry | (in) element that is to be inserted into list. |
Definition at line 385 of file slist.h.
{ SLIST_entry *cur,*prev; prev = 0; SLIST_FOREACH( cur, list ) { if (compare(cur,newentry) > 0) { SLIST_insert_after(list, prev,newentry); return; } prev = cur; } SLIST_push_back( list, newentry ); }
M_INLINE int SLIST_isempty | ( | SLIST * | head | ) |
M_INLINE SLIST_entry* SLIST_pop_front | ( | SLIST * | list | ) |
remove the first element from list (used to maintain queue)
list | (in) the object |
Definition at line 220 of file slist.h.
{ return SLIST_unlink_after(list, 0); }
M_INLINE void SLIST_push_back | ( | SLIST * | list, |
SLIST_entry * | newentry | ||
) |
insert element as last in list.
list | list head. |
newentry | entry to be inserted into list |
Definition at line 162 of file slist.h.
{ SLIST_insert_after( list, list->next, newentry ); }
M_INLINE void SLIST_push_front | ( | SLIST * | list, |
SLIST_entry * | newentry | ||
) |
insert element as first in list (used to maintain queue)
list | list head |
newentry | entry to be inserted into list |
Definition at line 172 of file slist.h.
{ SLIST_insert_after( list, 0, newentry ); }
M_INLINE void SLIST_reverse | ( | SLIST * | lst | ) |
Reverse a list This function turns the first element into the last element, the second element into the one before the last, and so on and on.
header | (in) the object |
M_INLINE size_t SLIST_size | ( | SLIST * | list | ) |
: return number of elements in list if we don't have element count in list (SLIST_NO_ELMCOUNT defined), then the whole list structure is traversed.
Definition at line 270 of file slist.h.
{ #ifndef SLIST_NO_ELMCOUNT return list->elmcount; #else size_t sz; SLIST_entry * cur; SLIST_FOREACH( cur, list ) { sz += 1; } return sz; #endif }
M_INLINE SLIST_entry* SLIST_unlink_after | ( | SLIST * | list, |
SLIST_entry * | link | ||
) |
delete an element from a list.
list | deletes this list element |
Definition at line 125 of file slist.h.
{ SLIST_entry *ret; if (!link) { ret = list->prev; list->prev = ret->next; if (!list->prev) { list->next = 0; } } else { ret = link->next; if (!ret) { return 0; } link->next = ret ? ret->next : 0; if (link->next == 0) { list->next = link; } } #ifndef SLIST_NO_ELMCOUNT list->elmcount --; #endif return ret; }