101 } |
101 } |
102 |
102 |
103 #define tree_node_layout \ |
103 #define tree_node_layout \ |
104 offsetof(tree_node, parent), offsetof(tree_node, children), -1, \ |
104 offsetof(tree_node, parent), offsetof(tree_node, children), -1, \ |
105 offsetof(tree_node, prev), offsetof(tree_node, next) |
105 offsetof(tree_node, prev), offsetof(tree_node, next) |
|
106 #define tree_node_layout_no_prev \ |
|
107 offsetof(tree_node, parent), offsetof(tree_node, children), -1, -1, \ |
|
108 offsetof(tree_node, next) |
106 #define tree_node_full_layout(structname) \ |
109 #define tree_node_full_layout(structname) \ |
107 offsetof(structname, parent), offsetof(structname, children),\ |
110 offsetof(structname, parent), offsetof(structname, children),\ |
108 offsetof(structname, last_child), \ |
111 offsetof(structname, last_child), \ |
109 offsetof(structname, prev), offsetof(structname, next) |
112 offsetof(structname, prev), offsetof(structname, next) |
110 #define tree_node2_layout cx_tree_node_base_layout |
113 #define tree_node2_layout cx_tree_node_base_layout |
197 CX_TEST(test_tree_unlink) { |
200 CX_TEST(test_tree_unlink) { |
198 tree_node parent = {0}; |
201 tree_node parent = {0}; |
199 tree_node child1 = {0}; |
202 tree_node child1 = {0}; |
200 tree_node child2 = {0}; |
203 tree_node child2 = {0}; |
201 tree_node child3 = {0}; |
204 tree_node child3 = {0}; |
|
205 tree_node child4 = {0}; |
202 cx_tree_link(&parent, &child1, tree_node_layout); |
206 cx_tree_link(&parent, &child1, tree_node_layout); |
203 cx_tree_link(&parent, &child3, tree_node_layout); |
207 cx_tree_link(&parent, &child3, tree_node_layout); |
|
208 cx_tree_link(&parent, &child4, tree_node_layout); |
204 cx_tree_link(&child3, &child2, tree_node_layout); |
209 cx_tree_link(&child3, &child2, tree_node_layout); |
205 |
210 |
206 CX_TEST_DO { |
211 CX_TEST_DO { |
207 cx_tree_unlink(&child3, tree_node_layout); |
212 cx_tree_unlink(&child3, tree_node_layout); |
208 |
213 |
212 CX_TEST_ASSERT(parent.children == &child1); |
217 CX_TEST_ASSERT(parent.children == &child1); |
213 |
218 |
214 CX_TEST_ASSERT(child1.parent == &parent); |
219 CX_TEST_ASSERT(child1.parent == &parent); |
215 CX_TEST_ASSERT(child1.children == NULL); |
220 CX_TEST_ASSERT(child1.children == NULL); |
216 CX_TEST_ASSERT(child1.prev == NULL); |
221 CX_TEST_ASSERT(child1.prev == NULL); |
217 CX_TEST_ASSERT(child1.next == NULL); |
222 CX_TEST_ASSERT(child1.next == &child4); |
|
223 |
|
224 CX_TEST_ASSERT(child4.parent == &parent); |
|
225 CX_TEST_ASSERT(child4.children == NULL); |
|
226 CX_TEST_ASSERT(child4.prev == &child1); |
|
227 CX_TEST_ASSERT(child4.next == NULL); |
218 |
228 |
219 // child 3 is unlinked |
229 // child 3 is unlinked |
220 CX_TEST_ASSERT(child3.parent == NULL); |
230 CX_TEST_ASSERT(child3.parent == NULL); |
221 CX_TEST_ASSERT(child3.prev == NULL); |
231 CX_TEST_ASSERT(child3.prev == NULL); |
222 CX_TEST_ASSERT(child3.next == NULL); |
232 CX_TEST_ASSERT(child3.next == NULL); |
226 CX_TEST_ASSERT(child2.parent == &child3); |
236 CX_TEST_ASSERT(child2.parent == &child3); |
227 CX_TEST_ASSERT(child2.children == NULL); |
237 CX_TEST_ASSERT(child2.children == NULL); |
228 CX_TEST_ASSERT(child2.prev == NULL); |
238 CX_TEST_ASSERT(child2.prev == NULL); |
229 CX_TEST_ASSERT(child2.next == NULL); |
239 CX_TEST_ASSERT(child2.next == NULL); |
230 |
240 |
231 // unlink last child from parent |
241 // unlink first child from parent |
232 cx_tree_unlink(&child1, tree_node_layout); |
242 cx_tree_unlink(&child1, tree_node_layout); |
233 CX_TEST_ASSERT(parent.next == NULL); |
243 CX_TEST_ASSERT(parent.next == NULL); |
234 CX_TEST_ASSERT(parent.prev == NULL); |
244 CX_TEST_ASSERT(parent.prev == NULL); |
235 CX_TEST_ASSERT(parent.parent == NULL); |
245 CX_TEST_ASSERT(parent.parent == NULL); |
236 CX_TEST_ASSERT(parent.children == NULL); |
246 CX_TEST_ASSERT(parent.children == &child4); |
237 CX_TEST_ASSERT(child1.parent == NULL); |
247 CX_TEST_ASSERT(child1.parent == NULL); |
|
248 CX_TEST_ASSERT(child4.parent == &parent); |
|
249 CX_TEST_ASSERT(child4.children == NULL); |
|
250 CX_TEST_ASSERT(child4.prev == NULL); |
|
251 CX_TEST_ASSERT(child4.next == NULL); |
|
252 } |
|
253 } |
|
254 |
|
255 CX_TEST(test_tree_unlink_no_prev) { |
|
256 tree_node parent = {0}; |
|
257 tree_node child1 = {0}; |
|
258 tree_node child2 = {0}; |
|
259 tree_node child3 = {0}; |
|
260 tree_node child4 = {0}; |
|
261 cx_tree_link(&parent, &child1, tree_node_layout_no_prev); |
|
262 cx_tree_link(&parent, &child3, tree_node_layout_no_prev); |
|
263 cx_tree_link(&parent, &child4, tree_node_layout_no_prev); |
|
264 cx_tree_link(&child3, &child2, tree_node_layout_no_prev); |
|
265 void * const marker = (void*) 0xc0ffee; |
|
266 child1.prev = child2.prev = child3.prev = child4.prev = marker; |
|
267 |
|
268 CX_TEST_DO { |
|
269 // in contrast to the other test we here remove child 4 instead of 3! |
|
270 cx_tree_unlink(&child4, tree_node_layout_no_prev); |
|
271 |
|
272 CX_TEST_ASSERT(parent.next == NULL); |
|
273 CX_TEST_ASSERT(parent.prev == NULL); |
|
274 CX_TEST_ASSERT(parent.parent == NULL); |
|
275 CX_TEST_ASSERT(parent.children == &child1); |
|
276 |
|
277 CX_TEST_ASSERT(child1.parent == &parent); |
|
278 CX_TEST_ASSERT(child1.children == NULL); |
|
279 CX_TEST_ASSERT(child1.prev == marker); |
|
280 CX_TEST_ASSERT(child1.next == &child3); |
|
281 |
|
282 // child 4 is unlinked |
|
283 CX_TEST_ASSERT(child4.parent == NULL); |
|
284 CX_TEST_ASSERT(child4.children == NULL); |
|
285 CX_TEST_ASSERT(child4.prev == marker); |
|
286 CX_TEST_ASSERT(child4.next == NULL); |
|
287 |
|
288 // unlink first child from parent |
|
289 cx_tree_unlink(&child1, tree_node_layout_no_prev); |
|
290 CX_TEST_ASSERT(parent.next == NULL); |
|
291 CX_TEST_ASSERT(parent.prev == NULL); |
|
292 CX_TEST_ASSERT(parent.parent == NULL); |
|
293 CX_TEST_ASSERT(parent.children == &child3); |
|
294 CX_TEST_ASSERT(child1.parent == NULL); |
|
295 CX_TEST_ASSERT(child3.parent == &parent); |
|
296 CX_TEST_ASSERT(child3.children == &child2); |
|
297 CX_TEST_ASSERT(child3.prev == marker); |
|
298 CX_TEST_ASSERT(child3.next == NULL); |
238 } |
299 } |
239 } |
300 } |
240 |
301 |
241 CX_TEST(test_tree2_link_new_child) { |
302 CX_TEST(test_tree2_link_new_child) { |
242 tree_node2 parent = {0}; |
303 tree_node2 parent = {0}; |
2146 |
2207 |
2147 cx_test_register(suite, test_tree_link_new_child); |
2208 cx_test_register(suite, test_tree_link_new_child); |
2148 cx_test_register(suite, test_tree_link_add_child); |
2209 cx_test_register(suite, test_tree_link_add_child); |
2149 cx_test_register(suite, test_tree_link_move_to_other_parent); |
2210 cx_test_register(suite, test_tree_link_move_to_other_parent); |
2150 cx_test_register(suite, test_tree_unlink); |
2211 cx_test_register(suite, test_tree_unlink); |
|
2212 cx_test_register(suite, test_tree_unlink_no_prev); |
2151 cx_test_register(suite, test_tree2_link_new_child); |
2213 cx_test_register(suite, test_tree2_link_new_child); |
2152 cx_test_register(suite, test_tree2_link_add_child); |
2214 cx_test_register(suite, test_tree2_link_add_child); |
2153 cx_test_register(suite, test_tree2_link_move_to_other_parent); |
2215 cx_test_register(suite, test_tree2_link_move_to_other_parent); |
2154 cx_test_register(suite, test_tree2_unlink); |
2216 cx_test_register(suite, test_tree2_unlink); |
2155 cx_test_register(suite, test_tree_search); |
2217 cx_test_register(suite, test_tree_search); |