change sizeof(a_cast) to sizeof(void*)
[liba.git] / test / rbt.h
blob81ed94ca5d9249c2912a9ea9a0de0063ef8eeb3e
1 #define MAIN(x) rbt##x
2 #include "test.h"
3 #include "a/rbt.h"
4 #include "a/str.h"
6 typedef struct
8 a_rbt_node node;
9 int data;
10 int reached;
11 } int_node;
13 static A_INLINE int_node *int_entry(void const *node)
15 return a_cast_r(int_node *, a_cast_r(a_uptr, node) - a_offsetof(int_node, node)); // NOLINT
18 static int int_cmp(void const *lhs, void const *rhs)
20 return int_entry(lhs)->data - int_entry(rhs)->data;
23 static int intcmp(void const *lhs, void const *rhs)
25 return *a_int_(const *, lhs) - *a_int_(const *, rhs);
28 static int test(int argc, char *argv[])
30 (void)(argc);
31 (void)(argv);
33 unsigned int const n = 0x1000;
35 a_str str = A_STR_NUL;
36 a_rbt root = A_RBT_ROOT;
37 int_node *vec = a_new(int_node, A_NULL, n);
38 int *sorted = a_new(int, A_NULL, n);
39 for (unsigned int i = 0; i < n; ++i)
41 a_str_putf(&str, "%u", i);
42 vec[i].data = a_cast_s(int, a_hash_bkdr(a_str_ptr(&str), 0));
43 a_str_drop(&str);
44 sorted[i] = vec[i].data;
45 a_rbt_insert(&root, &vec[i].node, int_cmp);
46 if (i % 0x100 == 0)
48 debug("insert 0x%04X/0x%04X\n", i, n);
51 a_str_dtor(&str);
53 for (unsigned int i = 0; i < n; ++i)
55 TEST_BUG(a_rbt_search(&root, &vec[i].node, int_cmp));
58 unsigned int x;
59 qsort(sorted, n, sizeof(int), intcmp);
61 x = 0;
62 for (unsigned int i = 0; i < n; ++i)
64 vec[i].reached = 0;
66 a_rbt_foreach(cur, &root)
68 int_node *it = int_entry(cur);
69 TEST_BUG(it->data == sorted[x]);
70 it->reached = 1;
71 ++x;
73 for (unsigned int i = 0; i < n; ++i)
75 TEST_BUG(vec[i].reached);
77 TEST_BUG(x == n);
79 x = n;
80 for (unsigned int i = 0; i < n; ++i)
82 vec[i].reached = 0;
84 a_rbt_foreach_reverse(cur, &root)
86 int_node *it = int_entry(cur);
87 TEST_BUG(it->data == sorted[--x]);
88 it->reached = 1;
90 for (unsigned int i = 0; i < n; ++i)
92 TEST_BUG(vec[i].reached);
94 TEST_BUG(x == 0);
96 for (unsigned int i = 0; i < n; ++i)
98 vec[i].reached = 0;
100 a_rbt_pre_foreach(cur, &root)
102 int_node *it = int_entry(cur);
103 it->reached = 1;
105 for (unsigned int i = 0; i < n; ++i)
107 TEST_BUG(vec[i].reached);
110 for (unsigned int i = 0; i < n; ++i)
112 vec[i].reached = 0;
114 a_rbt_pre_foreach_reverse(cur, &root)
116 int_node *it = int_entry(cur);
117 it->reached = 1;
119 for (unsigned int i = 0; i < n; ++i)
121 TEST_BUG(vec[i].reached);
124 for (unsigned int i = 0; i < n; ++i)
126 vec[i].reached = 0;
128 a_rbt_post_foreach(cur, &root)
130 int_node *it = int_entry(cur);
131 it->reached = 1;
133 for (unsigned int i = 0; i < n; ++i)
135 TEST_BUG(vec[i].reached);
138 for (unsigned int i = 0; i < n; ++i)
140 vec[i].reached = 0;
142 a_rbt_post_foreach_reverse(cur, &root)
144 int_node *it = int_entry(cur);
145 it->reached = 1;
147 for (unsigned int i = 0; i < n; ++i)
149 TEST_BUG(vec[i].reached);
152 for (unsigned int i = 0; i < n; ++i)
154 a_rbt_remove(&root, &vec[i].node);
155 if (i % 0x100 == 0)
157 debug("remove 0x%04X/0x%04X\n", i, n);
161 TEST_BUG(!a_rbt_search(&root, &vec->node, int_cmp));
163 for (unsigned int i = 0; i < n; ++i)
165 a_rbt_insert(&root, &vec[i].node, int_cmp);
166 vec[i].reached = 0;
168 a_rbt_fortear(cur, next, &root)
170 int_entry(cur)->reached = 1;
172 for (unsigned int i = 0; i < n; ++i)
174 TEST_BUG(vec[i].reached);
177 a_die(sorted);
178 a_die(vec);
179 return 0;
182 int main(int argc, char *argv[]) // NOLINT(misc-definitions-in-headers)
184 printf("%s\n", A_FUNC);
185 test(argc, argv);
186 return 0;