| 224 cx_foreach(void *, elem, iter) { |
224 cx_foreach(void *, elem, iter) { |
| 225 // investigate the current node |
225 // investigate the current node |
| 226 int ret_elem = sfunc(elem, node); |
226 int ret_elem = sfunc(elem, node); |
| 227 if (ret_elem == 0) { |
227 if (ret_elem == 0) { |
| 228 // if found, exit the search |
228 // if found, exit the search |
| 229 *result = (void *) elem; |
229 *result = elem; |
| 230 ret = 0; |
230 ret = 0; |
| 231 break; |
231 break; |
| 232 } else if (ret_elem > 0 && ret_elem < ret) { |
232 } else if (ret_elem > 0 && ret_elem < ret) { |
| 233 // new distance is better |
233 // new distance is better |
| 234 *result = elem; |
234 *result = elem; |
| 235 ret = ret_elem; |
235 ret = ret_elem; |
| 236 } else { |
236 } else if (ret_elem < 0 || ret_elem > ret) { |
| 237 // not contained or distance is worse, skip entire subtree |
237 // not contained or distance is worse, skip entire subtree |
| 238 cxTreeIteratorContinue(iter); |
238 cxTreeIteratorContinue(iter); |
| 239 } |
239 } |
| 240 |
240 |
| 241 // when we reached the max depth, skip the subtree |
241 // when we reached the max depth, skip the subtree |
| 303 } |
303 } |
| 304 } |
304 } |
| 305 |
305 |
| 306 if (children == NULL) { |
306 if (children == NULL) { |
| 307 // search for the next node |
307 // search for the next node |
| 308 void *next; |
308 void *next = NULL; |
| 309 cx_tree_iter_search_next: |
309 cx_tree_iter_search_next: |
| 310 // check if there is a sibling |
310 // check if there is a sibling, but only if we are not a (subtree-)root |
| 311 if (iter->exiting) { |
311 if (iter->exiting) { |
| 312 next = iter->node_next; |
312 next = iter->node_next; |
| 313 } else { |
313 } else if (iter->depth > 1) { |
| 314 next = tree_next(iter->node); |
314 next = tree_next(iter->node); |
| 315 iter->node_next = next; |
315 iter->node_next = next; |
| 316 } |
316 } |
| 317 if (next == NULL) { |
317 if (next == NULL) { |
| 318 // no sibling, we are done with this node and exit |
318 // no sibling, we are done with this node and exit |
| 324 if (iter->depth == 1) { |
324 if (iter->depth == 1) { |
| 325 // there is no parent - we have iterated the entire tree |
325 // there is no parent - we have iterated the entire tree |
| 326 // invalidate the iterator and free the node stack |
326 // invalidate the iterator and free the node stack |
| 327 iter->node = iter->node_next = NULL; |
327 iter->node = iter->node_next = NULL; |
| 328 iter->stack_capacity = iter->depth = 0; |
328 iter->stack_capacity = iter->depth = 0; |
| 329 free(iter->stack); |
329 cxFreeDefault(iter->stack); |
| 330 iter->stack = NULL; |
330 iter->stack = NULL; |
| 331 } else { |
331 } else { |
| 332 // the parent node can be obtained from the top of stack |
332 // the parent node can be obtained from the top of stack |
| 333 // this way we can avoid the loc_parent in the iterator |
333 // this way we can avoid the loc_parent in the iterator |
| 334 iter->depth--; |
334 iter->depth--; |
| 384 |
384 |
| 385 // visit the root node |
385 // visit the root node |
| 386 iter.node = root; |
386 iter.node = root; |
| 387 if (root != NULL) { |
387 if (root != NULL) { |
| 388 iter.stack_capacity = 16; |
388 iter.stack_capacity = 16; |
| 389 iter.stack = malloc(sizeof(void *) * 16); |
389 iter.stack = cxMallocDefault(sizeof(void *) * 16); |
| 390 iter.stack[0] = root; |
390 iter.stack[0] = root; |
| 391 iter.counter = 1; |
391 iter.counter = 1; |
| 392 iter.depth = 1; |
392 iter.depth = 1; |
| 393 } else { |
393 } else { |
| 394 iter.stack_capacity = 0; |
394 iter.stack_capacity = 0; |
| 414 static void cx_tree_visitor_enqueue_siblings( |
414 static void cx_tree_visitor_enqueue_siblings( |
| 415 struct cx_tree_visitor_s *iter, void *node, ptrdiff_t loc_next) { |
415 struct cx_tree_visitor_s *iter, void *node, ptrdiff_t loc_next) { |
| 416 node = tree_next(node); |
416 node = tree_next(node); |
| 417 while (node != NULL) { |
417 while (node != NULL) { |
| 418 struct cx_tree_visitor_queue_s *q; |
418 struct cx_tree_visitor_queue_s *q; |
| 419 q = malloc(sizeof(struct cx_tree_visitor_queue_s)); |
419 q = cxMallocDefault(sizeof(struct cx_tree_visitor_queue_s)); |
| 420 q->depth = iter->queue_last->depth; |
420 q->depth = iter->queue_last->depth; |
| 421 q->node = node; |
421 q->node = node; |
| 422 iter->queue_last->next = q; |
422 iter->queue_last->next = q; |
| 423 iter->queue_last = q; |
423 iter->queue_last = q; |
| 424 node = tree_next(node); |
424 node = tree_next(node); |
| 443 } else { |
443 } else { |
| 444 children = tree_children(iter->node); |
444 children = tree_children(iter->node); |
| 445 } |
445 } |
| 446 if (children != NULL) { |
446 if (children != NULL) { |
| 447 struct cx_tree_visitor_queue_s *q; |
447 struct cx_tree_visitor_queue_s *q; |
| 448 q = malloc(sizeof(struct cx_tree_visitor_queue_s)); |
448 q = cxMallocDefault(sizeof(struct cx_tree_visitor_queue_s)); |
| 449 q->depth = iter->depth + 1; |
449 q->depth = iter->depth + 1; |
| 450 q->node = children; |
450 q->node = children; |
| 451 if (iter->queue_last == NULL) { |
451 if (iter->queue_last == NULL) { |
| 452 assert(iter->queue_next == NULL); |
452 assert(iter->queue_next == NULL); |
| 453 iter->queue_next = q; |
453 iter->queue_next = q; |