1 /*
2  *      fm-list.h
3  *      A generic list container supporting reference counting.
4  *      Copyright 2009 PCMan <pcman.tw@gmail.com>
5  *      Copyright 2012 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
6  *
7  *      This file is a part of the Libfm library.
8  *
9  *      This library is free software; you can redistribute it and/or
10  *      modify it under the terms of the GNU Lesser General Public
11  *      License as published by the Free Software Foundation; either
12  *      version 2.1 of the License, or (at your option) any later version.
13  *
14  *      This library is distributed in the hope that it will be useful,
15  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *      Lesser General Public License for more details.
18  *
19  *      You should have received a copy of the GNU Lesser General Public
20  *      License along with this library; if not, write to the Free Software
21  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 
25 #ifndef __FM_LIST_H__
26 #define __FM_LIST_H__
27 
28 #include <glib.h>
29 
30 G_BEGIN_DECLS
31 
32 typedef struct _FmList			FmList;
33 typedef struct _FmListFuncs		FmListFuncs;
34 
35 struct _FmList
36 {
37     /*< private >*/
38     GQueue list;
39     FmListFuncs* funcs;
40     gint n_ref;
41 };
42 
43 /**
44  * FmListFuncs:
45  * @item_ref: function to increase reference counter on item
46  * @item_unref: function to decrease reference counter on item
47  */
48 struct _FmListFuncs
49 {
50     gpointer (*item_ref)(gpointer item);
51     void (*item_unref)(gpointer item);
52 };
53 
54 FmList* fm_list_new(FmListFuncs* funcs);
55 
56 FmList* fm_list_ref(FmList* list);
57 void fm_list_unref(FmList* list);
58 
59 #define FM_LIST(list)	((FmList*)list)
60 
61 /* Since FmList is actually a GQueue with reference counting,
62  * all APIs for GQueue should be usable */
63 
64 void fm_list_clear(FmList* list);
65 #ifndef __GTK_DOC_IGNORE__
fm_list_is_empty(FmList * list)66 static inline gboolean fm_list_is_empty(FmList* list)
67 {
68     return g_queue_is_empty((GQueue*)list);
69 }
fm_list_get_length(FmList * list)70 static inline guint fm_list_get_length(FmList* list)
71 {
72     return g_queue_get_length((GQueue*)list);
73 }
74 
fm_list_reverse(FmList * list)75 static inline void fm_list_reverse(FmList* list)
76 {
77     g_queue_reverse((GQueue*)list);
78 }
fm_list_foreach(FmList * list,GFunc f,gpointer d)79 static inline void fm_list_foreach(FmList* list, GFunc f, gpointer d)
80 {
81     g_queue_foreach((GQueue*)list,f,d);
82 }
fm_list_find(FmList * list,gpointer d)83 static inline GList* fm_list_find(FmList* list, gpointer d)
84 {
85     return g_queue_find((GQueue*)list,d);
86 }
fm_list_find_custom(FmList * list,gconstpointer d,GCompareFunc f)87 static inline GList* fm_list_find_custom(FmList* list, gconstpointer d, GCompareFunc f)
88 {
89     return g_queue_find_custom((GQueue*)list,d,f);
90 }
fm_list_sort(FmList * list,GCompareDataFunc f,gpointer d)91 static inline void fm_list_sort(FmList* list, GCompareDataFunc f, gpointer d)
92 {
93     g_queue_sort((GQueue*)list,f,d);
94 }
95 
fm_list_push_head(FmList * list,gpointer d)96 static inline void fm_list_push_head(FmList* list, gpointer d)
97 {
98     g_queue_push_head((GQueue*)list,(list)->funcs->item_ref(d));
99 }
fm_list_push_tail(FmList * list,gpointer d)100 static inline void fm_list_push_tail(FmList* list, gpointer d)
101 {
102     g_queue_push_tail((GQueue*)list,(list)->funcs->item_ref(d));
103 }
fm_list_push_nth(FmList * list,gpointer d,guint n)104 static inline void fm_list_push_nth(FmList* list, gpointer d, guint n)
105 {
106     g_queue_push_nth((GQueue*)list,(list)->funcs->item_ref(d),n);
107 }
108 
fm_list_push_head_noref(FmList * list,gpointer d)109 static inline void fm_list_push_head_noref(FmList* list, gpointer d)
110 {
111     g_queue_push_head((GQueue*)list,d);
112 }
fm_list_push_tail_noref(FmList * list,gpointer d)113 static inline void fm_list_push_tail_noref(FmList* list, gpointer d)
114 {
115     g_queue_push_tail((GQueue*)list,d);
116 }
fm_list_push_nth_noref(FmList * list,gpointer d,guint n)117 static inline void fm_list_push_nth_noref(FmList* list, gpointer d, guint n)
118 {
119     g_queue_push_nth((GQueue*)list,d,n);
120 }
121 
fm_list_pop_head(FmList * list)122 static inline gpointer fm_list_pop_head(FmList* list)
123 {
124     return g_queue_pop_head((GQueue*)list);
125 }
fm_list_pop_tail(FmList * list)126 static inline gpointer fm_list_pop_tail(FmList* list)
127 {
128     return g_queue_pop_tail((GQueue*)list);
129 }
fm_list_pop_nth(FmList * list,guint n)130 static inline gpointer fm_list_pop_nth(FmList* list, guint n)
131 {
132     return g_queue_pop_nth((GQueue*)list,n);
133 }
134 
fm_list_peek_head(FmList * list)135 static inline gpointer fm_list_peek_head(FmList* list)
136 {
137     return g_queue_peek_head((GQueue*)list);
138 }
fm_list_peek_tail(FmList * list)139 static inline gpointer fm_list_peek_tail(FmList* list)
140 {
141     return g_queue_peek_tail((GQueue*)list);
142 }
fm_list_peek_nth(FmList * list,guint n)143 static inline gpointer fm_list_peek_nth(FmList* list, guint n)
144 {
145     return g_queue_peek_nth((GQueue*)list,n);
146 }
147 
fm_list_index(FmList * list,gconstpointer d)148 static inline gint fm_list_index(FmList* list, gconstpointer d)
149 {
150     return g_queue_index((GQueue*)list,d);
151 }
152 #endif /* __GTK_DOC_IGNORE__ */
153 
154 void fm_list_remove(FmList* list, gpointer data);
155 void fm_list_remove_all(FmList* list, gpointer data);
156 #ifndef __GTK_DOC_IGNORE__
fm_list_insert_before(FmList * list,GList * s,gpointer d)157 static inline void fm_list_insert_before(FmList* list, GList* s, gpointer d)
158 {
159     g_queue_insert_before((GQueue*)list,s,(list)->funcs->item_ref(d));
160 }
fm_list_insert_after(FmList * list,GList * s,gpointer d)161 static inline void fm_list_insert_after(FmList* list, GList* s, gpointer d)
162 {
163     g_queue_insert_after((GQueue*)list,s,(list)->funcs->item_ref(d));
164 }
fm_list_insert_sorted(FmList * list,gpointer d,GCompareDataFunc f,gpointer u)165 static inline void fm_list_insert_sorted(FmList* list, gpointer d, GCompareDataFunc f, gpointer u)
166 {
167     g_queue_insert_sorted((GQueue*)list,(list)->funcs->item_ref(d),f,u);
168 }
169 
fm_list_insert_before_noref(FmList * list,GList * s,gpointer d)170 static inline void fm_list_insert_before_noref(FmList* list, GList* s, gpointer d)
171 {
172     g_queue_insert_before((GQueue*)list,s,d);
173 }
fm_list_insert_after_noref(FmList * list,GList * s,gpointer d)174 static inline void fm_list_insert_after_noref(FmList* list, GList* s, gpointer d)
175 {
176     g_queue_insert_after((GQueue*)list,s,d);
177 }
fm_list_insert_sorted_noref(FmList * list,gpointer d,GCompareDataFunc f,gpointer u)178 static inline void fm_list_insert_sorted_noref(FmList* list, gpointer d, GCompareDataFunc f, gpointer u)
179 {
180     g_queue_insert_sorted((GQueue*)list,d,f,u);
181 }
182 
fm_list_push_head_link(FmList * list,GList * l_)183 static inline void fm_list_push_head_link(FmList* list, GList* l_)
184 {
185     g_queue_push_head_link((GQueue*)list,l_);
186 }
fm_list_push_tail_link(FmList * list,GList * l_)187 static inline void fm_list_push_tail_link(FmList* list, GList* l_)
188 {
189     g_queue_push_tail_link((GQueue*)list,l_);
190 }
fm_list_push_nth_link(FmList * list,guint n,GList * l_)191 static inline void fm_list_push_nth_link(FmList* list, guint n, GList* l_)
192 {
193     g_queue_push_nth_link((GQueue*)list,n,l_);
194 }
195 
fm_list_pop_head_link(FmList * list)196 static inline GList* fm_list_pop_head_link(FmList* list)
197 {
198     return g_queue_pop_head_link((GQueue*)list);
199 }
fm_list_pop_tail_link(FmList * list)200 static inline GList* fm_list_pop_tail_link(FmList* list)
201 {
202     return g_queue_pop_tail_link((GQueue*)list);
203 }
fm_list_pop_nth_link(FmList * list,guint n)204 static inline GList* fm_list_pop_nth_link(FmList* list, guint n)
205 {
206     return g_queue_pop_nth_link((GQueue*)list,n);
207 }
208 
fm_list_peek_head_link(FmList * list)209 static inline GList* fm_list_peek_head_link(FmList* list)
210 {
211     return g_queue_peek_head_link((GQueue*)list);
212 }
fm_list_peek_tail_link(FmList * list)213 static inline GList* fm_list_peek_tail_link(FmList* list)
214 {
215     return g_queue_peek_tail_link((GQueue*)list);
216 }
fm_list_peek_nth_link(FmList * list,guint n)217 static inline GList* fm_list_peek_nth_link(FmList* list, guint n)
218 {
219     return g_queue_peek_nth_link((GQueue*)list,n);
220 }
221 
fm_list_link_index(FmList * list,GList * l_)222 static inline gint fm_list_link_index(FmList* list, GList* l_)
223 {
224     return g_queue_index((GQueue*)list,l_);
225 }
fm_list_unlink(FmList * list,GList * l_)226 static inline void fm_list_unlink(FmList* list, GList* l_)
227 {
228     g_queue_unlink((GQueue*)list,l_);
229 }
fm_list_delete_link_nounref(FmList * list,GList * l_)230 static inline void fm_list_delete_link_nounref(FmList* list, GList* l_)
231 {
232     g_queue_delete_link((GQueue*)list,l_);
233 }
234 #endif /* __GTK_DOC_IGNORE__ */
235 void fm_list_delete_link(FmList* list, GList* l_);
236 
237 G_END_DECLS
238 
239 #endif /* __FM_LIST_H__ */
240