Mercurial > MadButterfly
comparison include/mb_tools.h @ 186:530bb7728546 include_mb_test
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
This is the solution that I dicussed with FourDollars, last night.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 05 Nov 2008 15:24:01 +0800 |
parents | include/mb/tools.h@c7e5b8779bb5 |
children | 65cabbdd5284 |
comparison
equal
deleted
inserted
replaced
185:c7e5b8779bb5 | 186:530bb7728546 |
---|---|
1 #ifndef __TOOLS_H_ | |
2 #define __TOOLS_H_ | |
3 | |
4 typedef struct _elmpool elmpool_t; | |
5 | |
6 extern elmpool_t *elmpool_new(int elm_sz, int inc_num); | |
7 extern void *elmpool_elm_alloc(elmpool_t *pool); | |
8 extern void elmpool_elm_free(elmpool_t *pool, void *elm); | |
9 extern void elmpool_free(elmpool_t *pool); | |
10 | |
11 | |
12 #define STAILQ(type) \ | |
13 struct { \ | |
14 type *head; \ | |
15 type *tail; \ | |
16 } | |
17 #define STAILQ_INIT(q) \ | |
18 do { \ | |
19 (q).head = (q).tail = NULL; \ | |
20 } while(0) | |
21 #define STAILQ_CLEAN(q) STAILQ_INIT(q) | |
22 #define STAILQ_HEAD(q) ((q).head) | |
23 #define STAILQ_TAIL(q) ((q).tail) | |
24 #define STAILQ_NEXT(type, field, elm) ((elm)->field) | |
25 #define STAILQ_INS(q, type, field, elm) \ | |
26 do { \ | |
27 (elm)->field = (q).head; \ | |
28 (q).head = elm; \ | |
29 if((q).tail == NULL) \ | |
30 (q).tail = elm; \ | |
31 } while(0) | |
32 #define STAILQ_INS_TAIL(q, type, field, elm) \ | |
33 do { \ | |
34 (elm)->field = NULL; \ | |
35 if((q).tail != NULL) \ | |
36 (q).tail->field = elm; \ | |
37 (q).tail = elm; \ | |
38 if((q).head == NULL) \ | |
39 (q).head = elm; \ | |
40 } while(0) | |
41 #define STAILQ_INS_AFTER(type, field, follow, elm) \ | |
42 do { \ | |
43 (follow)->field = (elm)->field; \ | |
44 (elm)->field = follow; \ | |
45 } while(0) | |
46 #define STAILQ_REMOVE(q, type, field, elm) \ | |
47 do { \ | |
48 if((elm) == (q).head) { \ | |
49 (q).head = (elm)->field; \ | |
50 if((q).head == NULL) \ | |
51 (q).tail = NULL; \ | |
52 } else { \ | |
53 type *_stailq_cur = (q).head; \ | |
54 while(_stailq_cur != NULL && \ | |
55 _stailq_cur->field != (elm)) \ | |
56 _stailq_cur = _stailq_cur->field; \ | |
57 if(_stailq_cur != NULL) { \ | |
58 _stailq_cur->field = (elm)->field; \ | |
59 if((q).tail == (elm)) \ | |
60 (q).tail = _stailq_cur; \ | |
61 } \ | |
62 } \ | |
63 } while(0) | |
64 | |
65 /*! \defgroup darray Dynamic Array | |
66 * | |
67 * DARRAY is a dynamic sized array/list, it's length is a variable. | |
68 * It is extended, automatically, if it is full and more elemnts are | |
69 * putted in. | |
70 * | |
71 * Users of DARRAY must declare a new type to store data. The way to | |
72 * declear a new type is to invoke DARRAY() with paramters of name of | |
73 * type and type of data to be stored in. The new storage type is named | |
74 * with foo_t where foo is the name you pass in. | |
75 * | |
76 * DARRAY_DEFINE() is inovked to define foo_add() function; foo is name | |
77 * of storage type. You can call foo_add() to add a data element | |
78 * into a storage object. | |
79 * | |
80 * Get ith element in a storage object, use | |
81 * \code | |
82 * obj->ds[i] | |
83 * \endcode | |
84 * | |
85 * To loop over elements in a storage object, us | |
86 * \code | |
87 * for(i = 0; i < obj->num; i++) { | |
88 * v = obj->ds[i]; | |
89 * ...... | |
90 * } | |
91 * \endcode | |
92 * @{ | |
93 */ | |
94 /*! \brief Declare a DARRAY storage type. | |
95 * | |
96 * \param name is name of storage type. | |
97 * \param type is type of data elements that will be stored in. | |
98 * | |
99 * Type of <name>_t is defined by the macro. It is used to define a | |
100 * storage object to contain data elements. | |
101 */ | |
102 #define DARRAY(name, type) \ | |
103 struct _ ## name { \ | |
104 int max, num; \ | |
105 type *ds; \ | |
106 }; \ | |
107 typedef struct _ ## name name ## _t | |
108 #define DARRAY_DEFINE(name, type) \ | |
109 static int name ## _add(name ## _t *da, type v) { \ | |
110 type *new_ds; \ | |
111 int max; \ | |
112 if(da->num >= (da)->max) { \ | |
113 max = (da)->max + 32; \ | |
114 new_ds = realloc(da->ds, \ | |
115 max * sizeof(type)); \ | |
116 if(new_ds == NULL) return -1; \ | |
117 da->ds = new_ds; \ | |
118 da->max = max; \ | |
119 } \ | |
120 da->ds[da->num++] = v; \ | |
121 return 0; \ | |
122 } | |
123 #define DARRAY_CLEAN(da) do { (da)->num = 0; } while(0) | |
124 #define DARRAY_INIT(da) do { (da)->num = (da)->max = 0; (da)->ds = NULL; } | |
125 #define DARRAY_DESTROY(da) do { if((da)->ds) free((da)->ds); } while(0) | |
126 /* @} */ | |
127 | |
128 #include <stdlib.h> | |
129 | |
130 #define O_ALLOC(type) ((type *)malloc(sizeof(type))) | |
131 | |
132 #define OFFSET(type, mem) (((void *)&((type *)NULL)->mem) - NULL) | |
133 #define MEM2OBJ(var, type, mem) ((type *)((void *)var - OFFSET(type, mem))) | |
134 #define OFF2TYPE(obj, off, type) (*(type *)((void *)(obj) + (off))) | |
135 | |
136 #endif /* __TOOLS_H_ */ |