RList
|
00001 /* 00002 * Copyright (c) 2011, Stefan Götz <stefan.goetz@web.de> 00003 * 00004 * Permission to use, copy, modify, and/or distribute this software for any 00005 * purpose with or without fee is hereby granted, provided that the above 00006 * copyright notice and this permission notice appear in all copies. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 00009 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00010 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 00011 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00012 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00013 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00014 * PERFORMANCE OF THIS SOFTWARE. 00015 */ 00016 00105 #ifndef RLIST_SINGLE_H 00106 #define RLIST_SINGLE_H 00107 00108 #include <stddef.h> 00109 #include <stdbool.h> 00110 #include <assert.h> 00111 00112 #include "rlist/platform.h" 00113 #include "rlist/common.h" 00114 00115 C_DECLARATIONS_START 00116 00125 #define SRL_INIT { 0, NULL, NULL } 00126 00137 #define SRL_INIT_WITH(free_fn) { 0, free_fn, NULL } 00138 00146 struct srl_node_ { 00147 /* The payload data provided by the user */ 00148 void *payload; 00149 /* The next node in the list. 00150 * If next is NULL, this node is the last node in the list. */ 00151 struct srl_node_ *next; 00152 }; 00153 00164 struct srl_list { 00170 unsigned int node_count; 00177 rl_free_fn free_fn; 00183 struct srl_node_ *head; 00184 }; 00185 00215 struct srl_iterator { 00222 struct srl_list *list; 00227 struct srl_node_ *node; 00232 struct srl_node_ *prev; 00233 }; 00234 00250 typedef int (*srl_map_fn)(struct srl_iterator *const iter, 00251 void *const context); 00252 00253 /* The following functions are required by some inline functions here in the 00254 * header file. 00255 * Since they are only called from assert(), i.e. not present in production code, the performance impact of not inlining them, too, can be ignored. */ 00264 bool srl_check_list_ ARGS((const struct srl_list *const list)); 00265 00276 bool srl_check_iter_in_list_ ARGS((const struct srl_iterator *const iter)); 00277 00288 bool srl_check_iter_post_delete_ ARGS((const struct srl_iterator *const iter)); 00289 00300 bool srl_check_iter_end_of_list_ ARGS((const struct srl_iterator *const iter)); 00301 00312 bool srl_check_iter_in_list_or_end_of_list_ ARGS((const struct srl_iterator *const iter)); 00313 00324 static inline void *srl_payload(const struct srl_iterator *const iter) 00325 { 00326 assert(srl_check_iter_in_list_(iter)); 00327 return iter->node->payload; 00328 } 00329 00344 static inline void srl_init(struct srl_list *const list, 00345 rl_free_fn free_fn) 00346 { 00347 assert(list); 00348 *list = (struct srl_list) SRL_INIT_WITH(free_fn); 00349 assert(srl_check_list_(list)); 00350 } 00351 00361 static inline unsigned int srl_size(const struct srl_list *const list) 00362 { 00363 assert(srl_check_list_(list)); 00364 return list->node_count; 00365 } 00366 00380 static inline struct srl_iterator *srl_first(struct srl_list *const list, 00381 struct srl_iterator *const iter) 00382 { 00383 assert(srl_check_list_(list)); 00384 assert(iter); 00385 00386 iter->list = list; 00387 iter->node = list->head; 00388 iter->prev = NULL; 00389 00390 if (list->head) { 00391 assert(srl_check_iter_in_list_(iter)); 00392 } else { 00393 assert(srl_check_iter_end_of_list_(iter)); 00394 } 00395 00396 return iter; 00397 } 00398 00415 struct srl_iterator *srl_next ARGS((struct srl_iterator *const iter)); 00416 00430 static inline bool srl_is_eol(const struct srl_iterator *const iter) 00431 { 00432 return !iter->node; 00433 } 00434 00453 bool srl_insert_before ARGS((struct srl_iterator *const iter, 00454 void *const payload)); 00455 00478 void *srl_del ARGS((struct srl_iterator *const iter)); 00479 00490 void srl_del_all ARGS((struct srl_list *const list)); 00491 00513 struct srl_iterator *srl_find ARGS((struct srl_iterator *const iter, 00514 rl_match_fn match_fn, 00515 void *const match_context)); 00516 00534 struct srl_iterator *srl_find_payload ARGS((struct srl_iterator *const iter, 00535 void *const payload)); 00536 00564 int srl_map ARGS((struct srl_iterator *const iter, 00565 srl_map_fn map_fn, 00566 void *const map_context, 00567 rl_match_fn match_fn, 00568 void *const match_context)); 00569 00570 C_DECLARATIONS_END 00571 00572 #endif /* RLIST_SINGLE_H */