package t_array;
use strict;
use vars qw(@ISA);
#require ktemplate;
require t_template;
@ISA=qw(t_template);
my @parms = qw(NAME TYPE);
my %defaults = ( );
my @templatelines = <DATA>;
sub new { # no args
my $self = {};
bless $self;
$self->init(\@parms, \%defaults, \@templatelines);
return $self;
}
__DATA__
/*
* array type, derived from template
*
* parameters:
* NAME: <NAME>
* TYPE: <TYPE>
*
* methods:
* int init() -> nonzero if fail initial allocation
* unsigned long size() -> nonnegative number of values stored
* int grow(newsize) -> negative if fail allocation, memset(,0,) new space
* <TYPE> *getaddr(idx) -> aborts if out of range
* void set(idx, value) -> aborts if out of range
* <TYPE> get(idx) -> value, or aborts if out of range
*/
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <stdint.h>
struct <NAME>__header {
size_t allocated;
<TYPE> *elts;
};
typedef struct <NAME>__header <NAME>;
static inline int
<NAME>_init(<NAME> *arr)
{
arr->elts = calloc(10, sizeof(<TYPE>));
if (arr->elts == NULL)
return ENOMEM;
arr->allocated = 10;
return 0;
}
static inline long
<NAME>_size(<NAME> *arr)
{
return arr->allocated;
}
static inline unsigned long
<NAME>_max_size(<NAME> *arr)
{
size_t upper_bound;
upper_bound = SIZE_MAX / sizeof(*arr->elts);
if (upper_bound > ULONG_MAX)
upper_bound = ULONG_MAX;
return (unsigned long) upper_bound;
}
static inline int
<NAME>_grow(<NAME> *arr, unsigned long newcount)
{
size_t oldsize = sizeof(*arr->elts) * arr->allocated;
size_t newsize;
void *ptr;
if (newcount > LONG_MAX)
return -1;
if (newcount < arr->allocated)
return 0;
if (newcount > <NAME>_max_size(arr))
return -1;
newsize = sizeof(*arr->elts) * newcount;
ptr = realloc(arr->elts, newsize);
if (ptr == NULL)
return -1;
memset((char *)ptr + oldsize, 0, newsize - oldsize);
arr->elts = ptr;
arr->allocated = newcount;
return 0;
}
static inline <TYPE> *
<NAME>_getaddr (<NAME> *arr, long idx)
{
if (idx < 0 || (unsigned long) idx >= arr->allocated)
abort();
return arr->elts + idx;
}
static inline void
<NAME>_set (<NAME> *arr, long idx, <TYPE> value)
{
<TYPE> *newvalp;
newvalp = <NAME>_getaddr(arr, idx);
*newvalp = value;
}
static inline <TYPE>
<NAME>_get (<NAME> *arr, long idx)
{
return *<NAME>_getaddr(arr, idx);
}
static inline void
<NAME>_destroy (<NAME> *arr)
{
free(arr->elts);
arr->elts = 0;
}