diff options
author | Thomas Haller <thaller@redhat.com> | 2017-06-05 14:39:10 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-07-05 14:22:10 +0200 |
commit | 26f04fd886b9dc72e567608f5efefde0bca3df71 (patch) | |
tree | a5a4bc6081744ab6a126af9709a03468ae690c14 | |
parent | 348959cfa26b8896e7c0bafa4abae0ae77c7767c (diff) | |
download | NetworkManager-26f04fd886b9dc72e567608f5efefde0bca3df71.tar.gz |
shared: update c-list
Reimport c-list from upstream. It allows iterating over const-list.
Upstream commit is 17e7781b3fe26e06bbe3817e8ed7418d80f63feb "build: update NEWS".
-rw-r--r-- | shared/nm-utils/c-list.h | 165 |
1 files changed, 63 insertions, 102 deletions
diff --git a/shared/nm-utils/c-list.h b/shared/nm-utils/c-list.h index 07e3f3cecd..557862b6ff 100644 --- a/shared/nm-utils/c-list.h +++ b/shared/nm-utils/c-list.h @@ -74,7 +74,7 @@ static inline void c_list_init(CList *what) { offsetof(_t, _m)) - offsetof(_t, _m))) /** - * c_list_is_linked() - check whether a entry is linked + * c_list_is_linked() - check whether an entry is linked * @what: entry to check, or NULL * * Return: True if @what is linked in a list, false if not. @@ -206,71 +206,22 @@ static inline void c_list_swap(CList *list1, CList *list2) { * This removes all the entries from @source and splice them into @target. * The order of the two lists is preserved and the source is appended * to the end of target. - */ -static inline void c_list_splice(CList *target, CList *source) { - if (c_list_is_empty(source)) - return; - - /* attach the front of @source to the tail of @target */ - source->next->prev = target->prev; - target->prev->next = source->next; - - /* attach the tail of @source to the front of @target */ - source->prev->next = target; - target->prev = source->prev; -} - -/** - * c_list_loop_first() - return first list element, or head if empty - * @list: list to operate on - * - * This is an O(1) accessor to the first list element. If the list is empty, - * this returns a pointer to the list head. Hence, this never returns NULL. - * - * Return: Pointer to first list element, or pointer to head if empty. - */ -static inline CList *c_list_loop_first(CList *list) { - return list->next; -} - -/** - * c_list_loop_last() - return last list element, or head if empty - * @list: list to operate on - * - * This is an O(1) accessor to the last list element. If the list is empty, - * this returns a pointer to the list head. Hence, this never returns NULL. * - * Return: Pointer to last list element, or pointer to head if empty. + * On return, the source list will be empty. */ -static inline CList *c_list_loop_last(CList *list) { - return list->prev; -} +static inline void c_list_splice(CList *target, CList *source) { + if (!c_list_is_empty(source)) { + /* attach the front of @source to the tail of @target */ + source->next->prev = target->prev; + target->prev->next = source->next; -/** - * c_list_loop_next() - return next list element, or head if none - * @what: list entry to operate on - * - * This is an O(1) accessor to the next list element. If @what is the list tail - * this will return a pointer to the list head. Hence, this never returns NULL. - * - * Return: Pointer to next list element, or pointer to head if none. - */ -static inline CList *c_list_loop_next(CList *what) { - return what->next; -} + /* attach the tail of @source to the front of @target */ + source->prev->next = target; + target->prev = source->prev; -/** - * c_list_loop_prev() - return previous list element, or head if none - * @what: list entry to operate on - * - * This is an O(1) accessor to the previous list element. If @what is the list - * front this will return a pointer to the list head. Hence, this never returns - * NULL. - * - * Return: Pointer to previous list element, or pointer to head if none. - */ -static inline CList *c_list_loop_prev(CList *what) { - return what->prev; + /* clear source */ + *source = (CList)C_LIST_INIT(*source); + } } /** @@ -281,10 +232,10 @@ static inline CList *c_list_loop_prev(CList *what) { * This is a macro to use as for-loop to iterate an entire list. It is meant as * convenience macro. Feel free to code your own loop iterator. */ -#define c_list_for_each(_iter, _list) \ - for (_iter = c_list_loop_first(_list); \ - _iter != (_list); \ - _iter = c_list_loop_next(_iter)) +#define c_list_for_each(_iter, _list) \ + for (_iter = (_list)->next; \ + (_iter) != (_list); \ + _iter = (_iter)->next) /** @@ -302,10 +253,10 @@ static inline CList *c_list_loop_prev(CList *what) { * havoc if you remove other list entries. You better not modify anything but * the current list entry. */ -#define c_list_for_each_safe(_iter, _safe, _list) \ - for (_iter = c_list_loop_first(_list), _safe = c_list_loop_next(_iter); \ - _iter != (_list); \ - _iter = _safe, _safe = c_list_loop_next(_safe)) +#define c_list_for_each_safe(_iter, _safe, _list) \ + for (_iter = (_list)->next, _safe = (_iter)->next; \ + (_iter) != (_list); \ + _iter = (_safe), _safe = (_safe)->next) /** * c_list_for_each_entry() - loop over all list entries @@ -316,10 +267,10 @@ static inline CList *c_list_loop_prev(CList *what) { * This combines c_list_for_each() with c_list_entry(), making it easy to * iterate over a list of a specific type. */ -#define c_list_for_each_entry(_iter, _list, _m) \ - for (_iter = c_list_entry(c_list_loop_first(_list), __typeof__(*_iter), _m); \ - &_iter->_m != (_list); \ - _iter = c_list_entry(c_list_loop_next(&_iter->_m), __typeof__(*_iter), _m)) +#define c_list_for_each_entry(_iter, _list, _m) \ + for (_iter = c_list_entry((_list)->next, __typeof__(*_iter), _m); \ + &(_iter)->_m != (_list); \ + _iter = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m)) /** * c_list_for_each_entry_safe() - loop over all list entries, safe for removal @@ -331,12 +282,12 @@ static inline CList *c_list_loop_prev(CList *what) { * This combines c_list_for_each_safe() with c_list_entry(), making it easy to * iterate over a list of a specific type. */ -#define c_list_for_each_entry_safe(_iter, _safe, _list, _m) \ - for (_iter = c_list_entry(c_list_loop_first(_list), __typeof__(*_iter), _m), \ - _safe = c_list_entry(c_list_loop_next(&_iter->_m), __typeof__(*_iter), _m);\ - &_iter->_m != (_list); \ - _iter = _safe, \ - _safe = c_list_entry(c_list_loop_next(&_safe->_m), __typeof__(*_iter), _m)) +#define c_list_for_each_entry_safe(_iter, _safe, _list, _m) \ + for (_iter = c_list_entry((_list)->next, __typeof__(*_iter), _m), \ + _safe = c_list_entry((_iter)->_m.next, __typeof__(*_iter), _m); \ + &(_iter)->_m != (_list); \ + _iter = (_safe), \ + _safe = c_list_entry((_safe)->_m.next, __typeof__(*_iter), _m)) \ /** * c_list_first() - return pointer to first element, or NULL if empty @@ -391,44 +342,54 @@ static inline CList *c_list_last(CList *list) { c_list_entry(c_list_last(_list), _t, _m) /** - * c_list_length() - return the number of linked entries, excluding the head + * c_list_length() - return number of linked entries, excluding the head * @list: list to operate on * - * Returns the number of entires in the list, excluding the list head - * @list. That is, for a list that is empty according to c_list_is_empty(), - * the returned length is 0. This requires to iterate the list and has - * thus O(n) runtime. + * Returns the number of entries in the list, excluding the list head @list. + * That is, for a list that is empty according to c_list_is_empty(), the + * returned length is 0. This requires to iterate the list and has thus O(n) + * runtime. * - * Return: the number of items in the list + * Note that this function is meant for debugging purposes only. If you need + * the list size during normal operation, you should maintain a counter + * separately. + * + * Return: Number of items in @list. */ -static inline size_t c_list_length(const CList *list) { - CList *iter; - size_t n = 0; +static inline unsigned long c_list_length(const CList *list) { + unsigned long n = 0; + const CList *iter; + + c_list_for_each(iter, list) + ++n; - c_list_for_each(iter, (CList *)list) - n++; return n; } /** - * c_list_contains() - whether an item is linked in a certain list + * c_list_contains() - check whether an entry is linked in a certain list * @list: list to operate on - * @what: the list entry to find + * @what: entry to look for * - * Searches @list whether @what is a linked entry of the list - * in O(n). For the head @list, this also returns True. + * This checks whether @what is linked into @list. This requires a linear + * search through the list, as such runs in O(n). Note that the list-head is + * considered part of the list, and hence this returns true if @what equals + * @list. * - * Return: True if @what is in @list + * Note that this function is meant for debugging purposes, and consistency + * checks. You should always be aware whether your objects are linked in a + * specific list. + * + * Return: True if @what is in @list, false otherwise. */ static inline _Bool c_list_contains(const CList *list, const CList *what) { - const CList *iter = list; + const CList *iter; - do { - if (iter == what) + c_list_for_each(iter, list) + if (what == iter) return 1; - iter = iter->next; - } while (iter != list); - return 0; + + return what == list; } #ifdef __cplusplus |