3 static a_list
*a_que_new_(a_que
*ctx
)
8 node
= (a_list
*)a_alloc(A_NULL
, sizeof(a_list
) + ctx
->siz_
);
9 if (A_UNLIKELY(!node
)) { return node
; }
13 node
= ctx
->ptr_
[--ctx
->cur_
];
19 static int a_que_die_(a_que
*ctx
, a_list
*node
)
21 if (A_UNLIKELY(!node
)) { return A_INVALID
; }
22 if (ctx
->mem_
<= ctx
->cur_
)
24 a_size
const mem
= ctx
->mem_
+ (ctx
->mem_
>> 1) + 1;
25 a_list
**const ptr
= (a_list
**)a_alloc((void *)ctx
->ptr_
, sizeof(void *) * mem
);
26 if (A_UNLIKELY(!ptr
)) { return A_FAILURE
; }
30 ctx
->ptr_
[ctx
->cur_
++] = node
;
35 a_que
*a_que_new(a_size size
)
37 a_que
*const ctx
= (a_que
*)a_alloc(A_NULL
, sizeof(a_que
));
38 if (ctx
) { a_que_ctor(ctx
, size
); }
42 void a_que_die(a_que
*ctx
, void (*dtor
)(void *))
46 a_que_dtor(ctx
, dtor
);
51 void a_que_ctor(a_que
*ctx
, a_size size
)
53 if (!size
) { size
= sizeof(void *); }
54 a_list_ctor(&ctx
->head_
);
62 void a_que_dtor(a_que
*ctx
, void (*dtor
)(void *))
66 for (a_list
**node
= ctx
->ptr_
; ctx
->cur_
; --ctx
->cur_
)
71 a_list_forsafe_next(node
, next
, &ctx
->head_
)
79 for (a_list
**node
= ctx
->ptr_
; ctx
->cur_
; --ctx
->cur_
)
83 a_list_forsafe_next(node
, next
, &ctx
->head_
)
88 a_alloc((void *)ctx
->ptr_
, 0);
94 void a_que_move(a_que
*ctx
, a_que
*obj
)
96 a_copy(ctx
, obj
, sizeof(*obj
));
97 a_zero(obj
, sizeof(*obj
));
100 void *a_que_at(a_que
const *ctx
, a_diff idx
)
105 a_list_foreach_next(it
, &ctx
->head_
)
107 if (cur
++ == idx
) { return it
+ 1; }
112 a_list_foreach_prev(it
, &ctx
->head_
)
114 if (--cur
== idx
) { return it
+ 1; }
120 int a_que_drop(a_que
*ctx
, void (*dtor
)(void *))
122 a_list
*const head
= &ctx
->head_
;
123 for (a_list
*node
= head
->next
; node
!= head
; node
= head
->next
)
125 if (a_que_die_(ctx
, node
) == A_SUCCESS
)
127 a_list_del_node(node
);
130 else { return A_FAILURE
; }
134 a_size cur
= ctx
->cur_
;
135 a_list
**node
= ctx
->ptr_
;
136 for (; cur
; ++node
, --cur
)
144 int a_que_edit(a_que
*ctx
, a_size size
, void (*dtor
)(void *))
146 int ok
= a_que_drop(ctx
, dtor
);
149 if (!size
) { size
= sizeof(void *); }
150 if (size
> ctx
->siz_
)
152 a_size cur
= ctx
->cur_
;
153 a_list
**node
= ctx
->ptr_
;
154 for (; cur
; ++node
, --cur
)
156 void *const ptr
= a_alloc(*node
, sizeof(a_list
) + size
);
157 if (A_UNLIKELY(!ptr
)) { return A_FAILURE
; }
158 *node
= (a_list
*)ptr
;
166 int a_que_swap(a_que
const *ctx
, a_size lhs
, a_size rhs
)
171 a_size
const num
= ctx
->num_
- 1;
172 lhs
= lhs
< ctx
->num_
? lhs
: num
;
173 rhs
= rhs
< ctx
->num_
? rhs
: num
;
174 if (lhs
== rhs
) { return A_SUCCESS
; }
175 a_list_foreach_next(it
, &ctx
->head_
)
177 if (cur
== lhs
|| cur
== rhs
)
181 a_list_swap_node(it
, at
);
192 void a_que_sort_fore(a_que
const *ctx
, int (*cmp
)(void const *, void const *))
196 a_list
*const it
= ctx
->head_
.next
;
197 a_list
*at
= it
->next
;
199 if (cmp(it
+ 1, at
+ 1) <= 0) { break; }
201 } while (at
!= &ctx
->head_
);
204 at
= at
->prev
; // a-it-b-at-a => a-b-at-it-a
205 a_list_link(it
->prev
, it
->next
); // a-b
206 a_list_link(it
, at
->next
); // it-a
207 a_list_link(at
, it
); // at-it
212 void a_que_sort_back(a_que
const *ctx
, int (*cmp
)(void const *, void const *))
216 a_list
*const it
= ctx
->head_
.prev
;
217 a_list
*at
= it
->prev
;
219 if (cmp(at
+ 1, it
+ 1) <= 0) { break; }
221 } while (at
!= &ctx
->head_
);
224 at
= at
->next
; // a-at-b-it-a => a-it-at-b-a
225 a_list_link(it
->prev
, it
->next
); // b-a
226 a_list_link(at
->prev
, it
); // a-it
227 a_list_link(it
, at
); // it-at
232 void *a_que_push_sort(a_que
*ctx
, void const *key
, int (*cmp
)(void const *, void const *))
234 a_list
*it
= ctx
->head_
.prev
;
235 a_list
*const node
= a_que_new_(ctx
);
236 if (A_UNLIKELY(!node
)) { return node
; }
240 if (cmp(it
+ 1, key
) <= 0) { break; }
242 } while (it
!= &ctx
->head_
);
244 a_list_link(node
, it
->next
);
245 a_list_link(it
, node
);
249 void *a_que_push_fore(a_que
*ctx
)
251 a_list
*const node
= a_que_new_(ctx
);
252 if (A_UNLIKELY(!node
)) { return node
; }
253 a_list_add_next(&ctx
->head_
, node
);
257 void *a_que_push_back(a_que
*ctx
)
259 a_list
*const node
= a_que_new_(ctx
);
260 if (A_UNLIKELY(!node
)) { return node
; }
261 a_list_add_prev(&ctx
->head_
, node
);
265 void *a_que_pull_fore(a_que
*ctx
)
267 if (ctx
->head_
.next
!= &ctx
->head_
)
269 a_list
*const node
= (a_list
*)ctx
->head_
.next
;
270 if (a_que_die_(ctx
, node
) == A_SUCCESS
)
272 a_list_del_node(node
);
280 void *a_que_pull_back(a_que
*ctx
)
282 if (ctx
->head_
.prev
!= &ctx
->head_
)
284 a_list
*const node
= (a_list
*)ctx
->head_
.prev
;
285 if (a_que_die_(ctx
, node
) == A_SUCCESS
)
287 a_list_del_node(node
);
295 void *a_que_insert(a_que
*ctx
, a_size idx
)
300 a_list
*const node
= a_que_new_(ctx
);
303 a_list_foreach_next(it
, &ctx
->head_
)
307 a_list_add_prev(it
, node
);
315 return a_que_push_back(ctx
);
318 void *a_que_remove(a_que
*ctx
, a_size idx
)
323 a_list
*node
= A_NULL
;
324 a_list_foreach_next(it
, &ctx
->head_
)
332 if (a_que_die_(ctx
, node
) == A_SUCCESS
)
334 a_list_del_node(node
);
340 return a_que_pull_back(ctx
);