7 ms_init(Ms
*a
, ms_event_fn oninsert
, ms_event_fn onremove
)
9 a
->len
= a
->cap
= a
->last
= 0;
11 a
->oninsert
= oninsert
;
12 a
->onremove
= onremove
;
19 size_t ncap
= a
->cap
<< 1;
23 nitems
= malloc(ncap
* sizeof(void *));
27 memcpy(nitems
, a
->items
, a
->len
* sizeof(void *));
35 ms_append(Ms
*a
, void *item
)
37 if (a
->len
>= a
->cap
&& !grow(a
))
40 a
->items
[a
->len
++] = item
;
42 a
->oninsert(a
, item
, a
->len
- 1);
47 ms_delete(Ms
*a
, size_t i
)
54 a
->items
[i
] = a
->items
[--a
->len
];
56 /* it has already been removed now */
58 a
->onremove(a
, item
, i
);
65 while (ms_delete(a
, 0));
67 ms_init(a
, a
->oninsert
, a
->onremove
);
71 ms_remove(Ms
*a
, void *item
)
75 for (i
= 0; i
< a
->len
; i
++) {
76 if (a
->items
[i
] == item
)
77 return ms_delete(a
, i
);
83 ms_contains(Ms
*a
, void *item
)
87 for (i
= 0; i
< a
->len
; i
++) {
88 if (a
->items
[i
] == item
)
102 // The result of last behaviour is that ms_take returns the oldest elements
103 // first, exception is a row of multiple take calls without inserts on ms
104 // of even number of elements. See the test.
105 a
->last
= a
->last
% a
->len
;
106 item
= a
->items
[a
->last
];
107 ms_delete(a
, a
->last
);