SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2001  David Decotigny
002  
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007     
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012     
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.
017 */
018 #ifndef _SOS_LIST_H_
019 #define _SOS_LIST_H_
020 
021 /**
022  * @file list.h
023  *
024  * Circular doubly-linked lists implementation entirely based on C
025  * macros
026  */
027 
028 
029 /* *_named are used when next and prev links are not exactly next
030    and prev. For instance when we have next_in_team, prev_in_team,
031    prev_global and next_global */
032 
033 #define list_init_named(list,prev,next) \
034   ((list) = NULL)
035 
036 #define list_singleton_named(list,item,prev,next) ({ \
037   (item)->next = (item)->prev = (item); \
038   (list) = (item); \
039 })
040 
041 #define list_is_empty_named(list,prev,next) \
042   ((list) == NULL)
043 
044 #define list_get_head_named(list,prev,next) \
045   (list)
046 
047 #define list_get_tail_named(list,prev,next) \
048   ((list)?((list)->prev):NULL)
049 
050 /* Internal macro : insert before the head == insert at tail */
051 #define __list_insert_atleft_named(before_this,item,prev,next) ({ \
052    (before_this)->prev->next = (item); \
053    (item)->prev = (before_this)->prev; \
054    (before_this)->prev = (item); \
055    (item)->next = (before_this); \
056 })
057 
058 /* @note Before_this and item are expected to be valid ! */
059 #define list_insert_before_named(list,before_this,item,prev,next) ({ \
060    __list_insert_atleft_named(before_this,item,prev,next); \
061    if ((list) == (before_this)) (list) = (item); \
062 })    
063 
064 /** @note After_this and item are expected to be valid ! */
065 #define list_insert_after_named(list,after_this,item,prev,next) ({ \
066    (after_this)->next->prev = (item); \
067    (item)->next = (after_this)->next; \
068    (after_this)->next = (item); \
069    (item)->prev = (after_this); \
070 })
071 
072 #define list_add_head_named(list,item,prev,next) ({ \
073   if (list) \
074     list_insert_before_named(list,list,item,prev,next); \
075   else \
076     list_singleton_named(list,item,prev,next); \
077   (list) = (item); \
078 })
079 
080 #define list_add_tail_named(list,item,prev,next) ({ \
081   if (list) \
082     __list_insert_atleft_named(list,item,prev,next); \
083   else \
084     list_singleton_named(list,item,prev,next); \
085 })
086 
087 /** @note NO check whether item really is in list ! */
088 #define list_delete_named(list,item,prev,next) ({ \
089   if ( ((item)->next == (item)) && ((item)->prev == (item)) ) \
090     (item)->next = (item)->prev = (list) = NULL; \
091   else { \
092     (item)->prev->next = (item)->next; \
093     (item)->next->prev = (item)->prev; \
094     if ((item) == (list)) (list) = (item)->next; \
095     (item)->prev = (item)->next = NULL; \
096   } \
097 })
098 
099 #define list_pop_head_named(list,prev,next) ({ \
100   typeof(list) __ret_elt = (list); \
101   list_delete_named(list,__ret_elt,prev,next); \
102   __ret_elt; })
103 
104 /** Loop statement that iterates through all of its elements, from
105     head to tail */
106 #define list_foreach_forward_named(list,iterator,nb_elements,prev,next) \
107         for (nb_elements=0, (iterator) = (list) ; \
108              (iterator) && (!nb_elements || ((iterator) != (list))) ; \
109              nb_elements++, (iterator) = (iterator)->next )
110 
111 /** Loop statement that iterates through all of its elements, from
112     tail back to head */
113 #define list_foreach_backward_named(list,iterator,nb_elements,prev,next) \
114         for (nb_elements=0, (iterator) = list_get_tail_named(list,prev,next) ; \
115              (iterator) && (!nb_elements || \
116                ((iterator) != list_get_tail_named(list,prev,next))) ; \
117              nb_elements++, (iterator) = (iterator)->prev )
118 
119 #define list_foreach_named list_foreach_forward_named
120 
121 /** True when we exitted early from the foreach loop (ie break) */
122 #define list_foreach_early_break(list,iterator,nb_elements) \
123   ((list) && ( \
124     ((list) != (iterator)) || \
125     ( ((list) == (iterator)) && (nb_elements == 0)) ))
126 
127 /** Loop statement that also removes the item at each iteration */
128 #define list_collapse_named(list,iterator,prev,next) \
129         for ( ; ({ ((iterator) = (list)) ; \
130                    if (list) list_delete_named(list,iterator,prev,next) ; \
131                    (iterator); }) ; )
132 
133 
134 /*
135  * the same macros : assume that the prev and next fields are really
136  * named "prev" and "next"
137  */
138 
139 #define list_init(list) \
140   list_init_named(list,prev,next)
141 
142 #define list_singleton(list,item) \
143   list_singleton_named(list,item,prev,next)
144 
145 #define list_is_empty(list) \
146   list_is_empty_named(list,prev,next)
147 
148 #define list_get_head(list) \
149   list_get_head_named(list,prev,next) \
150 
151 #define list_get_tail(list) \
152   list_get_tail_named(list,prev,next) \
153 
154 /* @note Before_this and item are expected to be valid ! */
155 #define list_insert_after(list,after_this,item) \
156   list_insert_after_named(list,after_this,item,prev,next)
157 
158 /* @note After_this and item are expected to be valid ! */
159 #define list_insert_before(list,before_this,item) \
160   list_insert_before_named(list,before_this,item,prev,next)
161 
162 #define list_add_head(list,item) \
163   list_add_head_named(list,item,prev,next)
164 
165 #define list_add_tail(list,item) \
166   list_add_tail_named(list,item,prev,next)
167 
168 /* @note NO check whether item really is in list ! */
169 #define list_delete(list,item) \
170   list_delete_named(list,item,prev,next)
171 
172 #define list_pop_head(list) \
173   list_pop_head_named(list,prev,next)
174 
175 #define list_foreach_forward(list,iterator,nb_elements) \
176   list_foreach_forward_named(list,iterator,nb_elements,prev,next)
177 
178 #define list_foreach_backward(list,iterator,nb_elements) \
179   list_foreach_backward_named(list,iterator,nb_elements,prev,next)
180 
181 #define list_foreach list_foreach_forward
182 
183 #define list_collapse(list,iterator) \
184   list_collapse_named(list,iterator,prev,next)
185 
186 #endif /* _SOS_LIST_H_ */

source navigation ] diff markup ] identifier search ] general search ]