2 * UCW Library -- A simple growing array of an arbitrary type
4 * (c) 2010--2014 Martin Mares <mj@ucw.cz>
14 struct gary_hdr gary_empty_hdr;
17 gary_init(size_t elt_size, size_t num_elts, struct gary_allocator *allocator)
19 DBG("GARY: Init to %zd elements", num_elts);
20 struct gary_hdr *h = allocator->alloc(allocator, GARY_HDR_SIZE + elt_size * num_elts);
21 h->num_elts = h->have_space = num_elts;
22 h->elt_size = elt_size;
23 h->allocator = allocator;
27 static struct gary_hdr *
28 gary_realloc(struct gary_hdr *h, size_t n)
30 size_t old_size = h->have_space;
31 if (n > 2*h->have_space)
35 DBG("GARY: Resize from %zd to %zd elements (need %zd)", old_size, h->have_space, n);
36 return h->allocator->realloc(h->allocator, h, GARY_HDR_SIZE + old_size * h->elt_size, GARY_HDR_SIZE + h->have_space * h->elt_size);
40 gary_set_size(void *array, size_t n)
42 struct gary_hdr *h = GARY_HDR(array);
44 if (n <= h->have_space)
47 h = gary_realloc(h, n);
52 gary_push_helper(void *array, size_t n, byte **cptr)
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;
63 struct gary_hdr *h = GARY_HDR(array);
64 if (h->num_elts != h->have_space)
66 h = h->allocator->realloc(h->allocator, h, GARY_HDR_SIZE + h->have_space * h->elt_size, GARY_HDR_SIZE + h->num_elts * h->elt_size);
67 h->have_space = h->num_elts;
72 /* Default allocator */
74 static void *gary_default_alloc(struct gary_allocator *a UNUSED, size_t size)
79 static void *gary_default_realloc(struct gary_allocator *a UNUSED, void *ptr, size_t old_size UNUSED, size_t new_size)
81 return xrealloc(ptr, new_size);
84 static void gary_default_free(struct gary_allocator *a UNUSED, void *ptr)
89 struct gary_allocator gary_allocator_default = {
90 .alloc = gary_default_alloc,
91 .realloc = gary_default_realloc,
92 .free = gary_default_free,
95 /* Zeroing allocator */
97 static void *gary_zeroed_alloc(struct gary_allocator *a UNUSED, size_t size)
99 return xmalloc_zero(size);
102 static void *gary_zeroed_realloc(struct gary_allocator *a UNUSED, void *ptr, size_t old_size, size_t new_size)
104 ptr = xrealloc(ptr, new_size);
105 if (old_size < new_size)
106 bzero((byte *) ptr + old_size, new_size - old_size);
110 struct gary_allocator gary_allocator_zeroed = {
111 .alloc = gary_zeroed_alloc,
112 .realloc = gary_zeroed_realloc,
113 .free = gary_default_free,
123 GARY_INIT_ZERO(a, 5);
125 for (int i=0; i<5; i++)
138 for (int i=0; i<(int)GARY_SIZE(a); i++)
139 printf("%d\n", a[i]);