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)]))
45 #define rb_darray_append(ptr_to_ary, element) ( \
46 rb_darray_ensure_space((ptr_to_ary), sizeof(**(ptr_to_ary)), 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 (int 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 (int idx_name = 0; idx_name < rb_darray_size(ary); ++idx_name)
85 #define rb_darray_make(ptr_to_ary, size) rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), sizeof((*(ptr_to_ary))->data[0]))
90 #define rb_darray_clear(ary) (ary->meta.size = 0)
100 rb_darray_size(
const void *ary)
103 return meta ? meta->size : 0;
108 static inline int32_t
109 rb_darray_capa(
const void *ary)
112 return meta ? meta->capa : 0;
118 rb_darray_free(
void *ary)
125 rb_darray_buffer_size(int32_t capacity,
size_t header_size,
size_t element_size)
127 if (capacity == 0)
return 0;
128 return header_size + (size_t)capacity * element_size;
135 rb_darray_ensure_space(
void *ptr_to_ary,
size_t header_size,
size_t element_size)
139 int32_t current_capa = rb_darray_capa(meta);
140 if (rb_darray_size(meta) < current_capa)
return 1;
144 if (current_capa == 0) {
148 int64_t doubled = 2 * (int64_t)current_capa;
149 new_capa = (int32_t)doubled;
150 if (new_capa != doubled)
return 0;
154 size_t current_buffer_size = rb_darray_buffer_size(current_capa, header_size, element_size);
155 size_t new_buffer_size = rb_darray_buffer_size(new_capa, header_size, element_size);
156 if (new_buffer_size <= current_buffer_size)
return 0;
159 if (!doubled_ary)
return 0;
164 doubled_ary->size = 0;
167 doubled_ary->capa = new_capa;
171 memcpy(ptr_to_ary, &doubled_ary,
sizeof(doubled_ary));
176 rb_darray_make_impl(
void *ptr_to_ary, int32_t array_size,
size_t header_size,
size_t element_size)
179 if (array_size < 0)
return 0;
180 if (array_size == 0) {
181 *ptr_to_ptr_to_meta = NULL;
185 size_t buffer_size = rb_darray_buffer_size(array_size, header_size, element_size);
189 meta->size = array_size;
190 meta->capa = array_size;
194 memcpy(ptr_to_ary, &meta,
sizeof(meta));