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)