1 #ifndef R2_LIST_H
2 #define R2_LIST_H
3 
4 #include <r_types.h>
5 #include <r_flist.h>
6 #include <sdb.h>
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #ifndef _INCLUDE_R_LIST_HEAD_H_
12 #define _INCLUDE_R_LIST_HEAD_H_
13 typedef void (*RListFree)(void *ptr);
14 
15 typedef struct r_list_iter_t {
16 	void *data;
17 	struct r_list_iter_t *n, *p;
18 } RListIter;
19 
20 typedef struct r_list_t {
21 	RListIter *head;
22 	RListIter *tail;
23 	RListFree free;
24 	int length;
25 	bool sorted;
26 } RList;
27 
28 typedef struct r_list_range_t {
29 	HtPP *h;
30 	RList *l;
31 } RListRange;
32 
33 // RListComparator should return -1, 0, 1 to indicate "a<b", "a==b", "a>b".
34 typedef int (*RListComparator)(const void *a, const void *b);
35 
36 #define ROFList_Parent RList
37 typedef struct r_oflist_t {
38 	ROFList_Parent super; // super class
39 	RFList *array;	// statical readonly cache of linked list as a pointer array
40 } ROFList;
41 #endif
42 
43 #ifdef R_API
44 #define r_list_foreach(list, it, pos)\
45 	if (list)\
46 		for (it = list->head; it && (pos = it->data, 1); it = it->n)
47 #define r_list_foreach_iter(list, it)\
48 	if (list)\
49 		for (it = list->head; it; it = it->n)
50 /* Safe when calling r_list_delete() while iterating over the list. */
51 #define r_list_foreach_safe(list, it, tmp, pos)\
52 	if (list)\
53 		for (it = list->head; it && (pos = it->data, tmp = it->n, 1); it = tmp)
54 #define r_list_foreach_prev(list, it, pos)\
55 	if (list)\
56 		for (it = list->tail; it && (pos = it->data, 1); it = it->p)
57 #define r_list_foreach_prev_safe(list, it, tmp, pos) \
58 	for (it = list->tail; it && (pos = it->data, tmp = it->p, 1); it = tmp)
59 #ifndef _R_LIST_C_
60 #define r_list_push(x, y) r_list_append ((x), (y))
61 #define r_list_iterator(x) (x)? (x)->head: NULL
62 // #define r_list_empty(x) (!x || (!(x->head) && !(x->tail)))
63 #define r_list_empty(x) (!(x) || !(x)->length)
64 #define r_list_head(x) ((x)? (x)->head: NULL)
65 #define r_list_tail(x) ((x)? (x)->tail: NULL)
66 
67 #define r_list_iter_get(x) (x)->data; (x)=(x)->n
68 #define r_list_iter_next(x) ((x)? 1: 0)
69 
70 #define r_list_iter_cur(x) (x)->p
71 #define r_list_iter_free(x) (x)
72 #endif
73 R_API RList *r_list_new(void);
74 R_API RList *r_list_newf(RListFree f);
75 R_API RListIter *r_list_iter_get_next(RListIter *list);
76 R_API int r_list_set_n(RList *list, int n, void *p);
77 R_API void *r_list_iter_get_data(RListIter *list);
78 R_API RListIter *r_list_append(RList *list, void *data);
79 R_API RListIter *r_list_prepend(RList *list, void *data);
80 R_API RListIter *r_list_insert(RList *list, int n, void *data);
81 R_API int r_list_length(const RList *list);
82 R_API void *r_list_first(const RList *list);
83 R_API void *r_list_last(const RList *list);
84 R_API RListIter *r_list_add_sorted(RList *list, void *data, RListComparator cmp);
85 R_API void r_list_sort(RList *list, RListComparator cmp);
86 R_API void r_list_merge_sort(RList *list, RListComparator cmp);
87 R_API void r_list_insertion_sort(RList *list, RListComparator cmp);
88 R_API RList *r_list_uniq(const RList *list, RListComparator cmp);
89 R_API void r_list_init(RList *list);
90 R_API void r_list_delete(RList *list, RListIter *iter);
91 R_API bool r_list_delete_data(RList *list, void *ptr);
92 R_API void r_list_iter_init(RListIter *iter, RList *list);
93 R_API void r_list_purge(RList *list);
94 R_API void r_list_free(RList *list);
95 R_API RListIter *r_list_item_new(void *data);
96 R_API void r_list_split(RList *list, void *ptr);
97 R_API void r_list_split_iter(RList *list, RListIter *iter);
98 R_API int r_list_join(RList *list1, RList *list2);
99 R_API void *r_list_get_n(const RList *list, int n);
100 R_API int r_list_del_n(RList *list, int n);
101 R_API void *r_list_get_top(const RList *list);
102 R_API void *r_list_get_bottom(const RList *list);
103 R_API void *r_list_pop(RList *list);
104 R_API void *r_list_pop_head(RList *list);
105 R_API void r_list_reverse(RList *list);
106 R_API RList *r_list_clone(const RList *list);
107 R_API char *r_list_to_str(RList *list, char ch);
108 
109 /* hashlike api */
110 R_API RListIter *r_list_contains(const RList *list, const void *p);
111 R_API RListIter *r_list_find(const RList *list, const void *p, RListComparator cmp);
112 
113 /* rlistflist */
114 // TODO: rename to init or so.. #define r_oflist_new() R_NEW(ROFList);memset
115 #define r_oflist_length(x, y) r_list_length (x, y)
116 #define r_oflist_destroy(x) r_oflist_deserialize (x)
117 #define r_oflist_free(x) r_oflist_deserialize (x), r_list_free (x)
118 #define r_oflist_append(x, y) r_oflist_deserialize (x), r_list_append (x, y)
119 #define r_oflist_prepend(x, y) r_oflist_deserialize (x), r_list_prepend (x, y)
120 #define r_oflist_delete(x, y) r_oflist_deserialize (x), r_list_delete (x, y)
121 #define r_oflist_array(x) x->array? x->array: (x->array = r_oflist_serialize (x)), x->array
122 #define r_oflist_deserialize(x)\
123 	free (x->array - 1), x->array = 0
124 #define r_oflist_serialize(x)\
125 	x->array = r_flist_new (r_list_length (x)), { \
126 		int idx = 0;\
127 		void *ptr;\
128 		RListIter *iter;\
129 		r_list_foreach (x, iter, ptr) r_flist_set (x->array, idx++, ptr);\
130 	}\
131 	x->array;
132 #endif
133 
134 #ifdef __cplusplus
135 }
136 #endif
137 
138 #endif
139