fix when -DLIBA_JAVASCRIPT=1 and -DLIBA_CXX=0
[liba.git] / src / que.c
blobcda7f313b4eafac75139f0d2dde690b4a4f8559d
1 #include "a/que.h"
3 #undef a_que_at
4 #undef a_que_fore
5 #undef a_que_back
6 #undef a_que_fore_
7 #undef a_que_back_
8 #undef a_que_insert
9 #undef a_que_remove
10 #undef a_que_push_fore
11 #undef a_que_push_back
12 #undef a_que_pull_fore
13 #undef a_que_pull_back
15 static a_que_node *a_que_node_new(a_que *ctx)
17 a_que_node *node = A_NULL;
18 if (ctx->_cur)
20 node = ctx->_ptr[--ctx->_cur];
22 else
24 node = (a_que_node *)a_alloc(A_NULL, sizeof(a_que_node));
25 if (a_unlikely(!node)) { return node; }
26 node->_data = A_NULL;
28 if (!node->_data)
30 node->_data = a_alloc(A_NULL, ctx->_siz);
31 if (a_unlikely(!node->_data))
33 a_alloc(node, 0);
34 return A_NULL;
37 ++ctx->_num;
38 return node;
41 static int a_que_node_die(a_que *ctx, a_que_node *obj)
43 if (!obj) { return A_INVALID; }
44 if (ctx->_mem <= ctx->_cur)
46 a_size const mem = ctx->_mem + (ctx->_mem >> 1) + 1;
47 a_que_node **const ptr = (a_que_node **)a_alloc(ctx->_ptr, sizeof(void *) * mem);
48 if (a_unlikely(!ptr)) { return A_FAILURE; }
49 ctx->_ptr = ptr;
50 ctx->_mem = mem;
52 ctx->_ptr[ctx->_cur++] = obj;
53 --ctx->_num;
54 return A_SUCCESS;
57 static void a_que_drop_(a_que *ctx)
59 while (ctx->_head.next != &ctx->_head)
61 a_que_node *const node = (a_que_node *)ctx->_head.next;
62 if (a_unlikely(a_que_node_die(ctx, node))) { break; }
63 a_list_del_node(&node->_node);
64 a_list_dtor(&node->_node);
68 a_que *a_que_new(a_size size)
70 a_que *const ctx = (a_que *)a_alloc(A_NULL, sizeof(a_que));
71 if (ctx) { a_que_ctor(ctx, size); }
72 return ctx;
75 void a_que_die(a_que *ctx, void (*dtor)(void *))
77 if (ctx)
79 a_que_dtor(ctx, dtor);
80 a_alloc(ctx, 0);
84 void a_que_ctor(a_que *ctx, a_size size)
86 a_list_ctor(&ctx->_head);
87 ctx->_siz = size ? size : sizeof(a_cast);
88 ctx->_ptr = A_NULL;
89 ctx->_num = 0;
90 ctx->_cur = 0;
91 ctx->_mem = 0;
94 void a_que_dtor(a_que *ctx, void (*dtor)(void *))
96 a_que_node **node;
97 a_que_drop_(ctx);
98 node = ctx->_ptr;
99 if (dtor)
101 for (; ctx->_cur; ++node, --ctx->_cur)
103 dtor((**node)._data);
104 a_alloc((**node)._data, 0);
105 a_alloc(*node, 0);
108 else
110 for (; ctx->_cur; ++node, --ctx->_cur)
112 a_alloc((**node)._data, 0);
113 a_alloc(*node, 0);
116 a_alloc(ctx->_ptr, 0);
117 ctx->_ptr = A_NULL;
118 ctx->_siz = 0;
119 ctx->_mem = 0;
122 void a_que_move(a_que *ctx, a_que *obj)
124 a_copy(ctx, obj, sizeof(*obj));
125 a_zero(obj, sizeof(*obj));
128 void *a_que_at(a_que const *ctx, a_imax idx)
130 void *ptr = A_NULL;
131 a_imax cur = 0;
132 if (idx < 0)
134 a_list_foreach_prev(it, &ctx->_head)
136 if (--cur == idx)
138 ptr = ((a_que_node *)it)->_data;
139 break;
143 else
145 a_list_foreach_next(it, &ctx->_head)
147 if (cur++ == idx)
149 ptr = ((a_que_node *)it)->_data;
150 break;
154 return ptr;
157 void a_que_drop(a_que *ctx, void (*dtor)(void *))
159 a_que_node **node;
160 a_que_drop_(ctx);
161 node = ctx->_ptr;
162 if (dtor)
164 for (a_size cur = ctx->_cur; cur; ++node, --cur)
166 dtor((**node)._data);
167 a_alloc((**node)._data, 0);
168 (**node)._data = A_NULL;
171 else
173 for (a_size cur = ctx->_cur; cur; ++node, --cur)
175 a_alloc((**node)._data, 0);
176 (**node)._data = A_NULL;
181 void a_que_edit(a_que *ctx, a_size size, void (*dtor)(void *))
183 size = size ? size : sizeof(a_cast);
184 a_que_drop(ctx, dtor);
185 ctx->_siz = size;
188 int a_que_swap_(a_que const *ctx, void *lhs, void *rhs)
190 int ok = A_FAILURE;
191 a_que_node *l = A_NULL;
192 a_que_node *r = A_NULL;
193 if (lhs == rhs) { return A_SUCCESS; }
194 a_list_foreach_next(it, &ctx->_head)
196 a_que_node *const node = (a_que_node *)it;
197 if (node->_data == lhs || node->_data == rhs)
199 if (!l)
201 l = node;
203 else
205 r = node;
208 if (r)
210 a_list_swap_node(&l->_node, &r->_node);
211 ok = A_SUCCESS;
212 break;
215 return ok;
218 void a_que_swap(a_que const *ctx, a_size lhs, a_size rhs)
220 a_size cur = 0;
221 a_size const num = ctx->_num - 1;
222 lhs = lhs < ctx->_num ? lhs : num;
223 rhs = rhs < ctx->_num ? rhs : num;
224 if (lhs != rhs)
226 a_que_node *l = A_NULL;
227 a_que_node *r = A_NULL;
228 a_list_foreach_next(it, &ctx->_head)
230 if (cur == lhs || cur == rhs)
232 // because lhs less than num
233 // it's never a null pointer
234 if (!l)
236 l = (a_que_node *)it;
238 else
240 r = (a_que_node *)it;
242 if (!it) { break; }
244 if (r)
246 a_list_swap_node(&l->_node, &r->_node);
247 break;
249 ++cur;
254 void a_que_sort_fore(a_que const *ctx, int (*cmp)(void const *, void const *))
256 if (ctx->_num > 1)
258 a_list *pt = A_NULL;
259 a_list *const it = ctx->_head.next;
260 for (a_list *at = it->next; at != &ctx->_head; at = at->next)
262 void *const lhs = ((a_que_node *)it)->_data;
263 void *const rhs = ((a_que_node *)at)->_data;
264 if (cmp(lhs, rhs) > 0) { pt = at; }
265 else { break; }
267 if (pt)
269 /* a<->it<->b<->pt<->a */
270 a_list_link(it->prev, it->next); // a<->b
271 a_list_link(it, pt->next); // it<->a
272 a_list_link(pt, it); // pt<->it
273 /* a<->b<->pt<->it<->a */
278 void a_que_sort_back(a_que const *ctx, int (*cmp)(void const *, void const *))
280 if (ctx->_num > 1)
282 a_list *pt = A_NULL;
283 a_list *const it = ctx->_head.prev;
284 for (a_list *at = it->prev; at != &ctx->_head; at = at->prev)
286 void *const lhs = ((a_que_node *)at)->_data;
287 void *const rhs = ((a_que_node *)it)->_data;
288 if (cmp(lhs, rhs) > 0) { pt = at; }
289 else { break; }
291 if (pt)
293 /* a<->pt<->b<->it<->a */
294 a_list_link(it->prev, it->next); // b<->a
295 a_list_link(pt->prev, it); // a<->it
296 a_list_link(it, pt); // it<->pt
297 /* a<->it<->pt<->b<->a */
302 void *a_que_push_fore(a_que *ctx)
304 a_que_node *const node = a_que_node_new(ctx);
305 if (a_unlikely(!node)) { return node; }
306 a_list_add_next(&ctx->_head, &node->_node);
307 return node->_data;
310 void *a_que_push_back(a_que *ctx)
312 a_que_node *const node = a_que_node_new(ctx);
313 if (a_unlikely(!node)) { return node; }
314 a_list_add_prev(&ctx->_head, &node->_node);
315 return node->_data;
318 void *a_que_pull_fore(a_que *ctx)
320 void *data = A_NULL;
321 if (ctx->_head.next != &ctx->_head)
323 a_que_node *const node = (a_que_node *)ctx->_head.next;
324 if (a_unlikely(a_que_node_die(ctx, node))) { goto fail; }
325 a_list_del_node(&node->_node);
326 a_list_dtor(&node->_node);
327 data = node->_data;
329 fail:
330 return data;
333 void *a_que_pull_back(a_que *ctx)
335 void *data = A_NULL;
336 if (ctx->_head.prev != &ctx->_head)
338 a_que_node *const node = (a_que_node *)ctx->_head.prev;
339 if (a_unlikely(a_que_node_die(ctx, node))) { goto fail; }
340 a_list_del_node(&node->_node);
341 a_list_dtor(&node->_node);
342 data = node->_data;
344 fail:
345 return data;
348 void *a_que_insert(a_que *ctx, a_size idx)
350 if (idx < ctx->_num)
352 a_size cur = 0;
353 a_que_node *const node = a_que_node_new(ctx);
354 if (a_unlikely(!node)) { return node; }
355 a_list_foreach_next(it, &ctx->_head)
357 if (cur++ == idx)
359 a_list_add_prev(it, &node->_node);
360 break;
363 return node->_data;
365 return a_que_push_back(ctx);
368 void *a_que_remove(a_que *ctx, a_size idx)
370 if (idx < ctx->_num)
372 a_size cur = 0;
373 a_que_node *node = A_NULL;
374 a_list_foreach_next(it, &ctx->_head)
376 if (cur++ == idx)
378 // because idx less than num
379 // it's never a null pointer
380 node = (a_que_node *)it;
381 break;
384 if (a_unlikely(a_que_node_die(ctx, node))) { return A_NULL; }
385 a_list_del_node(&node->_node);
386 a_list_dtor(&node->_node);
387 return node->_data;
389 return a_que_pull_back(ctx);