// todo: rewrite this test with structures from l1_5/eve/margaret
// todo: but before that: don't even bother running this test

// #include "../../../../gen/l1_5/BuffRBTreeByLen_SetU64Segment.h"
// #include "../../../../gen/l1_5/BuffRBTreeByStart_SetU64Segment.h"
// #include "../../../../gen/l1_5/BuffRBTreeByLenRespAlign_SetU64Segment.h"
// #include "../../../l1/core/VecU8_as_str.h"
//
// U32 check_structure_h_dfs(const RBTreeNode* tree, U64 x, VecU8* f){
//     if (x == 0)
//         return 0;
//     if (*VecU8_at(f, x - 1) != 0)
//         check(false);
//     *VecU8_mat(f, x - 1) = 1;
//     U32 a = check_structure_h_dfs(tree, tree[x].left, f);
//     U32 b = check_structure_h_dfs(tree, tree[x].right, f);
//     check(a == b);
//     return a + (tree[x].color == RBTree_black ? 1 : 0);
// }
//
// void check_correctness_ByStart(const BuffRBTreeByStart_SetU64Segment* self){
//     check(self->tree.len == self->el.len + 1);
//     check(self->root < self->tree.len);
//     if (self->tree.len > 1) {
//         check(self->root != 0);
//     }
//     VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
//     check_structure_h_dfs(self->tree.buf, self->root, &f);
//     for (size_t i = 0; i < self->tree.len - 1; i++) {
//         check(*VecU8_at(&f, i));
//     }
//     VecU8_drop(f);  /* f invalidated */
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (v == self->root) {
//             check(self->tree.buf[v].parent == 0);
//         } else {
//             check(self->tree.buf[v].parent != 0);
//         }
//         check(self->tree.buf[v].parent < self->tree.len);
//         check(self->tree.buf[v].left < self->tree.len);
//         check(self->tree.buf[v].right < self->tree.len);
//         if (self->tree.buf[v].left != 0) {
//             check(self->tree.buf[self->tree.buf[v].left].parent == v);
//         }
//         if (self->tree.buf[v].right != 0) {
//             check(self->tree.buf[self->tree.buf[v].right].parent == v);
//         }
//     }
//
//     /* Checking coloring */
//     check(self->tree.buf[0].color == RBTree_black);
//     if (self->root != 0)
//         check(self->tree.buf[self->root].color == RBTree_black);
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].color == RBTree_red) {
//             check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
//             check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
//         }
//     }
//
//     /* checking keys, but better */
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].left != 0) {
//             check(U64Segment_less_by_start(&self->el.buf[self->tree.buf[v].left - 1], &self->el.buf[v - 1]));
//         }
//         if (self->tree.buf[v].right != 0) {
//             check(U64Segment_less_by_start(&self->el.buf[v - 1], &self->el.buf[self->tree.buf[v].right - 1]));
//         }
//     }
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].left != 0) {
//             size_t cur = self->tree.buf[v].left;
//             while (self->tree.buf[cur].right != 0)
//                 cur = self->tree.buf[cur].right;
//             check(U64Segment_less_by_start(&self->el.buf[cur - 1], &self->el.buf[v - 1]));
//         }
//         if (self->tree.buf[v].right != 0) {
//             size_t cur = self->tree.buf[v].right;
//             while (self->tree.buf[cur].left != 0)
//                 cur = self->tree.buf[cur].left;
//             check(U64Segment_less_by_start(&self->el.buf[v - 1], &self->el.buf[cur - 1]));
//         }
//     }
// }
//
// void stress_ByStart(){
//     printf("Prepare for some real stress\n");
//     for (int s = 2; s < 800; s++) {
//         srand(s);
//         BuffRBTreeByStart_SetU64Segment set = BuffRBTreeByStart_SetU64Segment_new();
//         VecU64Segment real_set = VecU64Segment_new();
//         U32 n = (U32)s;
//         VecU64Segment complementary_set = VecU64Segment_new_reserved(n);
//         for (size_t i = 0; i < n; i++) {
//             U64Segment value = {i, (U64)rand()};
//             VecU64Segment_append(&complementary_set, value);
//         }
//         for (int t = 0; t < 1000; t++) {
//             /* Do something */
//             int do_insertion = rand() % 2;
//             if (real_set.len == 0)
//                 do_insertion = 1;
//             if (complementary_set.len == 0)
//                 do_insertion = 0;
//             if (do_insertion) {
//                 assert(complementary_set.len > 0);
//                 size_t j = rand() % complementary_set.len;
//                 U64Segment v = VecU64Segment_unordered_pop(&complementary_set, j);
//                 VecU64Segment_append(&real_set, v);
//                 check(BuffRBTreeByStart_SetU64Segment_insert(&set, v));
//                 check_correctness_ByStart(&set);
//             } else {
//                 assert(real_set.len > 0);
//                 size_t j = rand() % real_set.len;
//                 U64Segment v = VecU64Segment_unordered_pop(&real_set, j);
//                 VecU64Segment_append(&complementary_set, v);
//                 check(BuffRBTreeByStart_SetU64Segment_erase(&set, &v));
//                 check_correctness_ByStart(&set);
//             }
//             /* We did something */
//             check(real_set.len == set.el.len);
//             for (size_t j = 0; j < real_set.len; j++) {
//                 check(BuffRBTreeByStart_SetU64Segment_find(&set, &real_set.buf[j]) != 0);
//                 check(BuffRBTreeByStart_SetU64Segment_at(&set, &real_set.buf[j]).variant == Option_Some);
//             }
//             for (size_t j = 0; j < complementary_set.len; j++) {
//                 check(BuffRBTreeByStart_SetU64Segment_find(&set, &complementary_set.buf[j]) == 0);
//                 check(BuffRBTreeByStart_SetU64Segment_at(&set, &complementary_set.buf[j]).variant == Option_None);
//             }
//         }
//         VecU64Segment_drop(real_set);
//         VecU64Segment_drop(complementary_set);
//         BuffRBTreeByStart_SetU64Segment_drop(set);
//         printf("Seed s=%d passed test\n", s);
//     }
// }
//
// void check_correctness_ByLen(const BuffRBTreeByLen_SetU64Segment* self){
//     check(self->tree.len == self->el.len + 1);
//     check(self->root < self->tree.len);
//     if (self->tree.len > 1) {
//         check(self->root != 0);
//     }
//     VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
//     check_structure_h_dfs(self->tree.buf, self->root, &f);
//     for (size_t i = 0; i < self->tree.len - 1; i++) {
//         check(*VecU8_at(&f, i));
//     }
//     VecU8_drop(f);  /* f invalidated */
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (v == self->root) {
//             check(self->tree.buf[v].parent == 0);
//         } else {
//             check(self->tree.buf[v].parent != 0);
//         }
//         check(self->tree.buf[v].parent < self->tree.len);
//         check(self->tree.buf[v].left < self->tree.len);
//         check(self->tree.buf[v].right < self->tree.len);
//         if (self->tree.buf[v].left != 0) {
//             check(self->tree.buf[self->tree.buf[v].left].parent == v);
//         }
//         if (self->tree.buf[v].right != 0) {
//             check(self->tree.buf[self->tree.buf[v].right].parent == v);
//         }
//     }
//
//     /* Checking coloring */
//     check(self->tree.buf[0].color == RBTree_black);
//     if (self->root != 0)
//         check(self->tree.buf[self->root].color == RBTree_black);
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].color == RBTree_red) {
//             check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
//             check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
//         }
//     }
//
//     /* checking keys, but better */
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].left != 0) {
//             check(U64Segment_less_by_len_and_start(&self->el.buf[self->tree.buf[v].left - 1], &self->el.buf[v - 1]));
//         }
//         if (self->tree.buf[v].right != 0) {
//             check(U64Segment_less_by_len_and_start(&self->el.buf[v - 1], &self->el.buf[self->tree.buf[v].right - 1]));
//         }
//     }
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].left != 0) {
//             size_t cur = self->tree.buf[v].left;
//             while (self->tree.buf[cur].right != 0)
//                 cur = self->tree.buf[cur].right;
//             check(U64Segment_less_by_len_and_start(&self->el.buf[cur - 1], &self->el.buf[v - 1]));
//         }
//         if (self->tree.buf[v].right != 0) {
//             size_t cur = self->tree.buf[v].right;
//             while (self->tree.buf[cur].left != 0)
//                 cur = self->tree.buf[cur].left;
//             check(U64Segment_less_by_len_and_start(&self->el.buf[v - 1], &self->el.buf[cur - 1]));
//         }
//     }
// }
//
// void stress_ByLen(){
//     printf("Prepare for some real stress\n");
//     for (int s = 2; s < 400; s++) {
//         srand(s);
//         BuffRBTreeByLen_SetU64Segment set = BuffRBTreeByLen_SetU64Segment_new();
//         VecU64Segment real_set = VecU64Segment_new();
//         U32 n = (U32)s;
//         VecU64Segment complementary_set = VecU64Segment_new_reserved(n);
//         for (size_t i = 0; i < n; i++) {
//             U64Segment value = {i, (U64)rand()};
//             VecU64Segment_append(&complementary_set, value);
//         }
//         for (int t = 0; t < 1000; t++) {
//             /* Do something */
//             int do_insertion = rand() % 2;
//             if (real_set.len == 0)
//                 do_insertion = 1;
//             if (complementary_set.len == 0)
//                 do_insertion = 0;
//             if (do_insertion) {
//                 assert(complementary_set.len > 0);
//                 size_t j = rand() % complementary_set.len;
//                 U64Segment v = VecU64Segment_unordered_pop(&complementary_set, j);
//                 VecU64Segment_append(&real_set, v);
//                 check(BuffRBTreeByLen_SetU64Segment_insert(&set, v));
//                 check_correctness_ByLen(&set);
//             } else {
//                 assert(real_set.len > 0);
//                 size_t j = rand() % real_set.len;
//                 U64Segment v = VecU64Segment_unordered_pop(&real_set, j);
//                 VecU64Segment_append(&complementary_set, v);
//                 check(BuffRBTreeByLen_SetU64Segment_erase(&set, &v));
//                 check_correctness_ByLen(&set);
//             }
//             /* We did something */
//             check(real_set.len == set.el.len);
//             for (size_t j = 0; j < real_set.len; j++) {
//                 check(BuffRBTreeByLen_SetU64Segment_find(&set, &real_set.buf[j]) != 0);
//                 check(BuffRBTreeByLen_SetU64Segment_at(&set, &real_set.buf[j]).variant == Option_Some);
//             }
//             for (size_t j = 0; j < complementary_set.len; j++) {
//                 check(BuffRBTreeByLen_SetU64Segment_find(&set, &complementary_set.buf[j]) == 0);
//                 check(BuffRBTreeByLen_SetU64Segment_at(&set, &complementary_set.buf[j]).variant == Option_None);
//             }
//         }
//         VecU64Segment_drop(real_set);
//         VecU64Segment_drop(complementary_set);
//         BuffRBTreeByLen_SetU64Segment_drop(set);
//         printf("Seed s=%d passed test\n", s);
//     }
// }
//
// void check_correctness_ByLenRespAlign(const BuffRBTreeByLenRespAlign_SetU64Segment* self, U8 alignment_exp){
//     check(self->guest == alignment_exp)
//     check(self->tree.len == self->el.len + 1);
//     check(self->root < self->tree.len);
//     if (self->tree.len > 1) {
//         check(self->root != 0);
//     }
//     VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
//     check_structure_h_dfs(self->tree.buf, self->root, &f);
//     for (size_t i = 0; i < self->tree.len - 1; i++) {
//         check(*VecU8_at(&f, i));
//     }
//     VecU8_drop(f);  /* f invalidated */
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (v == self->root) {
//             check(self->tree.buf[v].parent == 0);
//         } else {
//             check(self->tree.buf[v].parent != 0);
//         }
//         check(self->tree.buf[v].parent < self->tree.len);
//         check(self->tree.buf[v].left < self->tree.len);
//         check(self->tree.buf[v].right < self->tree.len);
//         if (self->tree.buf[v].left != 0) {
//             check(self->tree.buf[self->tree.buf[v].left].parent == v);
//         }
//         if (self->tree.buf[v].right != 0) {
//             check(self->tree.buf[self->tree.buf[v].right].parent == v);
//         }
//     }
//
//     /* Checking coloring */
//     check(self->tree.buf[0].color == RBTree_black);
//     if (self->root != 0)
//         check(self->tree.buf[self->root].color == RBTree_black);
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].color == RBTree_red) {
//             check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
//             check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
//         }
//     }
//
//     /* checking keys, but better */
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].left != 0) {
//             check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[self->tree.buf[v].left - 1], &self->el.buf[v - 1], alignment_exp));
//         }
//         if (self->tree.buf[v].right != 0) {
//             check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[v - 1], &self->el.buf[self->tree.buf[v].right - 1], alignment_exp));
//         }
//     }
//     for (size_t v = 1; v < self->tree.len; v++) {
//         if (self->tree.buf[v].left != 0) {
//             size_t cur = self->tree.buf[v].left;
//             while (self->tree.buf[cur].right != 0)
//                 cur = self->tree.buf[cur].right;
//             check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[cur - 1], &self->el.buf[v - 1], alignment_exp));
//         }
//         if (self->tree.buf[v].right != 0) {
//             size_t cur = self->tree.buf[v].right;
//             while (self->tree.buf[cur].left != 0)
//                 cur = self->tree.buf[cur].left;
//             check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[v - 1], &self->el.buf[cur - 1], alignment_exp));
//         }
//     }
// }
//
// void stress_ByLenRespAlign(U8 alignment_exp){
//     printf("Prepare for some real stress\n");
//     for (int s = 2; s < 400; s++) {
//         srand(s + 232323);
//         BuffRBTreeByLenRespAlign_SetU64Segment set = BuffRBTreeByLenRespAlign_SetU64Segment_new(alignment_exp);
//         VecU64Segment real_set = VecU64Segment_new();
//         U32 n = (U32)s;
//         VecU64Segment complementary_set = VecU64Segment_new_reserved(n);
//         for (size_t i = 0; i < n; i++) {
//             U64Segment value = {i, (U64)rand()};
//             VecU64Segment_append(&complementary_set, value);
//         }
//         for (int t = 0; t < 1000; t++) {
//             /* Do something */
//             int do_insertion = rand() % 2;
//             if (real_set.len == 0)
//                 do_insertion = 1;
//             if (complementary_set.len == 0)
//                 do_insertion = 0;
//             if (do_insertion) {
//                 assert(complementary_set.len > 0);
//                 size_t j = rand() % complementary_set.len;
//                 U64Segment v = VecU64Segment_unordered_pop(&complementary_set, j);
//                 VecU64Segment_append(&real_set, v);
//                 check(BuffRBTreeByLenRespAlign_SetU64Segment_insert(&set, v));
//                 check_correctness_ByLenRespAlign(&set, alignment_exp);
//             } else {
//                 assert(real_set.len > 0);
//                 size_t j = rand() % real_set.len;
//                 U64Segment v = VecU64Segment_unordered_pop(&real_set, j);
//                 VecU64Segment_append(&complementary_set, v);
//                 check(BuffRBTreeByLenRespAlign_SetU64Segment_erase(&set, &v));
//                 check_correctness_ByLenRespAlign(&set, alignment_exp);
//             }
//             /* We did something */
//             check(real_set.len == set.el.len);
//             for (size_t j = 0; j < real_set.len; j++) {
//                 check(BuffRBTreeByLenRespAlign_SetU64Segment_find(&set, &real_set.buf[j]) != 0);
//                 check(BuffRBTreeByLenRespAlign_SetU64Segment_at(&set, &real_set.buf[j]).variant == Option_Some);
//             }
//             for (size_t j = 0; j < complementary_set.len; j++) {
//                 check(BuffRBTreeByLenRespAlign_SetU64Segment_find(&set, &complementary_set.buf[j]) == 0);
//                 check(BuffRBTreeByLenRespAlign_SetU64Segment_at(&set, &complementary_set.buf[j]).variant == Option_None);
//             }
//         }
//         VecU64Segment_drop(real_set);
//         VecU64Segment_drop(complementary_set);
//         BuffRBTreeByLenRespAlign_SetU64Segment_drop(set);
//         printf("Seed s=%d passed test\n", s);
//     }
// }
//
// int main(){
//     stress_ByStart();
//     stress_ByLen();
//     stress_ByLenRespAlign(0);  // 1
//     stress_ByLenRespAlign(3);  // 8
//     stress_ByLenRespAlign(10);  // 1024
//     stress_ByLenRespAlign(12);  // 4096
//     return 0;
// }
