2 * - By Richard W.M. Jones <rich@annexia.org>
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.
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.
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.
18 * $Id: vector.c,v 1.4 2002/10/27 16:04:42 rich Exp $
41 _vector_new (pool pool, size_t size)
43 vector v = pmalloc (pool, sizeof *v);
48 v->used = v->allocated = 0;
54 new_subvector (pool pool, vector v, int i, int j)
56 vector new_v = pmalloc (pool, sizeof *v);
58 assert (0 <= i && j <= v->used);
61 new_v->size = v->size;
65 new_v->data = pmemdup (pool, v->data + i * v->size, (j - i) * v->size);
66 new_v->used = new_v->allocated = j - i;
71 new_v->used = new_v->allocated = 0;
78 copy_vector (pool pool, vector v)
80 return new_subvector (pool, v, 0, v->used);
84 _vector_push_back (vector v, const void *ptr)
86 if (v->used >= v->allocated)
88 int a = v->allocated + INCREMENT;
89 void *d = prealloc (v->pool, v->data, a * v->size);
94 if (ptr) memcpy (v->data + v->used * v->size, ptr, v->size);
99 _vector_pop_back (vector v, void *ptr)
101 assert (v->used > 0);
103 if (ptr) memcpy (ptr, v->data + v->used * v->size, v->size);
107 vector_insert_array (vector v, int i, const void *ptr, int n)
111 assert (0 <= i && i <= v->used);
113 /* Insert n dummy elements at the end of the list. */
114 for (j = 0; j < n; ++j) _vector_push_back (v, 0);
116 /* Move the other elements up. */
117 for (j = v->used-1; j > i; --j)
118 memcpy (v->data + j * v->size, v->data + (j-n) * v->size, v->size);
120 /* Insert these elements at position i. */
121 if (ptr) memcpy (v->data + i * v->size, ptr, v->size * n);
125 _vector_insert (vector v, int i, const void *ptr)
127 vector_insert_array (v, i, ptr, 1);
131 _vector_push_front (vector v, const void *ptr)
133 _vector_insert (v, 0, ptr);
137 _vector_pop_front (vector v, void *ptr)
139 _vector_get (v, 0, ptr);
144 vector_push_back_vector (vector v, const vector w)
148 assert (size == w->size);
150 if (v->used + w->used > v->allocated)
152 int a = v->used + w->used;
153 void *d = prealloc (v->pool, v->data, a * size);
158 memcpy (v->data + v->used * size, w->data, size * w->used);
163 vector_push_front_vector (vector v, const vector w)
167 assert (size == w->size);
169 if (v->used + w->used > v->allocated)
171 int a = v->used + w->used;
172 void *d = prealloc (v->pool, v->data, a * size);
177 memmove (v->data + w->used * size, v->data, v->used * size);
178 memcpy (v->data, w->data, size * w->used);
183 _vector_replace (vector v, int i, const void *ptr)
185 assert (0 <= i && i < v->used);
187 if (ptr) memcpy (v->data + i * v->size, ptr, v->size);
191 vector_erase_range (vector v, int i, int j)
193 assert (0 <= i && i < v->used && 0 <= j && j <= v->used);
199 for (k = i+n; k < v->used; ++k)
200 memcpy (v->data + (k-n) * v->size, v->data + k * v->size, v->size);
207 vector_erase (vector v, int i)
209 vector_erase_range (v, i, i+1);
213 vector_clear (vector v)
219 _vector_get (vector v, int i, void *ptr)
221 assert (0 <= i && i < v->used);
222 if (ptr) memcpy (ptr, v->data + i * v->size, v->size);
226 _vector_get_ptr (vector v, int i)
228 assert (0 <= i && i < v->used);
229 return v->data + i * v->size;
233 _vector_sort (vector v, int (*compare_fn) (const void *, const void *))
235 qsort (v->data, v->used, v->size, compare_fn);
239 _vector_compare (vector v1, vector v2,
240 int (*compare_fn) (const void *, const void *))
245 if (vector_size (v1) < vector_size (v2)) return -1;
246 else if (vector_size (v1) > vector_size (v2)) return 1;
248 for (i = 0; i < vector_size (v1); ++i)
250 vector_get_ptr (v1, i, p1);
251 vector_get_ptr (v2, i, p2);
253 r = compare_fn (p1, p2);
255 if (r != 0) return r;
262 _vector_fill (vector v, const void *ptr, int n)
265 _vector_push_back (v, ptr);
269 vector_swap (vector v, int i, int j)
276 vector_get_ptr (v, i, pi);
277 vector_get_ptr (v, j, pj);
279 memcpy (data, pi, v->size);
280 memcpy (pi, pj, v->size);
281 memcpy (pj, data, v->size);
285 vector_reallocate (vector v, int n)
287 if (n > v->allocated)
289 void *d = prealloc (v->pool, v->data, n * v->size);
296 vector_grep (pool p, vector v, int (*match_fn) (const void *))
298 vector nv = _vector_new (p, v->size);
301 for (i = 0; i < v->used; ++i)
302 if (match_fn (v->data + i * v->size))
303 _vector_push_back (nv, v->data + i * v->size);
309 vector_grep_pool (pool p, vector v, int (*match_fn) (pool, const void *))
311 vector nv = _vector_new (p, v->size);
314 for (i = 0; i < v->used; ++i)
315 if (match_fn (p, v->data + i * v->size))
316 _vector_push_back (nv, v->data + i * v->size);
322 _vector_map (pool p, vector v,
323 void (*map_fn) (const void *, void *),
326 vector nv = _vector_new (p, result_size);
329 vector_reallocate (nv, v->used);
332 for (i = 0; i < v->used; ++i)
333 map_fn (v->data + i * v->size, nv->data + i * nv->size);
339 _vector_map_pool (pool p, vector v,
340 void (*map_fn) (pool, const void *, void *),
343 vector nv = _vector_new (p, result_size);
346 vector_reallocate (nv, v->used);
349 for (i = 0; i < v->used; ++i)
350 map_fn (p, v->data + i * v->size, nv->data + i * nv->size);