Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison array.h @ 1:411b28d78483
standard arrays (nearly)
author | David A. Holland |
---|---|
date | Sun, 19 Dec 2010 16:47:59 -0500 |
parents | |
children | 9c1cecba517c |
comparison
equal
deleted
inserted
replaced
0:67fa1db0651c | 1:411b28d78483 |
---|---|
1 /*- | |
2 * Copyright (c) 2009 The NetBSD Foundation, Inc. | |
3 * All rights reserved. | |
4 * | |
5 * This code is derived from software contributed to The NetBSD Foundation | |
6 * by David A. Holland. | |
7 * | |
8 * Redistribution and use in source and binary forms, with or without | |
9 * modification, are permitted provided that the following conditions | |
10 * are met: | |
11 * 1. Redistributions of source code must retain the above copyright | |
12 * notice, this list of conditions and the following disclaimer. | |
13 * 2. Redistributions in binary form must reproduce the above copyright | |
14 * notice, this list of conditions and the following disclaimer in the | |
15 * documentation and/or other materials provided with the distribution. | |
16 * | |
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 * POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
30 #ifndef ARRAY_H | |
31 #define ARRAY_H | |
32 | |
33 #define ARRAYS_CHECKED | |
34 | |
35 #ifdef ARRAYS_CHECKED | |
36 #include <assert.h> | |
37 #define arrayassert assert | |
38 #else | |
39 #define arrayassert(x) ((void)(x)) | |
40 #endif | |
41 | |
42 //////////////////////////////////////////////////////////// | |
43 // type and base operations | |
44 | |
45 struct array { | |
46 void **v; | |
47 unsigned num, max; | |
48 }; | |
49 | |
50 struct array *array_create(void); | |
51 void array_destroy(struct array *); | |
52 void array_init(struct array *); | |
53 void array_cleanup(struct array *); | |
54 unsigned array_num(const struct array *); | |
55 void *array_get(const struct array *, unsigned index_); | |
56 void array_set(const struct array *, unsigned index_, void *val); | |
57 int array_setsize(struct array *, unsigned num); | |
58 int array_add(struct array *, void *val, unsigned *index_ret); | |
59 int array_insert(struct array *a, unsigned index_); | |
60 void array_remove(struct array *a, unsigned index_); | |
61 | |
62 //////////////////////////////////////////////////////////// | |
63 // inlining for base operations | |
64 | |
65 #ifndef ARRAYINLINE | |
66 #define ARRAYINLINE __c99inline | |
67 #endif | |
68 | |
69 ARRAYINLINE unsigned | |
70 array_num(const struct array *a) | |
71 { | |
72 return a->num; | |
73 } | |
74 | |
75 ARRAYINLINE void * | |
76 array_get(const struct array *a, unsigned index_) | |
77 { | |
78 arrayassert(index_ < a->num); | |
79 return a->v[index_]; | |
80 } | |
81 | |
82 ARRAYINLINE void | |
83 array_set(const struct array *a, unsigned index_, void *val) | |
84 { | |
85 arrayassert(index_ < a->num); | |
86 a->v[index_] = val; | |
87 } | |
88 | |
89 ARRAYINLINE int | |
90 array_add(struct array *a, void *val, unsigned *index_ret) | |
91 { | |
92 unsigned index_ = a->num; | |
93 if (array_setsize(a, index_+1)) { | |
94 return -1; | |
95 } | |
96 a->v[index_] = val; | |
97 if (index_ret != NULL) { | |
98 *index_ret = index_; | |
99 } | |
100 return 0; | |
101 } | |
102 | |
103 //////////////////////////////////////////////////////////// | |
104 // bits for declaring and defining typed arrays | |
105 | |
106 /* | |
107 * Usage: | |
108 * | |
109 * DECLARRAY_BYTYPE(foo, bar) declares "struct foo", which is | |
110 * an array of pointers to "bar", plus the operations on it. | |
111 * | |
112 * DECLARRAY(foo) is equivalent to DECLARRAY_BYTYPE(fooarray, struct foo). | |
113 * | |
114 * DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that | |
115 * they define the operations, and both take an extra argument INLINE. | |
116 * For C99 this should be INLINE in header files and empty in the | |
117 * master source file, the same as the usage of ARRAYINLINE above and | |
118 * in array.c. | |
119 * | |
120 * Example usage in e.g. item.h of some game: | |
121 * | |
122 * DECLARRAY_BYTYPE(stringarray, char); | |
123 * DECLARRAY(potion); | |
124 * DECLARRAY(sword); | |
125 * | |
126 * #ifndef ITEMINLINE | |
127 * #define ITEMINLINE INLINE | |
128 * #endif | |
129 * | |
130 * DEFARRAY_BYTYPE(stringarray, char, ITEMINLINE); | |
131 * DEFARRAY(potion, ITEMINLINE); | |
132 * DEFARRAY(sword, ITEMINLINE); | |
133 * | |
134 * Then item.c would do "#define ITEMINLINE" before including item.h. | |
135 */ | |
136 | |
137 #define DECLARRAY_BYTYPE(ARRAY, T) \ | |
138 struct ARRAY { \ | |
139 struct array arr; \ | |
140 }; \ | |
141 \ | |
142 struct ARRAY *ARRAY##_create(void); \ | |
143 void ARRAY##_destroy(struct ARRAY *a); \ | |
144 void ARRAY##_init(struct ARRAY *a); \ | |
145 void ARRAY##_cleanup(struct ARRAY *a); \ | |
146 unsigned ARRAY##_num(const struct ARRAY *a); \ | |
147 T *ARRAY##_get(const struct ARRAY *a, unsigned index_); \ | |
148 void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \ | |
149 int ARRAY##_setsize(struct ARRAY *a, unsigned num); \ | |
150 int ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret); \ | |
151 int ARRAY##_insert(struct ARRAY *a, unsigned index_); \ | |
152 void ARRAY##_remove(struct ARRAY *a, unsigned index_) | |
153 | |
154 | |
155 #define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \ | |
156 INLINE void \ | |
157 ARRAY##_init(struct ARRAY *a) \ | |
158 { \ | |
159 array_init(&a->arr); \ | |
160 } \ | |
161 \ | |
162 INLINE void \ | |
163 ARRAY##_cleanup(struct ARRAY *a) \ | |
164 { \ | |
165 array_cleanup(&a->arr); \ | |
166 } \ | |
167 \ | |
168 INLINE struct \ | |
169 ARRAY *ARRAY##_create(void) \ | |
170 { \ | |
171 struct ARRAY *a; \ | |
172 \ | |
173 a = malloc(sizeof(*a)); \ | |
174 if (a == NULL) { \ | |
175 return NULL; \ | |
176 } \ | |
177 ARRAY##_init(a); \ | |
178 return a; \ | |
179 } \ | |
180 \ | |
181 INLINE void \ | |
182 ARRAY##_destroy(struct ARRAY *a) \ | |
183 { \ | |
184 ARRAY##_cleanup(a); \ | |
185 free(a); \ | |
186 } \ | |
187 \ | |
188 INLINE unsigned \ | |
189 ARRAY##_num(const struct ARRAY *a) \ | |
190 { \ | |
191 return array_num(&a->arr); \ | |
192 } \ | |
193 \ | |
194 INLINE T * \ | |
195 ARRAY##_get(const struct ARRAY *a, unsigned index_) \ | |
196 { \ | |
197 return (T *)array_get(&a->arr, index_); \ | |
198 } \ | |
199 \ | |
200 INLINE void \ | |
201 ARRAY##_set(struct ARRAY *a, unsigned index_, T *val) \ | |
202 { \ | |
203 array_set(&a->arr, index_, (void *)val); \ | |
204 } \ | |
205 \ | |
206 INLINE int \ | |
207 ARRAY##_setsize(struct ARRAY *a, unsigned num) \ | |
208 { \ | |
209 return array_setsize(&a->arr, num); \ | |
210 } \ | |
211 \ | |
212 INLINE int \ | |
213 ARRAY##_add(struct ARRAY *a, T *val, unsigned *ret) \ | |
214 { \ | |
215 return array_add(&a->arr, (void *)val, ret); \ | |
216 } \ | |
217 \ | |
218 INLINE int \ | |
219 ARRAY##_insert(struct ARRAY *a, unsigned index_) \ | |
220 { \ | |
221 return array_insert(&a->arr, index_); \ | |
222 } \ | |
223 \ | |
224 INLINE void \ | |
225 ARRAY##_remove(struct ARRAY *a, unsigned index_) \ | |
226 { \ | |
227 return array_remove(&a->arr, index_); \ | |
228 } | |
229 | |
230 #define DECLARRAY(T) DECLARRAY_BYTYPE(T##array, struct T) | |
231 #define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE) | |
232 | |
233 //////////////////////////////////////////////////////////// | |
234 // basic array types | |
235 | |
236 DECLARRAY_BYTYPE(stringarray, char); | |
237 DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE); | |
238 | |
239 #endif /* ARRAY_H */ |