]> Pileus Git - ~andy/gtk/blob - glib/gslist.c
Initial revision
[~andy/gtk] / glib / gslist.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 #include "glib.h"
19
20
21 typedef struct _GRealListAllocator GRealListAllocator;
22
23 struct _GRealListAllocator
24 {
25   GMemChunk *list_mem_chunk;
26   GSList    *free_list;
27 };
28
29
30 static GRealListAllocator *default_allocator = NULL;
31 static GRealListAllocator *current_allocator = NULL;
32
33 GListAllocator*
34 g_slist_set_allocator (GListAllocator* fallocator)
35 {
36   GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
37   GRealListAllocator* old_allocator = current_allocator;
38
39   if (allocator)
40     current_allocator = allocator;
41   else
42     {
43       if (!default_allocator)
44         default_allocator = (GRealListAllocator*) g_list_allocator_new ();
45       current_allocator = default_allocator;
46     }
47
48   if (!current_allocator->list_mem_chunk)
49     current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
50                                                          sizeof (GSList),
51                                                          1024,
52                                                          G_ALLOC_ONLY);
53
54   return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
55 }
56
57
58 GSList*
59 g_slist_alloc ()
60 {
61   GSList *new_list;
62
63   g_slist_set_allocator (NULL);
64   if (current_allocator->free_list)
65     {
66       new_list = current_allocator->free_list;
67       current_allocator->free_list = current_allocator->free_list->next;
68     }
69   else
70     {
71       new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk);
72     }
73
74   new_list->data = NULL;
75   new_list->next = NULL;
76
77   return new_list;
78 }
79
80 void
81 g_slist_free (GSList *list)
82 {
83   GSList *last;
84
85   if (list)
86     {
87       last = g_slist_last (list);
88       last->next = current_allocator->free_list;
89       current_allocator->free_list = list;
90     }
91 }
92
93 void
94 g_slist_free_1 (GSList *list)
95 {
96   if (list)
97     {
98       list->next = current_allocator->free_list;
99       current_allocator->free_list = list;
100     }
101 }
102
103 GSList*
104 g_slist_append (GSList   *list,
105                 gpointer  data)
106 {
107   GSList *new_list;
108   GSList *last;
109
110   new_list = g_slist_alloc ();
111   new_list->data = data;
112
113   if (!list)
114     {
115       list = new_list;
116     }
117   else
118     {
119       last = g_slist_last (list);
120       g_assert (last != NULL);
121       last->next = new_list;
122     }
123
124   return list;
125 }
126
127 GSList*
128 g_slist_prepend (GSList   *list,
129                  gpointer  data)
130 {
131   GSList *new_list;
132
133   new_list = g_slist_alloc ();
134   new_list->data = data;
135   new_list->next = list;
136
137   return new_list;
138 }
139
140 GSList*
141 g_slist_insert (GSList   *list,
142                 gpointer  data,
143                 gint      position)
144 {
145   GSList *prev_list;
146   GSList *tmp_list;
147   GSList *new_list;
148
149   prev_list = NULL;
150   tmp_list = list;
151
152   while (tmp_list && (position-- > 0))
153     {
154       prev_list = tmp_list;
155       tmp_list = tmp_list->next;
156     }
157
158   if (!tmp_list && !prev_list)
159     return list;
160
161   new_list = g_slist_alloc ();
162
163   if (!prev_list)
164     {
165       new_list->next = list;
166       list = new_list;
167     }
168   else
169     {
170       new_list->next = prev_list->next;
171       prev_list->next = new_list;
172     }
173
174   return list;
175 }
176
177 GSList*
178 g_slist_remove (GSList   *list,
179                 gpointer  data)
180 {
181   GSList *tmp;
182   GSList *prev;
183
184   prev = NULL;
185   tmp = list;
186
187   while (tmp)
188     {
189       if (tmp->data == data)
190         {
191           if (prev)
192             prev->next = tmp->next;
193           if (list == tmp)
194             list = list->next;
195
196           tmp->next = NULL;
197           g_slist_free (tmp);
198
199           break;
200         }
201
202       prev = tmp;
203       tmp = tmp->next;
204     }
205
206   return list;
207 }
208
209 GSList*
210 g_slist_remove_link (GSList *list,
211                      GSList *link)
212 {
213   GSList *tmp;
214   GSList *prev;
215
216   prev = NULL;
217   tmp = list;
218
219   while (tmp)
220     {
221       if (tmp == link)
222         {
223           if (prev)
224             prev->next = tmp->next;
225           if (list == tmp)
226             list = list->next;
227
228           tmp->next = NULL;
229           break;
230         }
231
232       prev = tmp;
233       tmp = tmp->next;
234     }
235
236   return list;
237 }
238
239 GSList*
240 g_slist_reverse (GSList *list)
241 {
242   GSList *tmp;
243   GSList *prev;
244   GSList *last;
245
246   last = NULL;
247   prev = NULL;
248
249   while (list)
250     {
251       last = list;
252
253       tmp = list->next;
254       list->next = prev;
255
256       prev = list;
257       list = tmp;
258     }
259
260   return last;
261 }
262
263 GSList*
264 g_slist_nth (GSList *list,
265              gint    n)
266 {
267   while ((n-- > 0) && list)
268     list = list->next;
269
270   return list;
271 }
272
273 GSList*
274 g_slist_find (GSList   *list,
275               gpointer  data)
276 {
277   while (list)
278     {
279       if (list->data == data)
280         break;
281       list = list->next;
282     }
283
284   return list;
285 }
286
287 GSList*
288 g_slist_last (GSList *list)
289 {
290   if (list)
291     {
292       while (list->next)
293         list = list->next;
294     }
295
296   return list;
297 }
298
299 gint
300 g_slist_length (GSList *list)
301 {
302   gint length;
303
304   length = 0;
305   while (list)
306     {
307       length++;
308       list = list->next;
309     }
310
311   return length;
312 }
313
314 void
315 g_slist_foreach (GSList   *list,
316                  GFunc     func,
317                  gpointer  user_data)
318 {
319   while (list)
320     {
321       (*func) (list->data, user_data);
322       list = list->next;
323     }
324 }