1 /* ms.c - resizable multiset implementation */
3 /* Copyright (C) 2008 Keith Rarick and Philotic Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 ms_init(ms a
, ms_event_fn oninsert
, ms_event_fn onremove
)
28 a
->used
= a
->cap
= a
->last
= 0;
30 a
->oninsert
= oninsert
;
31 a
->onremove
= onremove
;
38 size_t ncap
= (a
->cap
<< 1) ? : 1;
40 nitems
= malloc(ncap
* sizeof(void *));
43 memcpy(nitems
, a
->items
, a
->used
* sizeof(void *));
50 ms_append(ms a
, void *item
)
52 if (a
->used
>= a
->cap
) grow(a
);
53 if (a
->used
>= a
->cap
) return 0;
55 a
->items
[a
->used
++] = item
;
56 if (a
->oninsert
) a
->oninsert(a
, item
, a
->used
- 1);
61 ms_delete(ms a
, size_t i
)
65 if (i
>= a
->used
) return 0;
67 a
->items
[i
] = a
->items
[--a
->used
];
69 /* it has already been removed now */
70 if (a
->onremove
) a
->onremove(a
, item
, i
);
77 while (ms_delete(a
, 0));
79 ms_init(a
, a
->oninsert
, a
->onremove
);
83 ms_remove(ms a
, void *item
)
87 for (i
= 0; i
< a
->used
; i
++) {
88 if (a
->items
[i
] == item
) return ms_delete(a
, i
);
94 ms_contains(ms a
, void *item
)
98 for (i
= 0; i
< a
->used
; i
++) {
99 if (a
->items
[i
] == item
) return 1;
109 if (!a
->used
) return NULL
;
111 a
->last
= a
->last
% a
->used
;
112 item
= a
->items
[a
->last
];
113 ms_delete(a
, a
->last
);