20#define rb_darray(T) struct { rb_darray_meta_t meta; T data[]; } *
26#define rb_darray_get(ary, idx) ((ary)->data[(idx)])
32#define rb_darray_set(ary, idx, element) ((ary)->data[(idx)] = (element))
38#define rb_darray_ref(ary, idx) (&((ary)->data[(idx)]))
44#define rb_darray_append(ptr_to_ary, element) do { \
45 rb_darray_ensure_space((ptr_to_ary), sizeof(**(ptr_to_ary)), \
46 sizeof((*(ptr_to_ary))->data[0])); \
47 rb_darray_set(*(ptr_to_ary), \
48 (*(ptr_to_ary))->meta.size, \
50 (*(ptr_to_ary))->meta.size++; \
56#define rb_darray_back(ary) ((ary)->data[(ary)->meta.size - 1])
60#define rb_darray_pop_back(ary) ((ary)->meta.size--)
63#define rb_darray_remove_unordered(ary, idx) do { \
64 rb_darray_set(ary, idx, rb_darray_back(ary)); \
65 rb_darray_pop_back(ary); \
70#define rb_darray_foreach(ary, idx_name, elem_ptr_var) \
71 for (size_t idx_name = 0; idx_name < rb_darray_size(ary) && ((elem_ptr_var) = rb_darray_ref(ary, idx_name)); ++idx_name)
75#define rb_darray_for(ary, idx_name) \
76 for (size_t idx_name = 0; idx_name < rb_darray_size(ary); ++idx_name)
84#define rb_darray_make(ptr_to_ary, size) \
85 rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), \
86 sizeof((*(ptr_to_ary))->data[0]))
88#define rb_darray_data_ptr(ary) ((ary)->data)
93#define rb_darray_clear(ary) (ary->meta.size = 0)
103rb_darray_size(
const void *ary)
106 return meta ? meta->size : 0;
112rb_darray_capa(
const void *ary)
115 return meta ? meta->capa : 0;
121rb_darray_free(
void *ary)
124 ruby_sized_xfree(ary, meta->capa);
131rb_darray_ensure_space(
void *ptr_to_ary,
size_t header_size,
size_t element_size)
135 size_t current_capa = rb_darray_capa(meta);
136 if (rb_darray_size(meta) < current_capa)
return;
139 size_t new_capa = current_capa == 0 ? 1 : current_capa * 2;
141 rb_darray_meta_t *doubled_ary = rb_xrealloc_mul_add(meta, new_capa, element_size, header_size);
143 assert(doubled_ary != NULL);
148 doubled_ary->size = 0;
151 doubled_ary->capa = new_capa;
155 memcpy(ptr_to_ary, &doubled_ary,
sizeof(doubled_ary));
159rb_darray_make_impl(
void *ptr_to_ary,
size_t array_size,
size_t header_size,
size_t element_size)
162 if (array_size == 0) {
163 *ptr_to_ptr_to_meta = NULL;
167 rb_darray_meta_t *meta = rb_xcalloc_mul_add(array_size, element_size, header_size);
169 assert(meta != NULL);
171 meta->size = array_size;
172 meta->capa = array_size;
176 memcpy(ptr_to_ary, &meta,
sizeof(meta));