==> include/mesh/member_list.h <==1/* @ajax/mesh-member-list: lists of fleet members (system ids 0..MAX_SYSTEMS) and their masks, in the
2 * text form every fleet message uses: "0,2,3", or "-" for none; a placement that is "every member
3 * that can" (Rust's `Option<Vec<u32>>` None) prints "all" (sched::at_word) or "*" (the document). */
4#ifndef MESH_MEMBER_LIST_H
5#define MESH_MEMBER_LIST_H
6
7#include <stdbool.h>
8#include <stddef.h>
9#include <stdint.h>
10
11typedef struct {
12 uint32_t *v;
13 size_t n, cap;
14} ml_list;
15
16/* Rust's Option<Vec<u32>>: some false is None. */
17typedef struct {
18 bool some;
19 ml_list l;
20} ml_opt;
21
22void ml_push(ml_list *l, uint32_t k);
23bool ml_has(const ml_list *l, uint32_t k);
24long ml_find(const ml_list *l, uint32_t k); /* index, or -1 */
25void ml_remove_value(ml_list *l, uint32_t k); /* every occurrence (Rust's retain(|x| x != k)) */
26void ml_remove_at(ml_list *l, size_t i);
27void ml_sort(ml_list *l);
28bool ml_eq(const ml_list *a, const ml_list *b);
29ml_list ml_clone(const ml_list *l);
30ml_list ml_of(const uint32_t *v, size_t n);
31void ml_free(ml_list *l);
32
33ml_opt ml_none(void);
34ml_opt ml_some(const uint32_t *v, size_t n);
35bool ml_opt_eq(const ml_opt *a, const ml_opt *b);
36ml_opt ml_opt_clone(const ml_opt *o);
37void ml_opt_free(ml_opt *o);
38/* Rust's `a.as_ref().is_none_or(|a| a.contains(&k))`: None counts as every member. */
39bool ml_opt_has_or_all(const ml_opt *o, uint32_t k);
40
41/* "-" or "0,2,3" (fleet::list, sched::list); a new string. */
42char *ml_text(const ml_list *l);
43/* sched::at_word: "all" for None, else ml_text. */
44char *ml_at_word(const ml_opt *o);
45/* fleet::parse_list: "-" is empty; each a u32 < MAX_SYSTEMS. On error *err is the Rust's message. */
46bool ml_parse(const char *s, ml_list *out, char **err);
47
48uint32_t ml_mask(const ml_list *l); /* fleet::mask_of */
49ml_list ml_members(uint32_t mask); /* fleet::members_of: bits 0..32 set */
50int ml_popcount(uint32_t x);
51
52#endif