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