12
my @parms = qw(NAME TYPE COMPARE);
14
my @templatelines = <DATA>;
19
$self->init(\@parms, \%defaults, \@templatelines);
26
$a->setparm("NAME", $self->{values}{"NAME"} . "__enumerator_array");
27
$a->setparm("TYPE", $self->{values}{"TYPE"});
29
$self->SUPER::output($fh);
37
* an enumerated collection type, generated from template
40
* int init() -> returns nonzero on alloc failure
42
* long find(match) -> -1 or index of any match
43
* long append(value) -> -1 or new index
44
* <TYPE> get(index) -> aborts if out of range
45
* void destroy() -> frees array data
47
* Errors adding elements don't distinguish between "out of memory"
48
* and "too big for size_t".
50
* Initial implementation: A flat array, reallocated as needed. Our
51
* uses probably aren't going to get very large.
54
struct <NAME>__enumerator {
55
<NAME>__enumerator_array a;
56
size_t used; /* number of entries used, idx used-1 is last */
58
typedef struct <NAME>__enumerator <NAME>;
61
<NAME>_init(<NAME> *en)
64
return <NAME>__enumerator_array_init(&en->a);
68
<NAME>_size(<NAME> *en)
74
<NAME>__s2l(size_t idx)
86
<NAME>_find(<NAME> *en, <TYPE> value)
89
for (i = 0; i < en->used; i++) {
90
if (<COMPARE> (value, <NAME>__enumerator_array_get(&en->a, <NAME>__s2l(i))) == 0)
97
<NAME>_append(<NAME> *en, <TYPE> value)
99
if (en->used >= LONG_MAX - 1)
101
if (en->used >= SIZE_MAX - 1)
103
if (<NAME>__enumerator_array_size(&en->a) == en->used) {
104
if (<NAME>__enumerator_array_grow(&en->a, en->used + 1) < 0)
107
<NAME>__enumerator_array_set(&en->a, <NAME>__s2l(en->used), value);
113
<NAME>_get(<NAME> *en, size_t idx)
115
return <NAME>__enumerator_array_get(&en->a, <NAME>__s2l(idx));
119
<NAME>_destroy(<NAME> *en)
121
<NAME>__enumerator_array_destroy(&en->a);
126
<NAME>_foreach(<NAME> *en, int (*fn)(size_t i, <TYPE> t, void *p), void *p)
129
for (i = 0; i < en->used; i++) {
130
if (fn (i, <NAME>__enumerator_array_get(&en->a, <NAME>__s2l(i)), p) != 0)