1 #define MAIN_(x) A_CAST_2(x, _avl)
14 static A_INLINE
int int_factor(a_avl_node
*node
)
16 #if defined(A_SIZE_POINTER) && (A_SIZE_POINTER + 0 > 3)
17 return a_cast_s(int, node
->_parent
& 3) - 1;
18 #else /* !A_SIZE_POINTER */
20 #endif /* A_SIZE_POINTER */
23 static A_INLINE int_node
*int_entry(void const *node
)
25 return a_cast_r(int_node
*, a_cast_r(a_uptr
, node
) - a_offsetof(int_node
, node
)); // NOLINT
28 static int int_cmp(void const *lhs
, void const *rhs
)
30 return int_entry(lhs
)->data
- int_entry(rhs
)->data
;
33 #define int_max(a, b) ((a) > (b) ? (a) : (b))
34 #define int_height(node) ((node) ? int_entry(node)->height : 0)
35 static void set_height(a_avl_node
*node
) // NOLINT
39 TEST_BUG(node
->left
!= node
);
40 TEST_BUG(node
->right
!= node
);
41 set_height(node
->left
);
42 set_height(node
->right
);
43 int const hl
= int_height(node
->left
);
44 int const hr
= int_height(node
->right
);
45 int_entry(node
)->height
= int_max(hl
, hr
) + 1;
49 static void check_tree(a_avl_node
*node
) // NOLINT
53 int const e
= int_factor(node
);
54 TEST_BUG(-1 <= e
&& e
<= 1);
55 TEST_BUG(int_height(node
->right
) - int_height(node
->left
) == e
);
58 TEST_BUG(int_entry(node
->left
)->data
< int_entry(node
)->data
);
59 check_tree(node
->left
);
63 TEST_BUG(int_entry(node
->right
)->data
> int_entry(node
)->data
);
64 check_tree(node
->right
);
69 static int intcmp(void const *lhs
, void const *rhs
)
71 return *a_int_(const *, lhs
) - *a_int_(const *, rhs
);
74 static int test(int argc
, char *argv
[])
79 a_str str
= A_STR_NUL
;
80 a_avl root
= A_AVL_ROOT
;
81 unsigned int const n
= 0x1000;
82 int_node
*vec
= a_new(int_node
, A_NULL
, n
);
83 int *sorted
= a_new(int, A_NULL
, n
);
84 for (unsigned int i
= 0; i
< n
; ++i
)
86 a_str_putf(&str
, "%u", i
);
87 vec
[i
].data
= a_cast_s(int, a_hash_bkdr(a_str_ptr(&str
), 0));
89 sorted
[i
] = vec
[i
].data
;
90 a_avl_insert(&root
, &vec
[i
].node
, int_cmp
);
91 set_height(root
.node
);
92 check_tree(root
.node
);
95 debug("insert 0x%04X/0x%04X\n", i
, n
);
100 for (unsigned int i
= 0; i
< n
; ++i
)
102 TEST_BUG(a_avl_search(&root
, &vec
[i
].node
, int_cmp
));
106 qsort(sorted
, n
, sizeof(int), intcmp
);
109 for (unsigned int i
= 0; i
< n
; ++i
)
113 a_avl_foreach(cur
, &root
)
115 int_node
*it
= int_entry(cur
);
116 TEST_BUG(it
->data
== sorted
[x
]);
120 for (unsigned int i
= 0; i
< n
; ++i
)
122 TEST_BUG(vec
[i
].reached
);
127 for (unsigned int i
= 0; i
< n
; ++i
)
131 a_avl_foreach_reverse(cur
, &root
)
133 int_node
*it
= int_entry(cur
);
134 TEST_BUG(it
->data
== sorted
[--x
]);
137 for (unsigned int i
= 0; i
< n
; ++i
)
139 TEST_BUG(vec
[i
].reached
);
143 for (unsigned int i
= 0; i
< n
; ++i
)
147 a_avl_pre_foreach(cur
, &root
)
149 int_node
*it
= int_entry(cur
);
152 for (unsigned int i
= 0; i
< n
; ++i
)
154 TEST_BUG(vec
[i
].reached
);
157 for (unsigned int i
= 0; i
< n
; ++i
)
161 a_avl_pre_foreach_reverse(cur
, &root
)
163 int_node
*it
= int_entry(cur
);
166 for (unsigned int i
= 0; i
< n
; ++i
)
168 TEST_BUG(vec
[i
].reached
);
171 for (unsigned int i
= 0; i
< n
; ++i
)
175 a_avl_post_foreach(cur
, &root
)
177 int_node
*it
= int_entry(cur
);
180 for (unsigned int i
= 0; i
< n
; ++i
)
182 TEST_BUG(vec
[i
].reached
);
185 for (unsigned int i
= 0; i
< n
; ++i
)
189 a_avl_post_foreach_reverse(cur
, &root
)
191 int_node
*it
= int_entry(cur
);
194 for (unsigned int i
= 0; i
< n
; ++i
)
196 TEST_BUG(vec
[i
].reached
);
199 for (unsigned int i
= 0; i
< n
; ++i
)
201 a_avl_remove(&root
, &vec
[i
].node
);
202 set_height(root
.node
);
203 check_tree(root
.node
);
206 debug("remove 0x%04X/0x%04X\n", i
, n
);
210 TEST_BUG(!a_avl_search(&root
, &vec
->node
, int_cmp
));
212 for (unsigned int i
= 0; i
< n
; ++i
)
214 a_avl_insert(&root
, &vec
[i
].node
, int_cmp
);
217 a_avl_fortear(cur
, next
, &root
)
219 int_entry(cur
)->reached
= 1;
221 for (unsigned int i
= 0; i
< n
; ++i
)
223 TEST_BUG(vec
[i
].reached
);
231 int MAIN(int argc
, char *argv
[]) // NOLINT(misc-definitions-in-headers)
233 printf("%s\n", A_FUNC
);