list.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #ifndef LIBC_LIST_H_
00036 #define LIBC_LIST_H_
00037 
00038 #include <unistd.h>
00039 
00041 typedef struct link {
00042         struct link *prev;  
00043         struct link *next;  
00044 } link_t;
00045 
00051 #define LIST_INITIALIZE(name) \
00052         link_t name = { \
00053                 .prev = &name, \
00054                 .next = &name \
00055         }
00056 
00057 #define list_get_instance(link, type, member) \
00058         ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
00059 
00060 #define list_foreach(list, iterator) \
00061         for (link_t *iterator = (list).next; \
00062             iterator != &(list); iterator = iterator->next)
00063 
00071 static inline void link_initialize(link_t *link)
00072 {
00073         link->prev = NULL;
00074         link->next = NULL;
00075 }
00076 
00084 static inline void list_initialize(link_t *list)
00085 {
00086         list->prev = list;
00087         list->next = list;
00088 }
00089 
00098 static inline void list_prepend(link_t *link, link_t *list)
00099 {
00100         link->next = list->next;
00101         link->prev = list;
00102         list->next->prev = link;
00103         list->next = link;
00104 }
00105 
00114 static inline void list_append(link_t *link, link_t *list)
00115 {
00116         link->prev = list->prev;
00117         link->next = list;
00118         list->prev->next = link;
00119         list->prev = link;
00120 }
00121 
00125 static inline void list_insert_before(link_t *link, link_t *list)
00126 {
00127         list_append(link, list);
00128 }
00129 
00133 static inline void list_insert_after(link_t *link, link_t *list)
00134 {
00135         list_prepend(list, link);
00136 }
00137 
00146 static inline void list_remove(link_t *link)
00147 {
00148         link->next->prev = link->prev;
00149         link->prev->next = link->next;
00150         link_initialize(link);
00151 }
00152 
00160 static inline int list_empty(link_t *list)
00161 {
00162         return (list->next == list);
00163 }
00164 
00173 static inline link_t *list_head(link_t *list)
00174 {
00175         return ((list->next == list) ? NULL : list->next);
00176 }
00177 
00191 static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
00192 {
00193         part1->prev->next = part2;
00194         part2->prev->next = part1;
00195         
00196         link_t *hlp = part1->prev;
00197         
00198         part1->prev = part2->prev;
00199         part2->prev = hlp;
00200 }
00201 
00212 static inline void headless_list_split(link_t *part1, link_t *part2)
00213 {
00214         headless_list_split_or_concat(part1, part2);
00215 }
00216 
00227 static inline void headless_list_concat(link_t *part1, link_t *part2)
00228 {
00229         headless_list_split_or_concat(part1, part2);
00230 }
00231 
00241 static inline link_t *list_nth(link_t *list, unsigned int n)
00242 {
00243         unsigned int cnt = 0;
00244         
00245         list_foreach(*list, link) {
00246                 if (cnt == n)
00247                         return link;
00248                 
00249                 cnt++;
00250         }
00251         
00252         return NULL;
00253 }
00254 
00255 extern int list_member(const link_t *, const link_t *);
00256 extern void list_concat(link_t *, link_t *);
00257 extern unsigned int list_count(const link_t *);
00258 
00259 #endif
00260 

Generated on Thu Jun 2 07:45:42 2011 for HelenOS/USB by  doxygen 1.4.7