ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

list.h
Go to the documentation of this file.
00001 /*
00002  * Linked lists support
00003  *
00004  * Copyright (C) 2002 Alexandre Julliard
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #ifndef __WINE_SERVER_LIST_H
00022 #define __WINE_SERVER_LIST_H
00023 
00024 #ifdef __cplusplus
00025 #define __WINE_SERVER_LIST_INLINE inline
00026 #else
00027 #if defined(__GNUC__)
00028 #define __WINE_SERVER_LIST_INLINE extern __inline__ __attribute__((__always_inline__))
00029 #elif defined(_MSC_VER)
00030 #define __WINE_SERVER_LIST_INLINE __inline
00031 #else
00032 #define __WINE_SERVER_LIST_INLINE static
00033 #endif
00034 #endif
00035 
00036 struct list
00037 {
00038     struct list *next;
00039     struct list *prev;
00040 };
00041 
00042 /* Define a list like so:
00043  *
00044  *   struct gadget
00045  *   {
00046  *       struct list  entry;   <-- doesn't have to be the first item in the struct
00047  *       int          a, b;
00048  *   };
00049  *
00050  *   static struct list global_gadgets = LIST_INIT( global_gadgets );
00051  *
00052  * or
00053  *
00054  *   struct some_global_thing
00055  *   {
00056  *       struct list gadgets;
00057  *   };
00058  *
00059  *   list_init( &some_global_thing->gadgets );
00060  *
00061  * Manipulate it like this:
00062  *
00063  *   list_add_head( &global_gadgets, &new_gadget->entry );
00064  *   list_remove( &new_gadget->entry );
00065  *   list_add_after( &some_random_gadget->entry, &new_gadget->entry );
00066  *
00067  * And to iterate over it:
00068  *
00069  *   struct gadget *gadget;
00070  *   LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry )
00071  *   {
00072  *       ...
00073  *   }
00074  *
00075  */
00076 
00077 /* add an element after the specified one */
00078 __WINE_SERVER_LIST_INLINE void list_add_after( struct list *elem, struct list *to_add )
00079 {
00080     to_add->next = elem->next;
00081     to_add->prev = elem;
00082     elem->next->prev = to_add;
00083     elem->next = to_add;
00084 }
00085 
00086 /* add an element before the specified one */
00087 __WINE_SERVER_LIST_INLINE void list_add_before( struct list *elem, struct list *to_add )
00088 {
00089     to_add->next = elem;
00090     to_add->prev = elem->prev;
00091     elem->prev->next = to_add;
00092     elem->prev = to_add;
00093 }
00094 
00095 /* add element at the head of the list */
00096 __WINE_SERVER_LIST_INLINE void list_add_head( struct list *list, struct list *elem )
00097 {
00098     list_add_after( list, elem );
00099 }
00100 
00101 /* add element at the tail of the list */
00102 __WINE_SERVER_LIST_INLINE void list_add_tail( struct list *list, struct list *elem )
00103 {
00104     list_add_before( list, elem );
00105 }
00106 
00107 /* remove an element from its list */
00108 __WINE_SERVER_LIST_INLINE void list_remove( struct list *elem )
00109 {
00110     elem->next->prev = elem->prev;
00111     elem->prev->next = elem->next;
00112 }
00113 
00114 /* get the next element */
00115 __WINE_SERVER_LIST_INLINE struct list *list_next( const struct list *list, const struct list *elem )
00116 {
00117     struct list *ret = elem->next;
00118     if (elem->next == list) ret = NULL;
00119     return ret;
00120 }
00121 
00122 /* get the previous element */
00123 __WINE_SERVER_LIST_INLINE struct list *list_prev( const struct list *list, const struct list *elem )
00124 {
00125     struct list *ret = elem->prev;
00126     if (elem->prev == list) ret = NULL;
00127     return ret;
00128 }
00129 
00130 /* get the first element */
00131 __WINE_SERVER_LIST_INLINE struct list *list_head( const struct list *list )
00132 {
00133     return list_next( list, list );
00134 }
00135 
00136 /* get the last element */
00137 __WINE_SERVER_LIST_INLINE struct list *list_tail( const struct list *list )
00138 {
00139     return list_prev( list, list );
00140 }
00141 
00142 /* check if a list is empty */
00143 __WINE_SERVER_LIST_INLINE int list_empty( const struct list *list )
00144 {
00145     return list->next == list;
00146 }
00147 
00148 /* initialize a list */
00149 __WINE_SERVER_LIST_INLINE void list_init( struct list *list )
00150 {
00151     list->next = list->prev = list;
00152 }
00153 
00154 /* count the elements of a list */
00155 __WINE_SERVER_LIST_INLINE unsigned int list_count( const struct list *list )
00156 {
00157     unsigned count = 0;
00158     const struct list *ptr;
00159     for (ptr = list->next; ptr != list; ptr = ptr->next) count++;
00160     return count;
00161 }
00162 
00163 /* move all elements from src to the tail of dst */
00164 __WINE_SERVER_LIST_INLINE void list_move_tail( struct list *dst, struct list *src )
00165 {
00166     if (list_empty(src)) return;
00167 
00168     dst->prev->next = src->next;
00169     src->next->prev = dst->prev;
00170     dst->prev = src->prev;
00171     src->prev->next = dst;
00172     list_init(src);
00173 }
00174 
00175 /* move all elements from src to the head of dst */
00176 __WINE_SERVER_LIST_INLINE void list_move_head( struct list *dst, struct list *src )
00177 {
00178     if (list_empty(src)) return;
00179 
00180     dst->next->prev = src->prev;
00181     src->prev->next = dst->next;
00182     dst->next = src->next;
00183     src->next->prev = dst;
00184     list_init(src);
00185 }
00186 
00187 /* iterate through the list */
00188 #define LIST_FOR_EACH(cursor,list) \
00189     for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
00190 
00191 /* iterate through the list, with safety against removal */
00192 #define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
00193     for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
00194          (cursor) != (list); \
00195          (cursor) = (cursor2), (cursor2) = (cursor)->next)
00196 
00197 /* iterate through the list using a list entry */
00198 #define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
00199     for ((elem) = LIST_ENTRY((list)->next, type, field); \
00200          &(elem)->field != (list); \
00201          (elem) = LIST_ENTRY((elem)->field.next, type, field))
00202 
00203 /* iterate through the list using a list entry, with safety against removal */
00204 #define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
00205     for ((cursor) = LIST_ENTRY((list)->next, type, field), \
00206          (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
00207          &(cursor)->field != (list); \
00208          (cursor) = (cursor2), \
00209          (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
00210 
00211 /* iterate through the list in reverse order */
00212 #define LIST_FOR_EACH_REV(cursor,list) \
00213     for ((cursor) = (list)->prev; (cursor) != (list); (cursor) = (cursor)->prev)
00214 
00215 /* iterate through the list in reverse order, with safety against removal */
00216 #define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
00217     for ((cursor) = (list)->prev, (cursor2) = (cursor)->prev; \
00218          (cursor) != (list); \
00219          (cursor) = (cursor2), (cursor2) = (cursor)->prev)
00220 
00221 /* iterate through the list in reverse order using a list entry */
00222 #define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
00223     for ((elem) = LIST_ENTRY((list)->prev, type, field); \
00224          &(elem)->field != (list); \
00225          (elem) = LIST_ENTRY((elem)->field.prev, type, field))
00226 
00227 /* iterate through the list in reverse order using a list entry, with safety against removal */
00228 #define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
00229     for ((cursor) = LIST_ENTRY((list)->prev, type, field), \
00230          (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field); \
00231          &(cursor)->field != (list); \
00232          (cursor) = (cursor2), \
00233          (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field))
00234 
00235 /* macros for statically initialized lists */
00236 #define LIST_INIT(list)  { &(list), &(list) }
00237 
00238 /* get pointer to object containing list element */
00239 #ifdef _WIN64
00240 #define LIST_ENTRY(elem, type, field) \
00241     ((type *)((char *)(elem) - (unsigned long long)(&((type *)0)->field)))
00242 #else
00243 #define LIST_ENTRY(elem, type, field) \
00244     ((type *)((char *)(elem) - (unsigned long)(&((type *)0)->field)))
00245 #endif
00246 
00247 #endif  /* __WINE_SERVER_LIST_H */

Generated on Sun May 27 2012 04:27:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.