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 ctx
->_siz
= size
? size
: sizeof(a_cast
);
82 void a_vec_dtor(a_vec
*ctx
, void (*dtor
)(void *))
86 a_vec_drop_(ctx
, 0, dtor
);
87 ctx
->_ptr
= a_alloc(ctx
->_ptr
, 0);
93 int a_vec_copy(a_vec
*ctx
, a_vec
const *obj
, int (*dup
)(void *, void const *))
95 ctx
->_ptr
= a_alloc(A_NULL
, obj
->_mem
* obj
->_siz
);
96 if (a_unlikely(!ctx
->_ptr
)) { return A_FAILURE
; }
97 ctx
->_num
= obj
->_num
;
98 ctx
->_mem
= obj
->_mem
;
99 ctx
->_siz
= obj
->_siz
;
102 a_byte
*dst
= (a_byte
*)ctx
->_ptr
;
103 a_byte
*src
= (a_byte
*)obj
->_ptr
;
104 for (a_size num
= obj
->_num
; num
; --num
)
113 a_copy(ctx
->_ptr
, obj
->_ptr
, obj
->_num
* obj
->_siz
);
118 void a_vec_move(a_vec
*ctx
, a_vec
*obj
)
120 a_copy(ctx
, obj
, sizeof(*obj
));
121 a_zero(obj
, sizeof(*obj
));
124 void a_vec_edit(a_vec
*ctx
, a_size size
, void (*dtor
)(void *))
126 size
= size
? size
: sizeof(a_cast
);
127 a_vec_drop_(ctx
, 0, dtor
);
128 ctx
->_mem
= ctx
->_mem
* ctx
->_siz
/ size
;
132 int a_vec_make(a_vec
*ctx
, a_size num
, void (*dtor
)(void *))
134 if (a_unlikely(a_vec_alloc(ctx
, num
))) { return A_FAILURE
; }
135 a_vec_drop_(ctx
, num
, dtor
);
139 void a_vec_drop(a_vec
*ctx
, void (*dtor
)(void *))
141 a_vec_drop_(ctx
, 0, dtor
);
144 void a_vec_swap(a_vec
const *ctx
, a_size lhs
, a_size rhs
)
146 a_size
const num
= ctx
->_num
- 1;
147 lhs
= lhs
< ctx
->_num
? lhs
: num
;
148 rhs
= rhs
< ctx
->_num
? rhs
: num
;
151 a_swap((a_byte
*)ctx
->_ptr
+ lhs
* ctx
->_siz
,
152 (a_byte
*)ctx
->_ptr
+ rhs
* ctx
->_siz
,
157 void a_vec_sort(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
159 qsort(ctx
->_ptr
, ctx
->_num
, ctx
->_siz
, cmp
);
162 void a_vec_sort_fore(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
166 a_byte
*ptr
= (a_byte
*)ctx
->_ptr
;
167 a_byte
*const end
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* ctx
->_num
- ctx
->_siz
;
169 a_byte
*const cur
= ptr
+ ctx
->_siz
;
170 if (cmp(ptr
, cur
) > 0)
172 a_swap(cur
, ptr
, ctx
->_siz
);
176 } while (ptr
!= end
);
180 void a_vec_sort_back(a_vec
const *ctx
, int (*cmp
)(void const *, void const *))
184 a_byte
*ptr
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* ctx
->_num
- ctx
->_siz
;
186 a_byte
*const cur
= ptr
- ctx
->_siz
;
187 if (cmp(cur
, ptr
) > 0)
189 a_swap(cur
, ptr
, ctx
->_siz
);
193 } while (ptr
!= ctx
->_ptr
);
197 void *a_vec_search(a_vec
const *ctx
, void const *obj
, int (*cmp
)(void const *, void const *))
199 return bsearch(obj
, ctx
->_ptr
, ctx
->_num
, ctx
->_siz
, cmp
);
202 void *a_vec_insert(a_vec
*ctx
, a_size idx
)
204 if (a_unlikely(a_vec_alloc(ctx
, ctx
->_num
))) { return A_NULL
; }
207 a_byte
*const src
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* (idx
+ 0);
208 a_byte
*const dst
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* (idx
+ 1);
209 a_move(dst
, src
, (ctx
->_num
- idx
) * ctx
->_siz
);
213 return a_vec_inc_(ctx
);
216 void *a_vec_push_fore(a_vec
*ctx
) { return a_vec_insert(ctx
, 0); }
218 void *a_vec_push_back(a_vec
*ctx
)
220 if (a_unlikely(a_vec_alloc(ctx
, ctx
->_num
))) { return A_NULL
; }
221 return a_vec_inc_(ctx
);
224 void *a_vec_remove(a_vec
*ctx
, a_size idx
)
226 if (ctx
->_num
&& idx
< ctx
->_num
- 1)
228 if (a_unlikely(a_vec_alloc(ctx
, ctx
->_num
))) { return A_NULL
; }
229 a_byte
*const ptr
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* ctx
->_num
;
230 a_byte
*const dst
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* (idx
+ 0);
231 a_byte
*const src
= (a_byte
*)ctx
->_ptr
+ ctx
->_siz
* (idx
+ 1);
232 a_copy(ptr
, dst
, ctx
->_siz
);
233 a_move(dst
, src
, (a_size
)(ptr
- src
));
237 return a_likely(ctx
->_num
) ? a_vec_dec_(ctx
) : A_NULL
;
240 void *a_vec_pull_fore(a_vec
*ctx
) { return a_vec_remove(ctx
, 0); }
242 void *a_vec_pull_back(a_vec
*ctx
)
244 return a_likely(ctx
->_num
) ? a_vec_dec_(ctx
) : A_NULL
;