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
)
27 a_size mem
= ctx
->mem_
;
29 mem
+= (mem
>> 1) + 1;
31 a_size
const siz
= a_size_up(sizeof(void *), ctx
->siz_
* mem
);
32 void *ptr
= a_alloc(ctx
->ptr_
, siz
);
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_
;
85 a_byte
*dst
= (a_byte
*)ctx
->ptr_
;
86 a_byte
*src
= (a_byte
*)obj
->ptr_
;
87 for (a_size num
= obj
->num_
; num
; --num
)
96 a_copy(ctx
->ptr_
, obj
->ptr_
, obj
->num_
* obj
->siz_
);
101 void a_vec_move(a_vec
*ctx
, a_vec
*obj
)
103 a_copy(ctx
, obj
, sizeof(*obj
));
104 a_zero(obj
, sizeof(*obj
));
107 void a_vec_edit(a_vec
*ctx
, a_size size
, void (*dtor
)(void *))
109 if (!size
) { size
= sizeof(void *); }
110 a_vec_drop_(ctx
, 0, dtor
);
111 ctx
->mem_
= ctx
->mem_
* ctx
->siz_
/ size
;
115 int a_vec_make(a_vec
*ctx
, a_size num
, void (*dtor
)(void *))
117 if (A_UNLIKELY(a_vec_alloc(ctx
, num
))) { return A_FAILURE
; }
118 a_vec_drop_(ctx
, num
, dtor
);
122 void a_vec_drop(a_vec
*ctx
, void (*dtor
)(void *))
124 a_vec_drop_(ctx
, 0, dtor
);
127 void a_vec_swap(a_vec
const *ctx
, a_size lhs
, a_size rhs
)
129 a_size
const num
= ctx
->num_
- 1;
130 lhs
= lhs
< ctx
->num_
? lhs
: num
;
131 rhs
= rhs
< ctx
->num_
? rhs
: num
;
134 a_swap((a_byte
*)ctx
->ptr_
+ lhs
* ctx
->siz_
,
135 (a_byte
*)ctx
->ptr_
+ rhs
* ctx
->siz_
,
140 void a_vec_sort(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
142 qsort(ctx
->ptr_
, ctx
->num_
, ctx
->siz_
, cmp
);
145 void a_vec_sort_fore(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
149 a_byte
*const end
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
150 a_byte
*const top
= end
- ctx
->siz_
;
151 a_byte
*ptr
= (a_byte
*)ctx
->ptr_
;
152 if (ctx
->num_
< ctx
->mem_
)
154 a_byte
*const pos
= ptr
;
156 a_byte
*const cur
= ptr
+ ctx
->siz_
;
157 if (cmp(pos
, cur
) <= 0) { break; }
159 } while (ptr
!= top
);
162 a_copy(end
, pos
, ctx
->siz_
);
163 a_move(pos
, pos
+ ctx
->siz_
, (a_size
)(ptr
- pos
));
164 a_copy(ptr
, end
, ctx
->siz_
);
170 a_byte
*const cur
= ptr
+ ctx
->siz_
;
171 if (cmp(ptr
, cur
) > 0)
173 a_swap(cur
, ptr
, ctx
->siz_
);
177 } while (ptr
!= top
);
182 void a_vec_sort_back(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
186 a_byte
*const end
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
187 a_byte
*ptr
= end
- ctx
->siz_
;
188 if (ctx
->num_
< ctx
->mem_
)
190 a_byte
*const pos
= ptr
;
192 a_byte
*const cur
= ptr
- ctx
->siz_
;
193 if (cmp(cur
, pos
) <= 0) { break; }
195 } while (ptr
!= ctx
->ptr_
);
198 a_copy(end
, pos
, ctx
->siz_
);
199 a_move(ptr
+ ctx
->siz_
, ptr
, (a_size
)(pos
- ptr
));
200 a_copy(ptr
, end
, ctx
->siz_
);
206 a_byte
*const cur
= ptr
- ctx
->siz_
;
207 if (cmp(cur
, ptr
) > 0)
209 a_swap(cur
, ptr
, ctx
->siz_
);
213 } while (ptr
!= ctx
->ptr_
);
218 void *a_vec_push_sort(a_vec
*ctx
, void const *key
, int (*cmp
)(void const *, void const *))
220 if (a_vec_alloc(ctx
, ctx
->num_
) == A_SUCCESS
)
222 a_byte
*ptr
= (a_byte
*)a_vec_inc_(ctx
);
225 a_byte
*const pos
= ptr
;
227 a_byte
*const cur
= ptr
- ctx
->siz_
;
228 if (cmp(cur
, key
) <= 0) { break; }
230 } while (ptr
!= ctx
->ptr_
);
233 a_move(ptr
+ ctx
->siz_
, ptr
, (a_size
)(pos
- ptr
));
241 void *a_vec_search(a_vec
const *ctx
, void const *obj
, int (*cmp
)(void const *, void const *))
243 return bsearch(obj
, ctx
->ptr_
, ctx
->num_
, ctx
->siz_
, cmp
);
246 void *a_vec_insert(a_vec
*ctx
, a_size idx
)
248 if (A_UNLIKELY(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
251 a_byte
*const src
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 0);
252 a_byte
*const dst
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 1);
253 a_move(dst
, src
, (ctx
->num_
- idx
) * ctx
->siz_
);
257 return a_vec_inc_(ctx
);
260 void *a_vec_push_fore(a_vec
*ctx
) { return a_vec_insert(ctx
, 0); }
262 void *a_vec_push_back(a_vec
*ctx
)
264 if (A_UNLIKELY(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
265 return a_vec_inc_(ctx
);
268 void *a_vec_remove(a_vec
*ctx
, a_size idx
)
270 if (ctx
->num_
&& idx
< ctx
->num_
- 1)
272 if (A_UNLIKELY(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
273 a_byte
*const ptr
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
274 a_byte
*const dst
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 0);
275 a_byte
*const src
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 1);
276 a_copy(ptr
, dst
, ctx
->siz_
);
277 a_move(dst
, src
, (a_size
)(ptr
- src
));
281 return ctx
->num_
? a_vec_dec_(ctx
) : A_NULL
;
284 void *a_vec_pull_fore(a_vec
*ctx
) { return a_vec_remove(ctx
, 0); }
286 void *a_vec_pull_back(a_vec
*ctx
)
288 return ctx
->num_
? a_vec_dec_(ctx
) : A_NULL
;