]>
Dogcows Code - chaz/rasterize/blob - array.h
3 * CS5600 University of Utah
5 * mcgarvey@eng.utah.edu
15 #define ARRAY_CAPACITY_DEFAULT (128)
16 #define ARRAY_CAPACITY_MIN (4)
20 * A random-access dynamically-expandable array class.
29 typedef struct array array_t
;
32 * Allocate a new array with the element size and initial capacity.
34 array_t
* array_alloc2(size_t size
, size_t capacity
);
37 * Allocate a new array with the element size.
40 array_t
* array_alloc(size_t size
)
42 return array_alloc2(size
, ARRAY_CAPACITY_DEFAULT
);
45 #define array_alloc_type(T) array_alloc(sizeof(T))
46 #define array_alloc_type2(T, C) array_alloc2(sizeof(T), C)
49 * Destroy an array, freeing up its memory.
52 void array_destroy(array_t
* v
)
61 * An iterator class for the array.
69 typedef struct array_it array_it_t
;
72 * Initialize an array iterator.
75 void array_it_init(array_it_t
* it
, const array_t
* v
, size_t position
, int direction
)
85 * Index into a random position into the array.
88 void* array_index(const array_t
* v
, size_t i
)
91 return (char*)v
->arr
+ i
* v
->siz
;
95 * Get the first item in the array.
98 void* array_front(const array_t
* v
)
100 return array_index(v
, 0);
104 * Get the last item in the array.
107 void* array_back(const array_t
* v
)
109 return array_index(v
, v
->len
- 1);
114 * Get a forward iterator at the first item in the array.
117 array_it_t
array_begin(const array_t
* v
)
121 array_it_init(&it
, v
, 0, 1);
126 * Get a forward iterator after the last item in the array.
129 array_it_t
array_end(const array_t
* v
)
133 array_it_init(&it
, v
, v
->len
, 1);
138 * Get a backward iterator at the last item in the array.
141 array_it_t
array_rbegin(const array_t
* v
)
145 array_it_init(&it
, v
, v
->len
- 1, -1);
150 * Get a backward iterator before the first item in the array.
153 array_it_t
array_rend(const array_t
* v
)
157 array_it_init(&it
, v
, -1, -1);
163 * Get the current capacity of the array. The capacity is how many elements
164 * could be inserted into the array without reallocating more memory.
167 size_t array_capacity(const array_t
* v
)
174 * Make sure there is at least enough memory for a certain number of elements.
176 void array_reserve(array_t
* v
, size_t s
);
179 * Shrink the amount of memory used to fit what is currently inserted into the
180 * array and no more. Of course more memory can be reallocated later.
182 void array_done(array_t
* v
);
186 * Get the current number of items in the array. This is less than or equal
187 * to the capacity of the array.
190 size_t array_size(const array_t
* v
)
197 * Get whether or not the array is empty.
200 bool array_empty(const array_t
* v
)
202 return array_size(v
) == 0;
206 * Resize the array, either truncating or expanding the size.
209 void array_resize(array_t
* v
, size_t s
)
216 * Remove all items from the array.
219 void array_clear(array_t
* v
)
227 * Push an item onto the end of the array.
230 void array_push(array_t
* v
, void* e
)
233 size_t len
= v
->len
+ 1;
235 array_reserve(v
, len
);
237 memcpy(array_index(v
, v
->len
), e
, v
->siz
);
243 * Pop the item off of the end of the array. The item is returned, but its
244 * memory could be overwritten with addition array calls, so it must be copied
245 * if it needs to be kept.
248 void* array_pop(array_t
* v
)
251 return array_index(v
, --v
->len
);
256 * The type of function used when calling elements of the array.
258 typedef void (*array_call_fn_t
)(size_t i
, void* e
);
261 * Call a function once for each element of the array.
263 void array_call(const array_t
* v
, array_call_fn_t fn
);
267 * Get the element pointed to by an iterator and increment the iterator.
270 void* array_it_next(array_it_t
* it
)
273 if (it
->pos
< it
->arr
->len
) {
274 void* e
= array_index(it
->arr
, it
->pos
);
282 * Decrement the iterator and get the element pointed to by the iterator.
285 void* array_it_prev(array_it_t
* it
)
288 if (it
->pos
- it
->dir
< it
->arr
->len
) {
290 void* e
= array_index(it
->arr
, it
->pos
);
297 #define DEFINE_ARRAY_TYPE(T) DEFINE_ARRAY_TYPE2(T##_t, T)
298 #define DEFINE_ARRAY_TYPE2(T, N) \
299 INLINE_MAYBE array_t* array_##N##_alloc() \
301 return array_alloc(sizeof(T)); \
303 INLINE_MAYBE array_t* array_##N##_alloc2(size_t capacity) \
305 return array_alloc2(sizeof(T), capacity); \
307 INLINE_MAYBE T* array_##N##_index(const array_t* v, size_t i) \
309 return (T*)array_index(v, i); \
311 INLINE_MAYBE T* array_##N##_front(array_t* v) \
313 return (T*)array_front(v); \
315 INLINE_MAYBE T* array_##N##_back(array_t* v) \
317 return (T*)array_back(v); \
319 INLINE_MAYBE void array_##N##_push(array_t* v, T e) \
321 assert(v && v->arr); \
322 size_t len = v->len + 1; \
323 if (v->cap < len) { \
324 array_reserve(v, len); \
326 T* t = array_##N##_back(v); \
328 /* specialize with assignment copying rather than memcpy */ \
331 INLINE_MAYBE T* array_##N##_pop(array_t* v) \
333 return (T*)array_pop(v); \
335 typedef void (*array_##N##_call_fn_t)(size_t i, T* e); \
337 array_##N##_call(array_t* v, array_##N##_call_fn_t fn) \
339 array_call(v, (array_call_fn_t)fn); \
341 INLINE_MAYBE T* array_it_##N##_next(array_it_t* it) \
343 return (T*)array_it_next(it); \
345 INLINE_MAYBE T* array_it_##N##_prev(array_it_t* it) \
347 return (T*)array_it_prev(it); \
This page took 0.046252 seconds and 4 git commands to generate.