==> tests/ranges.c <==1/* Merging, splitting, saturating lengths; and a random cross-check against a bitmap. */
2#include "mesh/check.h"
3#include "mesh/range_set.h"
4
5int main(void) {
6 rs_set r = {0};
7 rs_insert(&r, 10, 20);
8 rs_insert(&r, 30, 40);
9 rs_insert(&r, 20, 25); /* touches: merges */
10 CHECK(r.n == 2 && r.s[0] == 10 && r.e[0] == 25);
11 rs_insert(&r, 0, 100);
12 CHECK(r.n == 1 && rs_len(&r) == 100);
13 CHECK(rs_remove(&r, 40, 50) && r.n == 2 && rs_contains(&r, 39) && !rs_contains(&r, 40) && rs_contains(&r, 50));
14 CHECK(!rs_remove(&r, 40, 50) && !rs_remove(&r, 5, 5));
15 CHECK(rs_take(&r, 0) && !rs_contains(&r, 0));
16 uint64_t x;
17 CHECK(rs_first(&r, &x) && x == 1 && rs_end(&r, &x) && x == 100);
18 rs_set big = rs_of(0, UINT64_MAX);
19 rs_insert(&big, 5, 6);
20 CHECK(rs_len(&big) == UINT64_MAX);
21 rs_free(&big);
22 /* random operations against a bitmap */
23 uint64_t rng = 7;
24 for (int round = 0; round < 200; round++) {
25 rs_set s = {0};
26 uint8_t bits[256] = {0};
27 for (int op = 0; op < 60; op++) {
28 rng ^= rng << 13, rng ^= rng >> 7, rng ^= rng << 17;
29 uint64_t a = rng % 256, b = a + (rng >> 20) % 40;
30 if (b > 256) b = 256;
31 if ((rng >> 40) % 3) {
32 rs_insert(&s, a, b);
33 for (uint64_t i = a; i < b; i++) bits[i] = 1;
34 } else {
35 bool had = false;
36 for (uint64_t i = a; i < b; i++) had |= bits[i], bits[i] = 0;
37 CHECK(rs_remove(&s, a, b) == had);
38 }
39 }
40 uint64_t n = 0;
41 for (int i = 0; i < 256; i++) {
42 CHECK(rs_contains(&s, (uint64_t)i) == (bits[i] == 1));
43 n += bits[i];
44 }
45 CHECK_U(rs_len(&s), n);
46 for (size_t i = 1; i < s.n; i++) CHECK(s.e[i - 1] < s.s[i]);
47 rs_set c = rs_clone(&s);
48 CHECK(rs_eq(&c, &s));
49 rs_subtract(&c, &s);
50 CHECK(rs_is_empty(&c));
51 rs_union(&c, &s);
52 CHECK(rs_eq(&c, &s));
53 rs_free(&c);
54 rs_free(&s);
55 }
56 rs_free(&r);
57 return mesh_check_done();
58}