OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
darray.h
1#ifndef _DARRAY_H
2#define _DARRAY_H
3
4/* File: darray.h
5 * --------------
6 * Defines the interface for the DynamicArray ADT.
7 * The DArray allows the client to store any number of elements of any desired
8 * base type and is appropriate for a wide variety of storage problems. It
9 * supports efficient element access, and appending/inserting/deleting elements
10 * as well as optional sorting and searching. In all cases, the DArray imposes
11 * no upper bound on the number of elements and deals with all its own memory
12 * management. The client specifies the size (in bytes) of the elements that
13 * will be stored in the array when it is created. Thereafter the client and
14 * the DArray can refer to elements via (void*) ptrs.
15 */
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21/* Type: DArray
22 * ----------------
23 * Defines the DArray type itself. The client can declare variables of type
24 * DArray, but these variables must be initialized with the result of ArrayNew.
25 * The DArray is implemented with pointers, so all client copies in variables
26 * or parameters will be "shallow" -- they will all actually point to the
27 * same DArray structure. Only calls to ArrayNew create new arrays.
28 * The struct declaration below is "incomplete"- the implementation
29 * details are literally not visible in the client .h file.
30 */
31typedef struct DArrayImplementation *DArray;
32
33
34/* ArrayCompareFn
35 * --------------
36 * ArrayCompareFn is a pointer to a client-supplied function which the
37 * DArray uses to sort or search the elements. The comparator takes two
38 * (const void*) pointers (these will point to elements) and returns an int.
39 * The comparator should indicate the ordering of the two elements
40 * using the same convention as the strcmp library function:
41 * If elem1 is "less than" elem2, return a negative number.
42 * If elem1 is "greater than" elem2, return a positive number.
43 * If the two elements are "equal", return 0.
44 */
45#if defined(WIN32)
46 typedef int (__cdecl *ArrayCompareFn)(const void *elem1, const void *elem2);
47#else
48 typedef int (*ArrayCompareFn)(const void *elem1, const void *elem2);
49#endif
50
51
52/* ArrayMapFn
53 * ----------
54 * ArrayMapFn defines the space of functions that can be used to map over
55 * the elements in a DArray. A map function is called with a pointer to
56 * the element and a client data pointer passed in from the original
57 * caller.
58 */
59typedef void (*ArrayMapFn)(void *elem, void *clientData);
60
61/* ArrayMapFn2
62 * ----------_
63 * Same as ArrayMapFn, but can return 0 to stop the mapping.
64 * Used by ArrayMap2
65 */
66typedef int (*ArrayMapFn2)(void *elem, void *clientData);
67
68 /* ArrayElementFreeFn
69 * ------------------
70 * ArrayElementFreeFn defines the space of functions that can be used as the
71 * clean-up function for an element as it is deleted from the array
72 * or when the entire array of elements is freed. The cleanup function is
73 * called with a pointer to an element about to be deleted.
74 */
75typedef void (*ArrayElementFreeFn)(void *elem);
76
77
78/* ArrayNew
79 * --------
80 * Creates a new DArray and returns it. There are zero elements in the array.
81 * to start. The elemSize parameter specifies the number of bytes that a single
82 * element of this array should take up. For example, if you want to store
83 * elements of type Binky, you would pass sizeof(Binky) as this parameter.
84 * An assert is raised if the size is not greater than zero.
85 *
86 * The numElemsToAllocate parameter specifies the initial allocated length
87 * of the array, as well as the dynamic reallocation increment for when the
88 * array grows. Rather than growing the array one element at a time as
89 * elements are added (which is rather inefficient), you will grow the array
90 * in chunks of numElemsToAllocate size. The "allocated length" is the number
91 * of elements that have been allocated, the "logical length" is the number of
92 * those slots actually being currently used.
93 *
94 * A new array is initially allocated to the size of numElemsToAllocate, the
95 * logical length is zero. As elements are added, those allocated slots fill
96 * up and when the initial allocation is all used, grow the array by another
97 * numElemsToAllocate elements. You will continue growing the array in chunks
98 * like this as needed. Thus the allocated length will always be a multiple
99 * of numElemsToAllocate. Don't worry about using realloc to shrink the array
100 * allocation if many elements are deleted from the array. It turns out that
101 * many implementations of realloc don't even pay attention to such a request
102 * so there is little point in asking. Just leave the array over-allocated.
103 *
104 * The numElemsToAllocate is the client's opportunity to tune the resizing
105 * behavior for their particular needs. If constructing large arrays,
106 * specifying a large allocation chunk size will result in fewer resizing
107 * operations. If using small arrays, a small allocation chunk size will
108 * result in less space going unused. If the client passes 0 for
109 * numElemsToAllocate, the implementation will use the default value of 8.
110 *
111 * The elemFreeFn is the function that will be called on an element that
112 * is about to be deleted (using ArrayDeleteAt) or on each element in the
113 * array when the entire array is being freed (using ArrayFree). This function
114 * is your chance to do any deallocation/cleanup required for the element
115 * (such as freeing any pointers contained in the element). The client can pass
116 * NULL for the cleanupFn if the elements don't require any handling on free.
117 */
118DArray ArrayNew(int elemSize, int numElemsToAllocate,
119 ArrayElementFreeFn elemFreeFn);
120
121
122
123 /* ArrayFree
124 * ----------
125 * Frees up all the memory for the array and elements. It DOES NOT
126 * automatically free memory owned by pointers embedded in the elements.
127 * This would require knowledge of the structure of the elements which the
128 * DArray does not have. However, it will iterate over the elements calling
129 * the elementFreeFn earlier supplied to ArrayNew and therefore, the client,
130 * who knows what the elements are, can do the appropriate deallocation of any
131 * embedded pointers through that function. After calling this, the value of
132 * what array is pointing to is undefined.
133 */
134void ArrayFree(DArray array);
135
136
137/* ArrayLength
138 * -----------
139 * Returns the logical length of the array, i.e. the number of elements
140 * currently in the array. Must run in constant time.
141 */
142int ArrayLength(const DArray array);
143
144
145/* ArrayNth
146 * --------
147 * Returns a pointer to the element numbered n in the specified array.
148 * Numbering begins with 0. An assert is raised if n is less than 0 or greater
149 * than the logical length minus 1. Note this function returns a pointer into
150 * the DArray's element storage, so the pointer should be used with care.
151 * This function must operate in constant time.
152 *
153 * We could have written the DArray without this sort of access, but it
154 * is useful and efficient to offer it, although the client needs to be
155 * careful when using it. In particular, a pointer returned by ArrayNth
156 * becomes invalid after any calls which involve insertion, deletion or
157 * sorting the array, as all of these may rearrange the element storage.
158 */
159void *ArrayNth(DArray array, int n);
160
161
162/* ArrayAppend
163 * -----------
164 * Adds a new element to the end of the specified array. The element is
165 * passed by address, the element contents are copied from the memory pointed
166 * to by newElem. Note that right after this call, the new element will be
167 * the last in the array; i.e. its element number will be the logical length
168 * minus 1. This function must run in constant time (neglecting
169 * the memory reallocation time which may be required occasionally).
170 */
171void ArrayAppend(DArray array, const void *newElem);
172
173/* ArrayInsertAt
174 * -------------
175 * Inserts a new element into the array, placing it at the position n.
176 * An assert is raised if n is less than 0 or greater than the logical length.
177 * The array elements after position n will be shifted over to make room. The
178 * element is passed by address, the new element's contents are copied from
179 * the memory pointed to by newElem. This function runs in linear time.
180 */
181void ArrayInsertAt(DArray array, const void *newElem, int n);
182
183/* ArrayInsertSorted
184 * -------------
185 * Inserts a new element into the array, placing it at the position indicated by
186 * a binary search of the array using comparator.
187 * The array MUST be sorted prior to calling InsertSorted.
188 * Note that if you only ever call InsertSorted, the array will always be sorted.
189 */
190void ArrayInsertSorted(DArray array, const void *newElem, ArrayCompareFn comparator);
191
192 /* ArrayDeleteAt
193 * -------------
194 * Deletes the element numbered n from the array. Before being removed,
195 * the elemFreeFn that was supplied to ArrayNew will be called on the element.
196 * An assert is raised if n is less than 0 or greater than the logical length
197 * minus one. All the elements after position n will be shifted over to fill
198 * the gap. This function runs in linear time. It does not shrink the
199 * allocated size of the array when an element is deleted, the array just
200 * stays over-allocated.
201 */
202void ArrayDeleteAt(DArray array, int n);
203
204 /* ArrayDeleteAt
205 * -------------
206 * Removes the element numbered n from the array. The element will not be freed
207 * before being removed. All the elements after position n will be shifted over to fill
208 * the gap. This function runs in linear time. It does not shrink the
209 * allocated size of the array when an element is deleted, the array just
210 * stays over-allocated.
211 */
212void ArrayRemoveAt(DArray array, int n);
213
214/* ArrayReplaceAt
215 * -------------
216 * Overwrites the element numbered n from the array with a new value. Before
217 * being overwritten, the elemFreeFn that was supplied to ArrayNew is called
218 * on the old element. Then that position in the array will get a new value by
219 * copying the new element's contents from the memory pointed to by newElem.
220 * An assert is raised if n is less than 0 or greater than the logical length
221 * minus one. None of the other elements are affected or rearranged by this
222 * operation and the size of the array remains constant. This function must
223 * operate in constant time.
224 */
225void ArrayReplaceAt(DArray array, const void *newElem, int n);
226
227
228/* ArraySort
229 * ---------
230 * Sorts the specified array into ascending order according to the supplied
231 * comparator. The numbering of the elements will change to reflect the
232 * new ordering. An assert is raised if the comparator is NULL.
233 */
234void ArraySort(DArray array, ArrayCompareFn comparator);
235
236
237#define NOT_FOUND -1 // returned when a search fails to find the key
238
239/* ArraySearch
240 * -----------
241 * Searches the specified array for an element whose contents match
242 * the element passed as the key. Uses the comparator argument to test
243 * for equality. The "fromIndex" parameter controls where the search
244 * starts looking from. If the client desires to search the entire array,
245 * they should pass 0 as the fromIndex. The function will search from
246 * there to the end of the array. The "isSorted" parameter allows the client
247 * to specify that the array is already in sorted order, and thus it uses a
248 * faster binary search. If isSorted is false, a simple linear search is
249 * used. If a match is found, the position of the matching element is returned
250 * else the function returns NOT_FOUND. Calling this function does not
251 * re-arrange or change contents of DArray or modify the key in any way.
252 * An assert is raised if fromIndex is less than 0 or greater than
253 * the logical length (although searching from logical length will never
254 * find anything, allowing this case means you can search an entirely empty
255 * array from 0 without getting an assert). An assert is raised if the
256 * comparator is NULL.
257 */
258int ArraySearch(DArray array, const void *key, ArrayCompareFn comparator,
259 int fromIndex, int isSorted);
260
261
262/* ArrayMap
263 * -----------
264 * Iterates through each element in the array in order (from element 0 to
265 * element n-1) and calls the function fn for that element. The function is
266 * called with the address of the array element and the clientData pointer.
267 * The clientData value allows the client to pass extra state information to
268 * the client-supplied function, if necessary. If no client data is required,
269 * this argument should be NULL. An assert is raised if map function is NULL.
270 */
271void ArrayMap(DArray array, ArrayMapFn fn, void *clientData);
272
273/* ArrayMapBackwards
274 * -----------
275 * Same as ArrayMap, but goes through the array from end to front. This
276 * makes it safe to free elements during the mapping.
277 */
278void ArrayMapBackwards(DArray array, ArrayMapFn fn, void *clientData);
279
280/* ArrayMap2
281 * -----------
282 * Same as ArrayMap, but allows the mapping to be stopped by returning 0
283 * from the mapping function. If the mapping was stopped, the element
284 * it was stopped at will be returned. If it wasn't stopped, then NULL
285 * will be returned.
286 */
287void * ArrayMap2(DArray array, ArrayMapFn2 fn, void *clientData);
288
289/* ArrayMapBackwards2
290 * ------------
291 * Goes through the array backwards, and allows you to stop the mapping.
292 */
293void * ArrayMapBackwards2(DArray array, ArrayMapFn2 fn, void *clientData);
294
295/* ArrayClear
296 * -----------
297 * Deletes all elements in the array, but without freeing the array.
298 */
299void ArrayClear(DArray array);
300
301/* ArrayGetDataPtr
302 * -----------
303 * Obtain the pointer to the actual data storage
304 */
305void *ArrayGetDataPtr(DArray array);
306
307/* ArraySetDataPtr
308 * -----------
309 * Set the pointer to the actual data storage, which must be allocated with malloc
310 */
311void ArraySetDataPtr(DArray array, void *ptr, int count, int capacity);
312
313#ifdef __cplusplus
314}
315#endif
316
317#endif //_DARRAY_
Definition darray.c:34