#! /usr/bin/env cpppp
## param $namespace;
## param $vector_t;
## param $el_t = 'int';
## param $el_dtor;
## param $el_copy_ctor= sub($dest, $src) { "*($dest) = *($src)" };
##
## $namespace ||= "vector_$el_t" =~ s/\s*\*\s*/_p/gr =~ s/_t$//r;
## $vector_t ||= $namespace . '_t';
## section PUBLIC;
typedef struct $namespace {
size_t capacity, count;
$el_t el[];
} ${namespace}_t;
bool ${namespace}_realloc($vector_t **vec_p, size_t capacity);
void ${namespace}_free($vector_t **vec_p);
bool ${namespace}_append($vector_t **vec_p, $el_t *value_p);
## section PRIVATE;
bool ${namespace}_realloc($vector_t **vec_p, size_t capacity) {
$vector_t tmp;
size_t size, i;
## if ($el_dtor) {
// Exists and shrinking?
if (*vec_p && capacity < (*vec_p)->count)
// Run destructor for each deleted element
for (i=(*vec_p)->count; i > capacity;) {
$el_dtor((*vec_p)->el[--i]);
}
## }
size= sizeof(struct $namespace) + capacity * sizeof($el_t);
tmp= ($vector_t*)( *vec_p? realloc(*vec_p, size) : malloc(size) );
if (!tmp) return false;
if (!*vec_p)
tmp->count= 0;
tmp->capacity= capacity;
*vec_p= tmp;
}
void ${namespace}_free($vector_t **vec_p) {
if (*vec_p) {
## if ($el_dtor) {
// Run destructor for each deleted element
for (i=(*vec_p)->count; i > 0;) {
$el_dtor((*vec_p)->el[--i]);
}
## }
free(*vec_p);
*vec_p= NULL;
}
}
bool ${namespace}_append($vector_t **vec_p, $el_t *value_p) {
if ((*vec_p)->count >= (*vec_p)->capacity)
if (!${namespace}_realloc(vec_p, (*vec_p)->capacity << 1))
return false;
${{ $el_copy_ctor->( '(*vec_p)->el + (*vec_p)->count', 'value_p' ) }};
return true;
}