11 my @parms = qw(NAME TYPE);
13 my @templatelines = <DATA>;
18 $self->init(\@parms, \%defaults, \@templatelines);
25 * array type, derived from template
32 * int init() -> nonzero if fail initial allocation
33 * unsigned long size() -> nonnegative number of values stored
34 * int grow(newsize) -> negative if fail allocation, memset(,0,) new space
35 * <TYPE> *getaddr(idx) -> aborts if out of range
36 * void set(idx, value) -> aborts if out of range
37 * <TYPE> get(idx) -> value, or aborts if out of range
48 struct <NAME>__header {
52 typedef struct <NAME>__header <NAME>;
55 <NAME>_init(<NAME> *arr)
57 arr->elts = calloc(10, sizeof(<TYPE>));
58 if (arr->elts == NULL)
65 <NAME>_size(<NAME> *arr)
67 return arr->allocated;
70 static inline unsigned long
71 <NAME>_max_size(<NAME> *arr)
75 upper_bound = SIZE_MAX / sizeof(*arr->elts);
76 if (upper_bound > ULONG_MAX)
77 upper_bound = ULONG_MAX;
78 return (unsigned long) upper_bound;
82 <NAME>_grow(<NAME> *arr, unsigned long newcount)
84 size_t oldsize = sizeof(*arr->elts) * arr->allocated;
88 if (newcount > LONG_MAX)
90 if (newcount < arr->allocated)
92 if (newcount > <NAME>_max_size(arr))
95 newsize = sizeof(*arr->elts) * newcount;
96 ptr = realloc(arr->elts, newsize);
99 memset((char *)ptr + oldsize, 0, newsize - oldsize);
101 arr->allocated = newcount;
105 static inline <TYPE> *
106 <NAME>_getaddr (<NAME> *arr, long idx)
108 if (idx < 0 || (unsigned long) idx >= arr->allocated)
110 return arr->elts + idx;
114 <NAME>_set (<NAME> *arr, long idx, <TYPE> value)
117 newvalp = <NAME>_getaddr(arr, idx);
122 <NAME>_get (<NAME> *arr, long idx)
124 return *<NAME>_getaddr(arr, idx);
128 <NAME>_destroy (<NAME> *arr)