5 * Aaron Bockover (abockover@novell.com)
6 * Gonzalo Paniagua Javier (gonzalo@novell.com)
7 * Jeffrey Stedfast (fejj@novell.com)
9 * (C) 2006,2011 Novell, Inc.
11 * Permission is hereby granted, free of charge, to any person obtaining
12 * a copy of this software and associated documentation files (the
13 * "Software"), to deal in the Software without restriction, including
14 * without limitation the rights to use, copy, modify, merge, publish,
15 * distribute, sublicense, and/or sell copies of the Software, and to
16 * permit persons to whom the Software is furnished to do so, subject to
17 * the following conditions:
19 * The above copyright notice and this permission notice shall be
20 * included in all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 typedef struct _GPtrArrayPriv {
41 g_ptr_array_grow(GPtrArrayPriv *array, guint length)
43 guint new_length = array->len + length;
45 g_return_if_fail(array != NULL);
47 if(new_length <= array->size) {
53 while(array->size < new_length) {
57 array->size = MAX(array->size, 16);
58 array->pdata = g_realloc(array->pdata, array->size * sizeof(gpointer));
64 return g_ptr_array_sized_new(0);
68 g_ptr_array_sized_new(guint reserved_size)
70 GPtrArrayPriv *array = g_new0(GPtrArrayPriv, 1);
76 if(reserved_size > 0) {
77 g_ptr_array_grow(array, reserved_size);
80 return (GPtrArray *)array;
84 g_ptr_array_free(GPtrArray *array, gboolean free_seg)
86 gpointer *data = NULL;
88 g_return_val_if_fail(array != NULL, NULL);
102 g_ptr_array_set_size(GPtrArray *array, gint length)
104 g_return_if_fail(array != NULL);
106 if((size_t)length > array->len) {
107 g_ptr_array_grow((GPtrArrayPriv *)array, length);
108 memset(array->pdata + array->len, 0, (length - array->len)
116 g_ptr_array_add(GPtrArray *array, gpointer data)
118 g_return_if_fail(array != NULL);
119 g_ptr_array_grow((GPtrArrayPriv *)array, 1);
120 array->pdata[array->len++] = data;
124 g_ptr_array_remove_index(GPtrArray *array, guint index)
126 gpointer removed_node;
128 g_return_val_if_fail(array != NULL, NULL);
129 g_return_val_if_fail(index >= 0 || index < array->len, NULL);
131 removed_node = array->pdata[index];
133 if(index != array->len - 1) {
134 g_memmove(array->pdata + index, array->pdata + index + 1,
135 (array->len - index - 1) * sizeof(gpointer));
139 array->pdata[array->len] = NULL;
145 g_ptr_array_remove_index_fast(GPtrArray *array, guint index)
147 gpointer removed_node;
149 g_return_val_if_fail(array != NULL, NULL);
150 g_return_val_if_fail(index >= 0 || index < array->len, NULL);
152 removed_node = array->pdata[index];
154 if(index != array->len - 1) {
155 g_memmove(array->pdata + index, array->pdata + array->len - 1,
160 array->pdata[array->len] = NULL;
166 g_ptr_array_remove(GPtrArray *array, gpointer data)
170 g_return_val_if_fail(array != NULL, FALSE);
172 for(i = 0; i < array->len; i++) {
173 if(array->pdata[i] == data) {
174 g_ptr_array_remove_index(array, i);
183 g_ptr_array_remove_fast(GPtrArray *array, gpointer data)
187 g_return_val_if_fail(array != NULL, FALSE);
189 for(i = 0; i < array->len; i++) {
190 if(array->pdata[i] == data) {
193 array->pdata [i] = array->pdata [array->len];
195 array->pdata [i] = NULL;
204 g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data)
208 for(i = 0; i < array->len; i++) {
209 func(g_ptr_array_index(array, i), user_data);
214 g_ptr_array_sort(GPtrArray *array, GCompareFunc compare)
216 g_return_if_fail(array != NULL);
217 qsort(array->pdata, array->len, sizeof(gpointer), compare);
221 g_qsort_swap (char *a, char *b, size_t n)
234 g_qsort_median (char *a, char *b, char *c, GCompareDataFunc compare, gpointer user_data)
236 if (compare (a, b, user_data) < 0) {
238 if (compare (b, c, user_data) < 0)
242 if (compare (a, c, user_data) < 0)
249 if (compare (a, c, user_data) < 0)
253 if (compare (b, c, user_data) < 0)
262 g_qsort_with_data (gpointer base, size_t nmemb, size_t size, GCompareDataFunc compare, gpointer user_data)
264 char *middle = ((char *) base) + (nmemb / 2) * size;
265 char *last = ((char *) base) + (nmemb - 1) * size;
266 char *first = (char *) base;
267 register char *i = first + size;
268 register char *k = last;
269 register char *pivot;
274 /* determine which element contains the median value */
275 pivot = g_qsort_median (first, middle, last, compare, user_data);
277 /* swap pivot value into first element (so the location stays constant) */
278 g_qsort_swap (first, pivot, size);
282 /* find the first element with a value > pivot value */
283 while (compare (i, pivot, user_data) <= 0 && i < last && i < k)
286 /* find the last element with a value <= pivot value */
287 while (compare (k, pivot, user_data) > 0 && k > first && k >= i)
293 g_qsort_swap (i, k, size);
296 /* swap the pivot with the last element in the first partition */
297 g_qsort_swap (pivot, k, size);
299 /* sort the first partition */
300 g_qsort_with_data (first, (k - first) / size, size, compare, user_data);
302 /* sort the second partition */
303 g_qsort_with_data (k + size, (last - k) / size, size, compare, user_data);
307 g_ptr_array_sort_with_data (GPtrArray *array, GCompareDataFunc compare, gpointer user_data)
309 g_return_if_fail (array != NULL);
311 g_qsort_with_data (array->pdata, array->len, sizeof (gpointer), compare, user_data);