21#define rb_darray(T) struct { rb_darray_meta_t meta; T data[]; } *
27#define rb_darray_get(ary, idx) ((ary)->data[(idx)])
33#define rb_darray_set(ary, idx, element) ((ary)->data[(idx)] = (element))
39#define rb_darray_ref(ary, idx) (&((ary)->data[(idx)]))
45#define rb_darray_append(ptr_to_ary, element) \
46 rb_darray_append_impl(ptr_to_ary, element, rb_darray_realloc_mul_add)
48#define rb_darray_append_without_gc(ptr_to_ary, element) \
49 rb_darray_append_impl(ptr_to_ary, element, rb_darray_realloc_mul_add_without_gc)
51#define rb_darray_append_impl(ptr_to_ary, element, realloc_func) do { \
52 rb_darray_ensure_space((ptr_to_ary), \
53 sizeof(**(ptr_to_ary)), \
54 sizeof((*(ptr_to_ary))->data[0]), \
56 rb_darray_set(*(ptr_to_ary), \
57 (*(ptr_to_ary))->meta.size, \
59 (*(ptr_to_ary))->meta.size++; \
62#define rb_darray_insert_without_gc(ptr_to_ary, idx, element) do { \
63 rb_darray_ensure_space((ptr_to_ary), \
64 sizeof(**(ptr_to_ary)), \
65 sizeof((*(ptr_to_ary))->data[0]), \
66 rb_darray_realloc_mul_add_without_gc); \
68 rb_darray_ref(*(ptr_to_ary), idx + 1), \
69 rb_darray_ref(*(ptr_to_ary), idx), \
70 (*(ptr_to_ary))->data[0], \
71 rb_darray_size(*(ptr_to_ary)) - idx); \
72 rb_darray_set(*(ptr_to_ary), idx, element); \
73 (*(ptr_to_ary))->meta.size++; \
78#define rb_darray_foreach(ary, idx_name, elem_ptr_var) \
79 for (size_t idx_name = 0; idx_name < rb_darray_size(ary) && ((elem_ptr_var) = rb_darray_ref(ary, idx_name)); ++idx_name)
83#define rb_darray_for(ary, idx_name) \
84 for (size_t idx_name = 0; idx_name < rb_darray_size(ary); ++idx_name)
93#define rb_darray_make(ptr_to_ary, size) \
94 rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), \
95 sizeof((*(ptr_to_ary))->data[0]), rb_darray_calloc_mul_add)
97#define rb_darray_make_without_gc(ptr_to_ary, size) \
98 rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), \
99 sizeof((*(ptr_to_ary))->data[0]), rb_darray_calloc_mul_add_without_gc)
106#define rb_darray_resize_capa_without_gc(ptr_to_ary, capa) \
107 rb_darray_resize_capa_impl((ptr_to_ary), capa, sizeof(**(ptr_to_ary)), \
108 sizeof((*(ptr_to_ary))->data[0]), rb_darray_realloc_mul_add_without_gc)
110#define rb_darray_data_ptr(ary) ((ary)->data)
120rb_darray_clear(
void *ary)
131rb_darray_size(
const void *ary)
134 return meta ? meta->size : 0;
139#define rb_darray_memsize(ary) (sizeof(*(ary)) + (rb_darray_size(ary) * sizeof((ary)->data[0])))
142rb_darray_pop(
void *ary,
size_t count)
151rb_darray_capa(
const void *ary)
154 return meta ? meta->capa : 0;
159rb_darray_free(
void *ary)
165rb_darray_free_sized0(
void *ary,
size_t element_size)
169 ruby_xfree_sized(ary,
sizeof(*meta) + (element_size * meta->capa));
172#define rb_darray_free_sized(ary, T) rb_darray_free_sized0((ary), sizeof(T))
175rb_darray_free_without_gc(
void *ary)
182rb_darray_calloc_mul_add(
size_t x,
size_t y,
size_t z)
184 size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(x, y), z);
194rb_darray_calloc_mul_add_without_gc(
size_t x,
size_t y,
size_t z)
196 size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(x, y), z);
198 void *ptr = calloc(1, size);
199 if (ptr == NULL) rb_bug(
"rb_darray_calloc_mul_add_without_gc: failed");
204void *ruby_xrealloc_sized(
void *ptr,
size_t new_size,
size_t old_size);
208rb_darray_realloc_mul_add(
void *orig_ptr,
size_t capa,
size_t element_size,
size_t header_size)
210 size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(
capa, element_size), header_size);
211 size_t old_size = (rb_darray_capa(orig_ptr) * element_size) + header_size;
213 void *ptr = ruby_xrealloc_sized(orig_ptr, size, old_size);
221rb_darray_realloc_mul_add_without_gc(
void *orig_ptr,
size_t x,
size_t y,
size_t z)
223 size_t size = rbimpl_size_add_or_raise(rbimpl_size_mul_or_raise(x, y), z);
225 void *ptr = realloc(orig_ptr, size);
226 if (ptr == NULL) rb_bug(
"rb_darray_realloc_mul_add_without_gc: failed");
234rb_darray_resize_capa_impl(
void *ptr_to_ary,
size_t new_capa,
size_t header_size,
size_t element_size,
235 void *(*realloc_mul_add_impl)(
void *,
size_t,
size_t,
size_t))
240 rb_darray_meta_t *new_ary = realloc_mul_add_impl(meta, new_capa, element_size, header_size);
250 new_ary->capa = new_capa;
254 memcpy(ptr_to_ary, &new_ary,
sizeof(new_ary));
261rb_darray_ensure_space(
void *ptr_to_ary,
size_t header_size,
size_t element_size,
262 void *(*realloc_mul_add_impl)(
void *,
size_t,
size_t,
size_t))
266 size_t current_capa = rb_darray_capa(meta);
267 if (rb_darray_size(meta) < current_capa)
return;
270 size_t new_capa = current_capa == 0 ? 1 : current_capa * 2;
272 rb_darray_resize_capa_impl(ptr_to_ary, new_capa, header_size, element_size, realloc_mul_add_impl);
276rb_darray_make_impl(
void *ptr_to_ary,
size_t array_size,
size_t header_size,
size_t element_size,
277 void *(*calloc_mul_add_impl)(
size_t,
size_t,
size_t))
280 if (array_size == 0) {
281 *ptr_to_ptr_to_meta = NULL;
285 rb_darray_meta_t *meta = calloc_mul_add_impl(array_size, element_size, header_size);
287 meta->size = array_size;
288 meta->capa = array_size;
292 memcpy(ptr_to_ary, &meta,
sizeof(meta));
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define xfree
Old name of ruby_xfree.
#define xcalloc
Old name of ruby_xcalloc.
int capa
Designed capacity of the buffer.