/*
* UCW Library -- A simple growing array of an arbitrary type
*
- * (c) 2010 Martin Mares <mj@ucw.cz>
+ * (c) 2010--2012 Martin Mares <mj@ucw.cz>
*/
#undef LOCAL_DEBUG
#include "ucw/lib.h"
#include "ucw/gary.h"
+#include <string.h>
+
void *
-gary_init(size_t elt_size, size_t num_elts)
+gary_init(size_t elt_size, size_t num_elts, int zeroed)
{
DBG("GARY: Init to %zd elements", num_elts);
struct gary_hdr *h = xmalloc(GARY_HDR_SIZE + elt_size * num_elts);
h->num_elts = h->have_space = num_elts;
h->elt_size = elt_size;
- return (byte *)h + GARY_HDR_SIZE;
+ h->zeroed = zeroed;
+ if (zeroed)
+ bzero(GARY_BODY(h), elt_size * num_elts);
+ return GARY_BODY(h);
}
void
static struct gary_hdr *
gary_realloc(struct gary_hdr *h, size_t n)
{
+ size_t old_size = h->have_space;
if (n > 2*h->have_space)
h->have_space = n;
else
h->have_space *= 2;
- DBG("GARY: Resize to %zd elements (need %zd)", h->have_space, n);
- return xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size);
+ DBG("GARY: Resize from %zd to %zd elements (need %zd)", old_size, h->have_space, n);
+ h = xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size);
+ if (h->zeroed)
+ bzero(GARY_BODY(h) + h->elt_size * old_size, h->elt_size * (h->have_space - old_size));
+ return h;
}
void *
int main(void)
{
int *a;
- GARY_INIT(a, 5);
+ GARY_INIT_ZERO(a, 5);
for (int i=0; i<5; i++)
- a[i] = i+1;
+ {
+ ASSERT(!a[i]);
+ a[i] = i+1;
+ }
+ GARY_PUSH(a, 1);
*GARY_PUSH(a, 1) = 10;
*GARY_PUSH(a, 1) = 20;
*GARY_PUSH(a, 1) = 30;
/*
* UCW Library -- A simple growing array of an arbitrary type
*
- * (c) 2010 Martin Mares <mj@ucw.cz>
+ * (c) 2010--2012 Martin Mares <mj@ucw.cz>
*/
#ifndef _UCW_GARY_H
size_t num_elts;
size_t have_space;
size_t elt_size;
+ int zeroed;
};
#define GARY_HDR_SIZE ALIGN_TO(sizeof(struct gary_hdr), CPU_STRUCT_ALIGN)
#define GARY_HDR(ptr) ((struct gary_hdr *)((byte*)(ptr) - GARY_HDR_SIZE))
#define GARY_BODY(ptr) ((byte *)(ptr) + GARY_HDR_SIZE)
-#define GARY_INIT(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n))
+#define GARY_INIT(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n), 0)
+#define GARY_INIT_ZERO(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n), 1)
#define GARY_FREE(ptr) do { if (ptr) xfree(GARY_HDR(ptr)); } while (0)
#define GARY_SIZE(ptr) (GARY_HDR(ptr)->num_elts)
#define GARY_RESIZE(ptr, n) (ptr) = gary_set_size((ptr), (n))
#define GARY_FIX(ptr) (ptr) = gary_fix((ptr))
/* Internal functions */
-void *gary_init(size_t elt_size, size_t num_elts);
+void *gary_init(size_t elt_size, size_t num_elts, int zeroed);
void gary_free(void *array);
void *gary_set_size(void *array, size_t n);
void *gary_push_helper(void *array, size_t n, byte **cptr);