1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs         : $Id$
5  begin       : Sat Jun 28 2003
6  copyright   : (C) 2003 by Martin Preuss
7  email       : martin@libchipcard.de
8 
9  ***************************************************************************
10  *                                                                         *
11  *   This library is free software; you can redistribute it and/or         *
12  *   modify it under the terms of the GNU Lesser General Public            *
13  *   License as published by the Free Software Foundation; either          *
14  *   version 2.1 of the License, or (at your option) any later version.    *
15  *                                                                         *
16  *   This library is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
19  *   Lesser General Public License for more details.                       *
20  *                                                                         *
21  *   You should have received a copy of the GNU Lesser General Public      *
22  *   License along with this library; if not, write to the Free Software   *
23  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
24  *   MA  02111-1307  USA                                                   *
25  *                                                                         *
26  ***************************************************************************/
27 
28 /** @file list2.h
29  *
30  * @short This file contains some macros concerning lists.
31  *
32  */
33 
34 
35 #ifndef GWENHYWFAR_LIST2_H
36 #define GWENHYWFAR_LIST2_H
37 
38 #include <gwenhywfar/gwenhywfarapi.h>
39 #include <gwenhywfar/types.h>
40 #include <gwenhywfar/misc.h>
41 #include <gwenhywfar/list.h>
42 #include <gwenhywfar/refptr.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <assert.h>
47 
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
51 
52 /*
53  * This macro should be used in libraries with the
54  * __declspec(dllexport) declaration as the @c decl argument.
55  */
56 #define GWEN_LIST2_FUNCTION_LIB_DEFS(t, pr, decl) \
57   typedef struct t##_LIST2 t##_LIST2; \
58   typedef struct t##_LIST2_ITERATOR t##_LIST2_ITERATOR; \
59   typedef t* (t##_LIST2_FOREACH)(t *element, void *user_data); \
60   \
61   decl t##_LIST2 *pr##_List2_new(void); \
62   decl void pr##_List2_free(t##_LIST2 *l); \
63   decl t##_LIST2 *pr##_List2_dup(const t##_LIST2 *l); \
64   decl void pr##_List2_Unshare(t##_LIST2 *l); \
65   decl void pr##_List2_Dump(t##_LIST2 *l, FILE *f, unsigned int indent); \
66   decl void pr##_List2_PushBack(t##_LIST2 *l, t *p); \
67   decl void pr##_List2_PushFront(t##_LIST2 *l, t *p); \
68   decl t *pr##_List2_GetFront(const t##_LIST2 *l); \
69   decl t *pr##_List2_GetBack(const t##_LIST2 *l); \
70   decl void pr##_List2_Erase(t##_LIST2 *l, t##_LIST2_ITERATOR *it); \
71   decl void pr##_List2_Remove(t##_LIST2 *l, const t *p); \
72   decl unsigned int pr##_List2_GetSize(const t##_LIST2 *l); \
73   decl int pr##_List2_IsEmpty(const t##_LIST2 *l); \
74   decl void pr##_List2_PopBack(t##_LIST2 *l); \
75   decl void pr##_List2_PopFront(t##_LIST2 *l); \
76   decl void pr##_List2_Clear(t##_LIST2 *l); \
77   decl t##_LIST2_ITERATOR *pr##_List2_First(const t##_LIST2 *l); \
78   decl t##_LIST2_ITERATOR *pr##_List2_Last(const t##_LIST2 *l); \
79   decl t##_LIST2_ITERATOR *pr##_List2Iterator_new(t##_LIST2 *l); \
80   decl void pr##_List2Iterator_free(t##_LIST2_ITERATOR *li); \
81   decl t *pr##_List2Iterator_Previous(t##_LIST2_ITERATOR *li); \
82   decl t *pr##_List2Iterator_Next(t##_LIST2_ITERATOR *li); \
83   decl t *pr##_List2Iterator_Data(t##_LIST2_ITERATOR *li); \
84   decl void pr##_List2Iterator_IncLinkCount(t##_LIST2_ITERATOR *li); \
85   decl unsigned int pr##_List2Iterator_GetLinkCount(const t##_LIST2_ITERATOR *li); \
86   decl t##_LIST2_ITERATOR *pr##_List2_FindIter(t##_LIST2 *l, const t *p); \
87   decl const t *pr##_List2_Contains(t##_LIST2 *l, const t *p); \
88   decl t *pr##_List2_ForEach(t##_LIST2 *l, t##_LIST2_FOREACH, void *user_data);
89 
90 /** This macro should be used in applications, not in libraries. In
91  * libraries please use the macro @ref GWEN_LIST2_FUNCTION_LIB_DEFS. */
92 #define GWEN_LIST2_FUNCTION_DEFS(t, pr) \
93   GWEN_LIST2_FUNCTION_LIB_DEFS(t, pr, GWEN_DUMMY_EMPTY_ARG)
94 
95 
96 /** This macro actually implements the functions. Please use it in your
97  * source file (*.c) after the includes.
98  */
99 #define GWEN_LIST2_FUNCTIONS(t, pr) \
100   t##_LIST2 *pr##_List2_new(void) { \
101     return (t##_LIST2*)GWEN_List_new(); \
102   } \
103   \
104   void pr##_List2_free(t##_LIST2 *l) { \
105     GWEN_List_free((GWEN_LIST*)l); \
106   } \
107   \
108   t##_LIST2 *pr##_List2_dup(const t##_LIST2 *l) {\
109     return (t##_LIST2*)GWEN_List_dup((const GWEN_LIST*)l); \
110   }\
111   \
112   void pr##_List2_Unshare(t##_LIST2 *l) { \
113     GWEN_List_Unshare((GWEN_LIST*)l); \
114   } \
115   \
116   void pr##_List2_Dump(t##_LIST2 *l, FILE *f, unsigned int indent) { \
117     GWEN_List_Dump((GWEN_LIST*) l, f, indent); \
118   } \
119   \
120   void pr##_List2_PushBack(t##_LIST2 *l, t *p) { \
121     GWEN_List_PushBack((GWEN_LIST*) l, p); \
122   } \
123   \
124   void pr##_List2_PushFront(t##_LIST2 *l, t *p) { \
125     GWEN_List_PushFront((GWEN_LIST*) l, p); \
126   } \
127   \
128   t *pr##_List2_GetFront(const t##_LIST2 *l) { \
129   return (t*) GWEN_List_GetFront((const GWEN_LIST*) l); \
130   }\
131   \
132   t *pr##_List2_GetBack(const t##_LIST2 *l) { \
133   return (t*) GWEN_List_GetBack((const GWEN_LIST*) l); \
134   } \
135   \
136   void pr##_List2_Erase(t##_LIST2 *l, t##_LIST2_ITERATOR *it) { \
137     GWEN_List_Erase((GWEN_LIST*) l, (GWEN_LIST_ITERATOR*) it); \
138   } \
139   \
140   void pr##_List2_Remove(t##_LIST2 *l, const t *p){ \
141     GWEN_List_Remove((GWEN_LIST*) l, p); \
142   } \
143   \
144   unsigned int pr##_List2_GetSize(const t##_LIST2 *l){ \
145     return GWEN_List_GetSize((const GWEN_LIST*) l); \
146   }\
147   \
148   int pr##_List2_IsEmpty(const t##_LIST2 *l){ \
149     return GWEN_List_IsEmpty((const GWEN_LIST*) l); \
150   }\
151   \
152   void pr##_List2_PopBack(t##_LIST2 *l){ \
153     GWEN_List_PopBack((GWEN_LIST*) l); \
154   }\
155   \
156   void pr##_List2_PopFront(t##_LIST2 *l){ \
157     GWEN_List_PopFront((GWEN_LIST*) l); \
158   }\
159   \
160   void pr##_List2_Clear(t##_LIST2 *l){ \
161     GWEN_List_Clear((GWEN_LIST*) l); \
162   }\
163   \
164   \
165   t##_LIST2_ITERATOR *pr##_List2_First(const t##_LIST2 *l) { \
166     return (t##_LIST2_ITERATOR*) GWEN_List_First((const GWEN_LIST*) l); \
167   }\
168   \
169   t##_LIST2_ITERATOR *pr##_List2_Last(const t##_LIST2 *l) { \
170     return (t##_LIST2_ITERATOR*) GWEN_List_Last((const GWEN_LIST*) l); \
171   }\
172   \
173   t##_LIST2_ITERATOR *pr##_List2Iterator_new(t##_LIST2 *l) { \
174     return (t##_LIST2_ITERATOR*) GWEN_ListIterator_new((GWEN_LIST*) l); \
175   }\
176   \
177   void pr##_List2Iterator_free(t##_LIST2_ITERATOR *li) {\
178     GWEN_ListIterator_free((GWEN_LIST_ITERATOR*)li); \
179   } \
180   \
181   t *pr##_List2Iterator_Previous(t##_LIST2_ITERATOR *li) { \
182     return (t*) GWEN_ListIterator_Previous((GWEN_LIST_ITERATOR*)li); \
183   }\
184   \
185   t *pr##_List2Iterator_Next(t##_LIST2_ITERATOR *li) { \
186     return (t*) GWEN_ListIterator_Next((GWEN_LIST_ITERATOR*)li); \
187   }\
188   \
189   t *pr##_List2Iterator_Data(t##_LIST2_ITERATOR *li) { \
190     return (t*) GWEN_ListIterator_Data((GWEN_LIST_ITERATOR*)li); \
191   } \
192   \
193   void pr##_List2Iterator_IncLinkCount(t##_LIST2_ITERATOR *li) { \
194     GWEN_ListIterator_IncLinkCount((GWEN_LIST_ITERATOR*)li); \
195   } \
196   \
197   unsigned int pr##_List2Iterator_GetLinkCount(const t##_LIST2_ITERATOR *li){\
198     return GWEN_ListIterator_GetLinkCount((const GWEN_LIST_ITERATOR*)li); \
199   } \
200   \
201   t##_LIST2_ITERATOR *pr##_List2_FindIter(t##_LIST2 *l, const t *p){ \
202     return (t##_LIST2_ITERATOR*) GWEN_List_FindIter((GWEN_LIST *)l, p); \
203   } \
204   \
205   const t *pr##_List2_Contains(t##_LIST2 *l, const t *p){ \
206     return (const t*) GWEN_List_Contains((GWEN_LIST*)l, p); \
207   } \
208   \
209   t *pr##_List2_ForEach(t##_LIST2 *l, t##_LIST2_FOREACH fn, void *user_data){ \
210     t##_LIST2_ITERATOR *it; \
211     t *el; \
212     if (!l) return 0; \
213     \
214     it=pr##_List2_First(l); \
215     if (!it) \
216       return 0; \
217     el=pr##_List2Iterator_Data(it); \
218     while(el) { \
219       el=fn(el, user_data); \
220       if (el) { \
221         pr##_List2Iterator_free(it); \
222         return el; \
223       } \
224       el=pr##_List2Iterator_Next(it); \
225       } \
226     pr##_List2Iterator_free(it); \
227     return 0; \
228   }
229 
230 /*
231  * This macro should be used in libraries with the
232  * __declspec(dllexport) declaration as the @c decl argument.
233  */
234 #define GWEN_CONSTLIST2_FUNCTION_LIB_DEFS(t, pr, decl) \
235   typedef struct t##_CONSTLIST2 t##_CONSTLIST2; \
236   typedef struct t##_CONSTLIST2_ITERATOR t##_CONSTLIST2_ITERATOR; \
237   typedef const t* (t##_CONSTLIST2_FOREACH)(const t *element, void *user_data); \
238   \
239   decl t##_CONSTLIST2 *pr##_ConstList2_new(void); \
240   decl void pr##_ConstList2_free(t##_CONSTLIST2 *l); \
241   decl void pr##_ConstList2_PushBack(t##_CONSTLIST2 *l, const t *p); \
242   decl void pr##_ConstList2_PushFront(t##_CONSTLIST2 *l, const t *p); \
243   decl const t *pr##_ConstList2_GetFront(const t##_CONSTLIST2 *l); \
244   decl const t *pr##_ConstList2_GetBack(const t##_CONSTLIST2 *l); \
245   decl unsigned int pr##_ConstList2_GetSize(const t##_CONSTLIST2 *l); \
246   decl int pr##_ConstList2_IsEmpty(const t##_CONSTLIST2 *l); \
247   decl void pr##_ConstList2_PopBack(t##_CONSTLIST2 *l); \
248   decl void pr##_ConstList2_PopFront(t##_CONSTLIST2 *l); \
249   decl void pr##_ConstList2_Clear(t##_CONSTLIST2 *l); \
250   decl t##_CONSTLIST2_ITERATOR *pr##_ConstList2_First(const t##_CONSTLIST2 *l); \
251   decl t##_CONSTLIST2_ITERATOR *pr##_ConstList2_Last(const t##_CONSTLIST2 *l); \
252   decl t##_CONSTLIST2_ITERATOR *pr##_ConstList2Iterator_new(t##_CONSTLIST2 *l); \
253   decl void pr##_ConstList2Iterator_free(t##_CONSTLIST2_ITERATOR *li); \
254   decl const t *pr##_ConstList2Iterator_Previous(t##_CONSTLIST2_ITERATOR *li); \
255   decl const t *pr##_ConstList2Iterator_Next(t##_CONSTLIST2_ITERATOR *li); \
256   decl const t *pr##_ConstList2Iterator_Data(t##_CONSTLIST2_ITERATOR *li); \
257   decl t##_CONSTLIST2_ITERATOR *pr##_ConstList2_FindIter(t##_CONSTLIST2 *l, const t *p); \
258   decl const t *pr##_ConstList2_Contains(t##_CONSTLIST2 *l, const t *p); \
259   decl void pr##_ConstList2_Remove(t##_CONSTLIST2 *l, const t *p); \
260   decl const t *pr##_ConstList2_ForEach(t##_CONSTLIST2 *l, t##_CONSTLIST2_FOREACH, void *user_data);
261 
262 /* This macro should be used in applications, not in libraries. In
263  * libraries please use the macro @ref
264  * GWEN_CONSTLIST2_FUNCTION_LIB_DEFS. */
265 #define GWEN_CONSTLIST2_FUNCTION_DEFS(t, pr) \
266   GWEN_CONSTLIST2_FUNCTION_LIB_DEFS(t, pr, GWEN_DUMMY_EMPTY_ARG)
267 
268 
269 #define GWEN_CONSTLIST2_FUNCTIONS(t, pr) \
270   t##_CONSTLIST2 *pr##_ConstList2_new(void) { \
271     return (t##_CONSTLIST2*)GWEN_ConstList_new(); \
272   } \
273   \
274   void pr##_ConstList2_free(t##_CONSTLIST2 *l) { \
275     GWEN_ConstList_free((GWEN_CONSTLIST*)l); \
276   } \
277   \
278   void pr##_ConstList2_PushBack(t##_CONSTLIST2 *l, const t *p) { \
279     GWEN_ConstList_PushBack((GWEN_CONSTLIST*) l, p); \
280   } \
281   \
282   void pr##_ConstList2_PushFront(t##_CONSTLIST2 *l, const t *p) { \
283     GWEN_ConstList_PushFront((GWEN_CONSTLIST*) l, p); \
284   } \
285   \
286   const t *pr##_ConstList2_GetFront(const t##_CONSTLIST2 *l) { \
287   return (t*) GWEN_ConstList_GetFront((const GWEN_CONSTLIST*) l); \
288   }\
289   \
290   const t *pr##_ConstList2_GetBack(const t##_CONSTLIST2 *l) { \
291   return (t*) GWEN_ConstList_GetBack((const GWEN_CONSTLIST*) l); \
292   } \
293   \
294   \
295   unsigned int pr##_ConstList2_GetSize(const t##_CONSTLIST2 *l){ \
296     return GWEN_ConstList_GetSize((const GWEN_CONSTLIST*) l); \
297   }\
298   \
299   int pr##_ConstList2_IsEmpty(const t##_CONSTLIST2 *l){ \
300     return GWEN_ConstList_IsEmpty((const GWEN_CONSTLIST*) l); \
301   }\
302   \
303   void pr##_ConstList2_PopBack(t##_CONSTLIST2 *l){ \
304     GWEN_ConstList_PopBack((GWEN_CONSTLIST*) l); \
305   }\
306   \
307   void pr##_ConstList2_PopFront(t##_CONSTLIST2 *l){ \
308     GWEN_ConstList_PopFront((GWEN_CONSTLIST*) l); \
309   }\
310   \
311   void pr##_ConstList2_Clear(t##_CONSTLIST2 *l){ \
312     GWEN_ConstList_Clear((GWEN_CONSTLIST*) l); \
313   }\
314   \
315   \
316   t##_CONSTLIST2_ITERATOR *pr##_ConstList2_First(const t##_CONSTLIST2 *l) { \
317     return (t##_CONSTLIST2_ITERATOR*) GWEN_ConstList_First((const GWEN_CONSTLIST*) l); \
318   }\
319   \
320   t##_CONSTLIST2_ITERATOR *pr##_ConstList2_Last(const t##_CONSTLIST2 *l) { \
321     return (t##_CONSTLIST2_ITERATOR*) GWEN_ConstList_Last((const GWEN_CONSTLIST*) l); \
322   }\
323   \
324   t##_CONSTLIST2_ITERATOR *pr##_ConstList2Iterator_new(t##_CONSTLIST2 *l) { \
325     return (t##_CONSTLIST2_ITERATOR*) GWEN_ConstListIterator_new((GWEN_CONSTLIST*) l); \
326   }\
327   \
328   void pr##_ConstList2Iterator_free(t##_CONSTLIST2_ITERATOR *li) {\
329     GWEN_ConstListIterator_free((GWEN_CONSTLIST_ITERATOR*)li); \
330   } \
331   \
332   const t *pr##_ConstList2Iterator_Previous(t##_CONSTLIST2_ITERATOR *li) { \
333     return (t*) GWEN_ConstListIterator_Previous((GWEN_CONSTLIST_ITERATOR*)li); \
334   }\
335   \
336   const t *pr##_ConstList2Iterator_Next(t##_CONSTLIST2_ITERATOR *li) { \
337     return (t*) GWEN_ConstListIterator_Next((GWEN_CONSTLIST_ITERATOR*)li); \
338   }\
339   \
340   const t *pr##_ConstList2Iterator_Data(t##_CONSTLIST2_ITERATOR *li) { \
341     return (t*) GWEN_ConstListIterator_Data((GWEN_CONSTLIST_ITERATOR*)li); \
342   } \
343   \
344   t##_CONSTLIST2_ITERATOR *pr##_ConstList2_FindIter(t##_CONSTLIST2 *l, const t *p){ \
345     return (t##_CONSTLIST2_ITERATOR*) GWEN_ConstList_FindIter((GWEN_CONSTLIST *)l, p); \
346   } \
347   \
348   const t *pr##_ConstList2_Contains(t##_CONSTLIST2 *l, const t *p){ \
349     return (const t*) GWEN_ConstList_Contains((GWEN_CONSTLIST*)l, p); \
350   } \
351   \
352   void pr##_ConstList2_Remove(t##_CONSTLIST2 *l, const t *p){ \
353     GWEN_ConstList_Remove((GWEN_CONSTLIST*) l, p); \
354   } \
355   \
356   const t *pr##_ConstList2_ForEach(t##_CONSTLIST2 *l, t##_CONSTLIST2_FOREACH fn, void *user_data){ \
357     t##_CONSTLIST2_ITERATOR *it; \
358     const t *el; \
359     if (!l) return 0; \
360     \
361     it=pr##_ConstList2_First(l); \
362     if (!it) \
363       return 0; \
364     el=pr##_ConstList2Iterator_Data(it); \
365     while(el) { \
366       el=fn(el, user_data); \
367       if (el) { \
368         pr##_ConstList2Iterator_free(it); \
369         return el; \
370       } \
371       el=pr##_ConstList2Iterator_Next(it); \
372       } \
373     pr##_ConstList2Iterator_free(it); \
374     return 0; \
375   }
376 
377 
378 #ifdef __cplusplus
379 }
380 #endif
381 
382 
383 #endif /* GWENHYWFAR_LIST2_H */
384 
385 
386 
387