|
Cedro
|
Go to the documentation of this file.
13 #define DEFINE_ARRAY_OF(T, PADDING, DESTRUCT_BLOCK) \
21 typedef struct T##_array { \
28 } mut_##T##_array, * const mut_##T##_array_p, * mut_##T##_array_mut_p; \
29 typedef const struct T##_array \
30 T##_array, * const T##_array_p, * T##_array_mut_p; \
38 typedef struct T##_array_slice { \
43 } mut_##T##_array_slice, * const mut_##T##_array_slice_p, \
44 * mut_##T##_array_slice_mut_p; \
45 typedef const struct T##_array_slice \
46 T##_array_slice, * const T##_array_slice_p, \
47 * T##_array_slice_mut_p; \
62 typedef struct T##_array_mut_slice { \
64 mut_##T##_mut_p start_p; \
66 mut_##T##_mut_p end_p; \
68 mut_##T##_array_mut_slice, \
70 * const mut_##T##_array_mut_slice_p, \
72 * mut_##T##_array_mut_slice_mut_p; \
86 typedef struct T##_array_mut_slice \
88 T##_array_mut_slice, \
90 * const T##_array_mut_slice_p, \
92 * T##_array_mut_slice_mut_p; \
98 init_##T##_array_slice(mut_##T##_array_slice_p _, \
99 T##_array_p array_p, \
100 size_t start, size_t end) \
102 _->start_p = array_p->start + start; \
103 if (end) _->end_p = array_p->start + end; \
104 else _->end_p = array_p->start + array_p->len; \
111 init_##T##_array_mut_slice(mut_##T##_array_mut_slice_p _, \
112 mut_##T##_array_mut_p array_p, \
113 size_t start, size_t end) \
115 _->start_p = (mut_##T##_mut_p) array_p->start + start; \
116 if (end) _->end_p = (mut_##T##_mut_p) array_p->start + end; \
117 else _->end_p = (mut_##T##_mut_p) array_p->start + array_p->len; \
121 destruct_##T##_block(mut_##T##_mut_p cursor, T##_p end) \
136 init_##T##_array(mut_##T##_array_p _, size_t initial_capacity) \
139 _->capacity = initial_capacity + PADDING; \
140 _->start = _->capacity? malloc(_->capacity * sizeof(*_->start)): NULL;\
156 init_from_constant_##T##_array(mut_##T##_array_p _, \
157 T* items, size_t len) \
167 static mut_##T##_array \
168 new_##T##_array(size_t initial_capacity) \
171 init_##T##_array(&_, initial_capacity); \
176 static mut_##T##_array_p \
177 new_##T##_array_p(size_t initial_capacity) \
179 mut_##T##_array_p _ = malloc(sizeof(T##_array)); \
180 if (_) init_##T##_array(_, initial_capacity); \
188 destruct_##T##_array(mut_##T##_array_p _) \
190 if (_->capacity is_not 0) { \
192 destruct_##T##_block((mut_##T##_p) _->start, _->start + _->len); \
193 free((mut_##T##_mut_p) (_->start)); \
194 *((mut_##T##_mut_p *) &(_->start)) = NULL; \
206 free_##T##_array(mut_##T##_array_p _) \
208 destruct_##T##_array(_); \
223 static mut_##T##_array \
224 move_##T##_array(mut_##T##_array_p _) \
226 mut_##T##_array transferred_copy = *_; \
229 *((mut_##T##_mut_p *) &(_->start)) = NULL; \
230 return transferred_copy; \
236 ensure_capacity_##T##_array(mut_##T##_array_p _, size_t minimum) \
238 minimum += PADDING; \
239 if (minimum <= _->capacity) return; \
240 if (_->capacity is 0) { \
242 _->capacity = minimum + PADDING; \
243 _->start = malloc(_->capacity * sizeof(*_->start)); \
245 _->capacity = 2*_->capacity + PADDING; \
246 if (minimum > _->capacity) _->capacity = minimum; \
247 _->start = realloc((void*) _->start, \
248 _->capacity * sizeof(*_->start)); \
255 push_##T##_array(mut_##T##_array_p _, T item) \
257 ensure_capacity_##T##_array(_, _->len + 1); \
258 *((mut_##T##_p) _->start + _->len++) = item; \
270 splice_##T##_array(mut_##T##_array_p _, \
271 size_t position, size_t delete, \
272 mut_##T##_array_p deleted, \
273 T##_array_slice insert) \
275 assert(position + delete <= _->len); \
277 T##_array_slice slice = { \
278 .start_p = (mut_##T##_p) _->start + position, \
279 .end_p = (mut_##T##_p) _->start + position + delete \
281 splice_##T##_array(deleted, deleted->len, 0, NULL, slice); \
283 destruct_##T##_block((mut_##T##_p) _->start + position, \
284 _->start + position + delete); \
287 size_t insert_len = 0; \
288 size_t new_len = _->len - delete; \
289 if (insert.start_p is_not insert.end_p) { \
290 assert(_->start > insert.end_p || \
291 _->start + _->len < insert.start_p); \
292 assert(insert.end_p >= insert.start_p); \
293 insert_len = (size_t)(insert.end_p - insert.start_p); \
294 new_len += insert_len; \
295 ensure_capacity_##T##_array(_, new_len); \
298 size_t gap_end = position + insert_len; \
299 memmove((void*) (_->start + gap_end), \
300 _->start + position + delete, \
301 (_->len - delete - position) * sizeof(*_->start)); \
302 _->len = _->len + insert_len - delete; \
304 memcpy((void*) (_->start + position), \
306 insert_len * sizeof(*_->start)); \
314 append_##T##_array(mut_##T##_array_p _, T##_array_slice insert) \
316 splice_##T##_array(_, _->len, 0, NULL, insert); \
323 delete_##T##_array(mut_##T##_array_p _, size_t position, size_t delete) \
325 assert(position + delete <= _->len); \
326 destruct_##T##_block((mut_##T##_p) _->start + position, \
327 _->start + position + delete); \
329 memmove((void*) (_->start + position), \
330 _->start + position + delete, \
331 (_->len - delete - position) * sizeof(*_->start)); \
340 pop_##T##_array(mut_##T##_array_p _, mut_##T##_p item_p) \
342 if (not _->len) return; \
343 mut_##T##_p last_p = (mut_##T##_p) _->start + _->len - 1; \
344 if (item_p) memmove((void*) last_p, item_p, sizeof(*_->start)); \
345 else destruct_##T##_block((mut_##T##_p) last_p, last_p + 1); \
352 get_##T##_array(T##_array_p _, size_t position) \
354 assert(position < _->len); \
355 return _->start + position; \
361 get_mut_##T##_array(T##_array_p _, size_t position) \
363 assert(position < _->len); \
364 return (mut_##T##_p) _->start + position; \
369 start_of_##T##_array(T##_array_p _) \
376 end_of_##T##_array(T##_array_p _) \
378 return _->start + _->len; \
382 static T##_array_slice \
383 bounds_of_##T##_array(T##_array_p _) \
385 return (T##_array_slice){ _->start, _->start + _->len }; \
390 start_of_mut_##T##_array(mut_##T##_array_p _) \
392 return (mut_##T##_p) _->start; \
397 end_of_mut_##T##_array(mut_##T##_array_p _) \
399 return (mut_##T##_p) _->start + _->len; \
403 static mut_##T##_array_slice \
404 bounds_of_mut_##T##_array(mut_##T##_array_p _) \
406 return (mut_##T##_array_slice){ _->start, _->start + _->len }; \
411 index_##T##_array(T##_array_p _, T##_p pointer) \
413 return (size_t)(pointer - _->start); \
415 static const size_t PADDING_##T##_ARRAY = PADDING