skip to content
==> 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}