]> mj.ucw.cz Git - libucw.git/blob - ucw/gary.c
Implemented a new growing array module
[libucw.git] / ucw / gary.c
1 /*
2  *      UCW Library -- A simple growing array of an arbitrary type
3  *
4  *      (c) 2010 Martin Mares <mj@ucw.cz>
5  */
6
7 #undef LOCAL_DEBUG
8
9 #include "ucw/lib.h"
10 #include "ucw/gary.h"
11
12 void *
13 gary_init(size_t elt_size, size_t num_elts)
14 {
15   DBG("GARY: Init to %zd elements", num_elts);
16   struct gary_hdr *h = xmalloc(GARY_HDR_SIZE + elt_size * num_elts);
17   h->num_elts = h->have_space = num_elts;
18   h->elt_size = elt_size;
19   return (byte *)h + GARY_HDR_SIZE;
20 }
21
22 void
23 gary_free(void *array)
24 {
25   xfree(GARY_HDR(array));
26 }
27
28 static struct gary_hdr *
29 gary_realloc(struct gary_hdr *h, size_t n)
30 {
31   if (n > 2*h->have_space)
32     h->have_space = n;
33   else
34     h->have_space *= 2;
35   DBG("GARY: Resize to %zd elements (need %zd)", h->have_space, n);
36   return xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size);
37 }
38
39 void *
40 gary_set_size(void *array, size_t n)
41 {
42   struct gary_hdr *h = GARY_HDR(array);
43   h->num_elts = n;
44   if (n <= h->have_space)
45     return array;
46
47   h = gary_realloc(h, n);
48   return GARY_BODY(h);
49 }
50
51 void *
52 gary_push_helper(void *array, size_t n, byte **cptr)
53 {
54   struct gary_hdr *h = GARY_HDR(array);
55   h = gary_realloc(h, h->num_elts);
56   *cptr = GARY_BODY(h) + (h->num_elts - n) * h->elt_size;
57   return GARY_BODY(h);
58 }
59
60 void *
61 gary_fix(void *array)
62 {
63   struct gary_hdr *h = GARY_HDR(array);
64   if (h->num_elts != h->have_space)
65     {
66       h = xrealloc(h, GARY_HDR_SIZE + h->num_elts * h->elt_size);
67       h->have_space = h->num_elts;
68     }
69   return GARY_BODY(h);
70 }
71
72 #ifdef TEST
73
74 #include <stdio.h>
75
76 int main(void)
77 {
78   int *a;
79   GARY_INIT(a, 5);
80
81   for (int i=0; i<5; i++)
82     a[i] = i+1;
83
84   *GARY_PUSH(a, 1) = 10;
85   *GARY_PUSH(a, 1) = 20;
86   *GARY_PUSH(a, 1) = 30;
87   GARY_POP(a, 1);
88   GARY_FIX(a);
89
90   for (int i=0; i<(int)GARY_SIZE(a); i++)
91     printf("%d\n", a[i]);
92
93   GARY_FREE(a);
94   return 0;
95 }
96
97 #endif