Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/adt/list.h

    re98f1c3e r9d58539  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
    3  * Copyright (c) 2013 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    3737#define KERN_LIST_H_
    3838
    39 #include <debug.h>
    4039#include <typedefs.h>
    4140#include <trace.h>
     
    5150        link_t head;  /**< List head. Does not have any data. */
    5251} list_t;
    53 
    54 
    55 extern bool list_member(const link_t *, const list_t *);
    56 extern void list_splice(list_t *, link_t *);
    57 extern unsigned long list_count(const list_t *);
    58 
    5952
    6053/** Declare and initialize statically allocated list.
     
    7265
    7366#define list_get_instance(link, type, member) \
    74         ((type *) (((void *)(link)) - list_link_to_void(&(((type *) NULL)->member))))
    75 
    76 #define list_foreach(list, member, itype, iterator) \
    77         for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
    78                 for (link_t *_link = (list).head.next; \
    79                     iterator = list_get_instance(_link, itype, member), \
    80                     _link != &(list).head; _link = _link->next)
    81 
    82 #define list_foreach_rev(list, member, itype, iterator) \
    83         for (itype *iterator = NULL; iterator == NULL; iterator = (itype *) 1) \
    84                 for (link_t *_link = (list).head.prev; \
    85                     iterator = list_get_instance(_link, itype, member), \
    86                     _link != &(list).head; _link = _link->prev)
    87 
    88 /** Unlike list_foreach(), allows removing items while traversing a list.
    89  *
    90  * @code
    91  * list_t mylist;
    92  * typedef struct item {
    93  *     int value;
    94  *     link_t item_link;
    95  * } item_t;
    96  *
    97  * //..
    98  *
    99  * // Print each list element's value and remove the element from the list.
    100  * list_foreach_safe(mylist, cur_link, next_link) {
    101  *     item_t *cur_item = list_get_instance(cur_link, item_t, item_link);
    102  *     printf("%d\n", cur_item->value);
    103  *     list_remove(cur_link);
    104  * }
    105  * @endcode
    106  *
    107  * @param list List to traverse.
    108  * @param iterator Iterator to the current element of the list.
    109  *             The item this iterator points may be safely removed
    110  *             from the list.
    111  * @param next_iter Iterator to the next element of the list.
    112  */
    113 #define list_foreach_safe(list, iterator, next_iter) \
    114         for (link_t *iterator = (list).head.next, \
    115             *next_iter = iterator->next; \
    116             iterator != &(list).head; \
    117             iterator = next_iter, next_iter = iterator->next)
    118 
    119        
     67        ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
     68
     69#define list_foreach(list, iterator) \
     70        for (link_t *iterator = (list).head.next; \
     71            iterator != &(list).head; iterator = iterator->next)
     72
    12073#define assert_link_not_used(link) \
    121         ASSERT(!link_used(link))
     74        ASSERT(((link)->prev == NULL) && ((link)->next == NULL))
    12275
    12376/** Initialize doubly-linked circular list link
     
    220173 *
    221174 */
    222 NO_TRACE static inline bool list_empty(const list_t *list)
     175NO_TRACE static inline int list_empty(const list_t *list)
    223176{
    224177        return (list->head.next == &list->head);
     
    249202{
    250203        return ((list->head.prev == &list->head) ? NULL : list->head.prev);
    251 }
    252 
    253 /** Get next item in list.
    254  *
    255  * @param link Current item link
    256  * @param list List containing @a link
    257  *
    258  * @return Next item or NULL if @a link is the last item.
    259  */
    260 static inline link_t *list_next(link_t *link, const list_t *list)
    261 {
    262         return (link->next == &list->head) ? NULL : link->next;
    263 }
    264 
    265 /** Get previous item in list.
    266  *
    267  * @param link Current item link
    268  * @param list List containing @a link
    269  *
    270  * @return Previous item or NULL if @a link is the first item.
    271  */
    272 static inline link_t *list_prev(link_t *link, const list_t *list)
    273 {
    274         return (link->prev == &list->head) ? NULL : link->prev;
    275204}
    276205
     
    329258}
    330259
    331 /** Concatenate two lists
    332  *
    333  * Concatenate lists @a list1 and @a list2, producing a single
    334  * list @a list1 containing items from both (in @a list1, @a list2
    335  * order) and empty list @a list2.
    336  *
    337  * @param list1         First list and concatenated output
    338  * @param list2         Second list and empty output.
    339  *
    340  */
    341 NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
    342 {
    343         list_splice(list2, list1->head.prev);
    344 }
    345 
    346260/** Get n-th item in a list.
    347261 *
     
    353267 *
    354268 */
    355 static inline link_t *list_nth(list_t *list, unsigned long n)
    356 {
    357         unsigned long cnt = 0;
    358         link_t *link;
    359        
    360         link = list_first(list);
    361         while (link != NULL) {
     269static inline link_t *list_nth(list_t *list, unsigned int n)
     270{
     271        unsigned int cnt = 0;
     272       
     273        list_foreach(*list, link) {
    362274                if (cnt == n)
    363275                        return link;
    364276               
    365277                cnt++;
    366                 link = list_next(link, list);
    367278        }
    368279       
     
    370281}
    371282
    372 /** Verify that argument type is a pointer to link_t (at compile time).
    373  *
    374  * This can be used to check argument type in a macro.
    375  */
    376 static inline const void *list_link_to_void(const link_t *link)
    377 {
    378         return link;
    379 }
    380 
    381 /** Determine if link is used.
    382  *
    383  * @param link Link
    384  * @return @c true if link is used, @c false if not.
    385  */
    386 static inline bool link_used(link_t *link)
    387 {
    388         if (link->prev == NULL && link->next == NULL)
    389                 return false;
    390 
    391         ASSERT(link->prev != NULL && link->next != NULL);
    392         return true;
    393 }
     283extern int list_member(const link_t *, const list_t *);
     284extern void list_concat(list_t *, list_t *);
     285extern unsigned int list_count(const list_t *);
    394286
    395287#endif
Note: See TracChangeset for help on using the changeset viewer.