change a_float to a_real
[liba.git] / test / rbt.h
blob3929beb62331b9cac6d1659c8f9a4408ff6ddd7d
1 #define MAIN(x) rbt##x
2 #include "test.h"
3 #include "a/rbt.h"
4 #include "a/str.h"
5 #include "a/hash.h"
7 typedef struct
9 a_rbt_node node;
10 int data;
11 int reached;
12 } int_node;
14 static A_INLINE int_node *int_entry(void const *node)
16 return a_cast_r(int_node *, a_cast_r(a_uptr, node) - a_offsetof(int_node, node)); /* NOLINT */
19 static int int_cmp(void const *lhs, void const *rhs)
21 int a = int_entry(lhs)->data;
22 int b = int_entry(rhs)->data;
23 return (a > b) - (a < b);
26 static int intcmp(void const *lhs, void const *rhs)
28 int a = *a_int_(const *, lhs);
29 int b = *a_int_(const *, rhs);
30 return (a > b) - (a < b);
33 static int test(unsigned long n)
35 unsigned int i;
36 unsigned long x;
37 a_rbt_node *cur, *next;
38 a_str str = A_STR_INIT;
39 a_rbt root = A_RBT_ROOT;
40 int *sorted = a_new(int, A_NULL, n);
41 int_node *vec = a_new(int_node, A_NULL, n);
42 for (i = 0; i < n; ++i)
44 a_str_setf(&str, "%u", i);
45 vec[i].data = sorted[i] = a_cast_s(int, a_hash_bkdr(a_str_ptr(&str), 0));
46 a_rbt_insert(&root, &vec[i].node, int_cmp);
47 if (i % 0x100 == 0)
49 debug("insert 0x%04X/0x%04lX\n", i, n);
52 a_str_dtor(&str);
54 for (i = 0; i < n; ++i)
56 TEST_BUG(a_rbt_search(&root, &vec[i].node, int_cmp));
59 qsort(sorted, n, sizeof(int), intcmp);
61 x = 0;
62 for (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 (i = 0; i < n; ++i)
75 TEST_BUG(vec[i].reached);
77 TEST_BUG(x == n);
79 x = n;
80 for (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 (i = 0; i < n; ++i)
92 TEST_BUG(vec[i].reached);
94 TEST_BUG(x == 0);
96 for (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 (i = 0; i < n; ++i)
107 TEST_BUG(vec[i].reached);
110 for (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 (i = 0; i < n; ++i)
121 TEST_BUG(vec[i].reached);
124 for (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 (i = 0; i < n; ++i)
135 TEST_BUG(vec[i].reached);
138 for (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 (i = 0; i < n; ++i)
149 TEST_BUG(vec[i].reached);
152 for (i = 0; i < n; ++i)
154 a_rbt_remove(&root, &vec[i].node);
155 if (i % 0x100 == 0)
157 debug("remove 0x%04X/0x%04lX\n", i, n);
161 TEST_BUG(!a_rbt_search(&root, &vec->node, int_cmp));
163 for (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 (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 unsigned long n = 0x1000;
185 if (argc > 1) { n = strtoul(argv[1], A_NULL, 0); }
186 puts(A_FUNC);
187 test(n);
188 return 0;