17 #undef a_vec_push_fore
18 #undef a_vec_push_back
19 #undef a_vec_pull_fore
20 #undef a_vec_pull_back
22 static A_INLINE
void *a_vec_inc_(a_vec
*ctx
)
24 return (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
++;
27 static A_INLINE
void *a_vec_dec_(a_vec
*ctx
)
29 return (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* --ctx
->num_
;
32 static void a_vec_drop_(a_vec
*ctx
, a_size bot
, void (*dtor
)(void *))
36 while (ctx
->num_
> bot
) { dtor(a_vec_dec_(ctx
)); }
41 static int a_vec_alloc(a_vec
*ctx
, a_size num
)
45 a_size mem
= ctx
->mem_
;
47 mem
+= (mem
>> 1) + 1;
49 a_size
const siz
= a_size_up(sizeof(void *), ctx
->siz_
* mem
);
50 void *ptr
= a_alloc(ctx
->ptr_
, siz
);
51 if (a_unlikely(!ptr
)) { return A_FAILURE
; }
58 a_vec
*a_vec_new(a_size size
)
60 a_vec
*const ctx
= (a_vec
*)a_alloc(A_NULL
, sizeof(a_vec
));
61 if (ctx
) { a_vec_ctor(ctx
, size
); }
65 void a_vec_die(a_vec
*ctx
, void (*dtor
)(void *))
69 a_vec_dtor(ctx
, dtor
);
74 void a_vec_ctor(a_vec
*ctx
, a_size size
)
76 if (!size
) { size
= sizeof(a_cast
); }
83 void a_vec_dtor(a_vec
*ctx
, void (*dtor
)(void *))
87 a_vec_drop_(ctx
, 0, dtor
);
88 ctx
->ptr_
= a_alloc(ctx
->ptr_
, 0);
94 int a_vec_copy(a_vec
*ctx
, a_vec
const *obj
, int (*dup
)(void *, void const *))
96 ctx
->ptr_
= a_alloc(A_NULL
, obj
->mem_
* obj
->siz_
);
97 if (a_unlikely(!ctx
->ptr_
)) { return A_FAILURE
; }
98 ctx
->num_
= obj
->num_
;
99 ctx
->mem_
= obj
->mem_
;
100 ctx
->siz_
= obj
->siz_
;
103 a_byte
*dst
= (a_byte
*)ctx
->ptr_
;
104 a_byte
*src
= (a_byte
*)obj
->ptr_
;
105 for (a_size num
= obj
->num_
; num
; --num
)
114 a_copy(ctx
->ptr_
, obj
->ptr_
, obj
->num_
* obj
->siz_
);
119 void a_vec_move(a_vec
*ctx
, a_vec
*obj
)
121 a_copy(ctx
, obj
, sizeof(*obj
));
122 a_zero(obj
, sizeof(*obj
));
125 void a_vec_edit(a_vec
*ctx
, a_size size
, void (*dtor
)(void *))
127 if (!size
) { size
= sizeof(a_cast
); }
128 a_vec_drop_(ctx
, 0, dtor
);
129 ctx
->mem_
= ctx
->mem_
* ctx
->siz_
/ size
;
133 int a_vec_make(a_vec
*ctx
, a_size num
, void (*dtor
)(void *))
135 if (a_unlikely(a_vec_alloc(ctx
, num
))) { return A_FAILURE
; }
136 a_vec_drop_(ctx
, num
, dtor
);
140 void a_vec_drop(a_vec
*ctx
, void (*dtor
)(void *))
142 a_vec_drop_(ctx
, 0, dtor
);
145 void a_vec_swap(a_vec
const *ctx
, a_size lhs
, a_size rhs
)
147 a_size
const num
= ctx
->num_
- 1;
148 lhs
= lhs
< ctx
->num_
? lhs
: num
;
149 rhs
= rhs
< ctx
->num_
? rhs
: num
;
152 a_swap((a_byte
*)ctx
->ptr_
+ lhs
* ctx
->siz_
,
153 (a_byte
*)ctx
->ptr_
+ rhs
* ctx
->siz_
,
158 void a_vec_sort(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
160 qsort(ctx
->ptr_
, ctx
->num_
, ctx
->siz_
, cmp
);
163 void a_vec_sort_fore(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
167 a_byte
*ptr
= (a_byte
*)ctx
->ptr_
;
168 a_byte
*const end
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
- 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
!= end
);
181 void a_vec_sort_back(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
185 a_byte
*ptr
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
- ctx
->siz_
;
187 a_byte
*const cur
= ptr
- ctx
->siz_
;
188 if (cmp(cur
, ptr
) > 0)
190 a_swap(cur
, ptr
, ctx
->siz_
);
194 } while (ptr
!= ctx
->ptr_
);
198 void *a_vec_search(a_vec
const *ctx
, void const *obj
, int (*cmp
)(void const *, void const *))
200 return bsearch(obj
, ctx
->ptr_
, ctx
->num_
, ctx
->siz_
, cmp
);
203 void *a_vec_insert(a_vec
*ctx
, a_size idx
)
205 if (a_unlikely(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
208 a_byte
*const src
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 0);
209 a_byte
*const dst
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 1);
210 a_move(dst
, src
, (ctx
->num_
- idx
) * ctx
->siz_
);
214 return a_vec_inc_(ctx
);
217 void *a_vec_push_fore(a_vec
*ctx
) { return a_vec_insert(ctx
, 0); }
219 void *a_vec_push_back(a_vec
*ctx
)
221 if (a_unlikely(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
222 return a_vec_inc_(ctx
);
225 void *a_vec_remove(a_vec
*ctx
, a_size idx
)
227 if (ctx
->num_
&& idx
< ctx
->num_
- 1)
229 if (a_unlikely(a_vec_alloc(ctx
, ctx
->num_
))) { return A_NULL
; }
230 a_byte
*const ptr
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* ctx
->num_
;
231 a_byte
*const dst
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 0);
232 a_byte
*const src
= (a_byte
*)ctx
->ptr_
+ ctx
->siz_
* (idx
+ 1);
233 a_copy(ptr
, dst
, ctx
->siz_
);
234 a_move(dst
, src
, (a_size
)(ptr
- src
));
238 return a_likely(ctx
->num_
) ? a_vec_dec_(ctx
) : A_NULL
;
241 void *a_vec_pull_fore(a_vec
*ctx
) { return a_vec_remove(ctx
, 0); }
243 void *a_vec_pull_back(a_vec
*ctx
)
245 return a_likely(ctx
->num_
) ? a_vec_dec_(ctx
) : A_NULL
;