4 static A_INLINE
void *a_vec_inc_(a_vec
*ctx
)
6 return (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
++;
9 static A_INLINE
void *a_vec_dec_(a_vec
*ctx
)
11 return (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* --ctx
->num_
;
14 static void a_vec_drop_(a_vec
*ctx
, a_size bot
, void (*dtor
)(void *))
18 while (ctx
->num_
> bot
) { dtor(a_vec_dec_(ctx
)); }
23 static int a_vec_alloc(a_vec
*ctx
, a_size num
)
28 a_size mem
= ctx
->mem_
;
30 mem
+= (mem
>> 1) + 1;
32 ptr
= a_alloc(ctx
->ptr_
, a_size_up(sizeof(void *), ctx
->siz_
* mem
));
33 if (A_UNLIKELY(!ptr
)) { return A_FAILURE
; }
40 a_vec
*a_vec_new(a_size size
)
42 a_vec
*const ctx
= (a_vec
*)a_alloc(A_NULL
, sizeof(a_vec
));
43 if (ctx
) { a_vec_ctor(ctx
, size
); }
47 void a_vec_die(a_vec
*ctx
, void (*dtor
)(void *))
51 a_vec_dtor(ctx
, dtor
);
56 void a_vec_ctor(a_vec
*ctx
, a_size size
)
58 if (!size
) { size
= sizeof(void *); }
65 void a_vec_dtor(a_vec
*ctx
, void (*dtor
)(void *))
69 a_vec_drop_(ctx
, 0, dtor
);
70 ctx
->ptr_
= a_alloc(ctx
->ptr_
, 0);
76 int a_vec_copy(a_vec
*ctx
, a_vec
const *obj
, int (*dup
)(void *, void const *))
78 ctx
->ptr_
= a_alloc(A_NULL
, obj
->mem_
* obj
->siz_
);
79 if (A_UNLIKELY(!ctx
->ptr_
)) { return A_FAILURE
; }
80 ctx
->num_
= obj
->num_
;
81 ctx
->mem_
= obj
->mem_
;
82 ctx
->siz_
= obj
->siz_
;
86 a_byte
*dst
= (a_byte
*)ctx
->ptr_
;
87 a_byte
*src
= (a_byte
*)obj
->ptr_
;
88 for (num
= obj
->num_
; num
; --num
)
97 a_copy(ctx
->ptr_
, obj
->ptr_
, obj
->num_
* obj
->siz_
);
102 void a_vec_move(a_vec
*ctx
, a_vec
*obj
)
104 a_copy(ctx
, obj
, sizeof(*obj
));
105 a_zero(obj
, sizeof(*obj
));
108 void a_vec_edit(a_vec
*ctx
, a_size size
, void (*dtor
)(void *))
110 if (!size
) { size
= sizeof(void *); }
111 a_vec_drop_(ctx
, 0, dtor
);
112 ctx
->mem_
= ctx
->mem_
* ctx
->siz_
/ size
;
116 int a_vec_make(a_vec
*ctx
, a_size num
, void (*dtor
)(void *))
118 if (A_UNLIKELY(a_vec_alloc(ctx
, num
))) { return A_FAILURE
; }
119 a_vec_drop_(ctx
, num
, dtor
);
123 void a_vec_drop(a_vec
*ctx
, void (*dtor
)(void *))
125 a_vec_drop_(ctx
, 0, dtor
);
128 void a_vec_swap(a_vec
const *ctx
, a_size lhs
, a_size rhs
)
130 a_size
const num
= ctx
->num_
- 1;
131 lhs
= lhs
< ctx
->num_
? lhs
: num
;
132 rhs
= rhs
< ctx
->num_
? rhs
: num
;
135 a_swap((a_byte
*)ctx
->ptr_
+ lhs
* ctx
->siz_
,
136 (a_byte
*)ctx
->ptr_
+ rhs
* ctx
->siz_
,
141 void a_vec_sort(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
143 qsort(ctx
->ptr_
, ctx
->num_
, ctx
->siz_
, cmp
);
146 void a_vec_sort_fore(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
150 a_byte
*const end
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
151 a_byte
*const top
= end
- ctx
->siz_
;
152 a_byte
*ptr
= (a_byte
*)ctx
->ptr_
;
153 if (ctx
->num_
< ctx
->mem_
)
155 a_byte
*const pos
= ptr
;
157 a_byte
*const cur
= ptr
+ ctx
->siz_
;
158 if (cmp(pos
, cur
) <= 0) { break; }
160 } while (ptr
!= top
);
163 a_copy(end
, pos
, ctx
->siz_
);
164 a_move(pos
, pos
+ ctx
->siz_
, (a_size
)(ptr
- pos
));
165 a_copy(ptr
, end
, ctx
->siz_
);
171 a_byte
*const cur
= ptr
+ ctx
->siz_
;
172 if (cmp(ptr
, cur
) > 0)
174 a_swap(cur
, ptr
, ctx
->siz_
);
178 } while (ptr
!= top
);
183 void a_vec_sort_back(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
187 a_byte
*const end
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
188 a_byte
*ptr
= end
- ctx
->siz_
;
189 if (ctx
->num_
< ctx
->mem_
)
191 a_byte
*const pos
= ptr
;
193 a_byte
*const cur
= ptr
- ctx
->siz_
;
194 if (cmp(cur
, pos
) <= 0) { break; }
196 } while (ptr
!= ctx
->ptr_
);
199 a_copy(end
, pos
, ctx
->siz_
);
200 a_move(ptr
+ ctx
->siz_
, ptr
, (a_size
)(pos
- ptr
));
201 a_copy(ptr
, end
, ctx
->siz_
);
207 a_byte
*const cur
= ptr
- ctx
->siz_
;
208 if (cmp(cur
, ptr
) > 0)
210 a_swap(cur
, ptr
, ctx
->siz_
);
214 } while (ptr
!= ctx
->ptr_
);
219 void *a_vec_push_sort(a_vec
*ctx
, void const *key
, int (*cmp
)(void const *, void const *))
221 if (a_vec_alloc(ctx
, ctx
->num_
) == A_SUCCESS
)
223 a_byte
*ptr
= (a_byte
*)a_vec_inc_(ctx
);
226 a_byte
*const pos
= ptr
;
228 a_byte
*const cur
= ptr
- ctx
->siz_
;
229 if (cmp(cur
, key
) <= 0) { break; }
231 } while (ptr
!= ctx
->ptr_
);
234 a_move(ptr
+ ctx
->siz_
, ptr
, (a_size
)(pos
- ptr
));
242 void *a_vec_search(a_vec
const *ctx
, void const *obj
, int (*cmp
)(void const *, void const *))
244 return bsearch(obj
, ctx
->ptr_
, ctx
->num_
, ctx
->siz_
, cmp
);
247 void *a_vec_insert(a_vec
*ctx
, a_size idx
)
249 if (A_UNLIKELY(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
252 a_byte
*const src
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 0);
253 a_byte
*const dst
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 1);
254 a_move(dst
, src
, (ctx
->num_
- idx
) * ctx
->siz_
);
258 return a_vec_inc_(ctx
);
261 void *a_vec_push_fore(a_vec
*ctx
) { return a_vec_insert(ctx
, 0); }
263 void *a_vec_push_back(a_vec
*ctx
)
265 if (A_UNLIKELY(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
266 return a_vec_inc_(ctx
);
269 void *a_vec_remove(a_vec
*ctx
, a_size idx
)
271 if (ctx
->num_
&& idx
< ctx
->num_
- 1)
273 if (a_vec_alloc(ctx
, ctx
->num_
) == A_SUCCESS
)
275 a_byte
*const ptr
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
276 a_byte
*const dst
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 0);
277 a_byte
*const src
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 1);
278 a_size
const siz
= (a_size
)(ptr
- src
);
279 a_copy(ptr
, dst
, ctx
->siz_
);
280 a_move(dst
, src
, siz
);
286 return ctx
->num_
? a_vec_dec_(ctx
) : A_NULL
;
289 void *a_vec_pull_fore(a_vec
*ctx
) { return a_vec_remove(ctx
, 0); }
291 void *a_vec_pull_back(a_vec
*ctx
)
293 return ctx
->num_
? a_vec_dec_(ctx
) : A_NULL
;