3 /* Copyright (c) 2004 Arnaud Legrand. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
8 /* Warning, this module is done to be efficient and performs tons of
9 cast and dirty things. So avoid using it unless you really know
10 what you are doing. */
15 #include "xbt/sysdep.h"
16 #include "gras_config.h" /* inline */
18 /* This type should be added to a type that is to be used in such a swag */
19 /* Whenever a new object with this struct is created, all fields have
27 These typedefs are public so that the compiler can
28 do his job but believe me, you don't want to try to play with
29 those structs directly. Use them as an abstract datatype.
32 typedef struct xbt_swag_hookup {
35 } s_xbt_swag_hookup_t;
36 /**< This type should be added to a type that is to be used in a swag.
37 * For example like that :
41 s_xbt_swag_hookup_t set1_hookup;
42 s_xbt_swag_hookup_t set2_hookup;
52 set1 = xbt_swag_new(xbt_swag_offset(elem, set1_hookup));
53 set2 = xbt_swag_new(xbt_swag_offset(elem, set2_hookup));
58 typedef s_xbt_swag_hookup_t *xbt_swag_hookup_t;
61 typedef struct xbt_swag {
66 } s_xbt_swag_t, *xbt_swag_t;
67 /**< A typical swag */
70 xbt_swag_t xbt_swag_new(size_t offset);
71 void xbt_swag_free(xbt_swag_t swag);
72 void xbt_swag_init(xbt_swag_t swag, size_t offset);
73 void xbt_swag_insert(void *obj, xbt_swag_t swag);
74 void xbt_swag_insert_at_head(void *obj, xbt_swag_t swag);
75 void xbt_swag_insert_at_tail(void *obj, xbt_swag_t swag);
76 void *xbt_swag_remove(void *obj, xbt_swag_t swag);
77 void *xbt_swag_extract(xbt_swag_t swag);
78 int xbt_swag_size(xbt_swag_t swag);
79 int xbt_swag_belongs(void *obj, xbt_swag_t swag);
81 static inline void *xbt_swag_getFirst(xbt_swag_t swag)
86 #define xbt_swag_getNext(obj,offset) (((xbt_swag_hookup_t)(((char *) (obj)) + (offset)))->prev)
87 #define xbt_swag_getPrev(obj,offset) (((xbt_swag_hookup_t)(((char *) (obj)) + (offset)))->next)
91 * \brief Offset computation
92 * \arg var a variable of type <tt>struct</tt> something
93 * \arg field a field of <tt>struct</tt> something
94 * \return the offset of \a field in <tt>struct</tt> something.
96 * It is very similar to offsetof except that is done at runtime and that
97 * you have to declare a variable. Why defining such a macro then ?
98 * Because it is portable...
100 #define xbt_swag_offset(var,field) ((char *)&( (var).field ) - (char *)&(var))
106 * Iterates over the whole swag.
109 #define xbt_swag_foreach(obj,swag) \
110 for((obj)=xbt_swag_getFirst((swag)); \
112 (obj)=xbt_swag_getNext((obj),(swag)->offset))
113 /**< A simple swag iterator
114 * \param obj the indice of the loop
115 * \param swag what to iterate over
117 \warning you cannot modify the \a swag while using this loop */
118 #define xbt_swag_foreach_safe(obj,obj_next,swag) \
119 for((obj)=xbt_swag_getFirst((swag)), \
120 ((obj)?(obj_next=xbt_swag_getNext((obj),(swag)->offset)): \
124 ((obj)?(obj_next=xbt_swag_getNext((obj),(swag)->offset)): \
126 /**< A safe swag iterator
127 * \param obj the indice of the loop
128 * \param obj_next the object that is right after (if any) \a obj in the swag
129 * \param swag what to iterate over
131 You can safely modify the \a swag while using this loop.
132 Well, safely... Err. You can remove \a obj without having any
136 #endif /* _XBT_SWAG_H */