| 47 /** |
47 /** |
| 48 * A depth-first tree iterator. |
48 * A depth-first tree iterator. |
| 49 * |
49 * |
| 50 * This iterator is not position-aware in a strict sense, as it does not assume |
50 * This iterator is not position-aware in a strict sense, as it does not assume |
| 51 * a particular order of elements in the tree. However, the iterator keeps track |
51 * a particular order of elements in the tree. However, the iterator keeps track |
| 52 * of the number of nodes it has passed in a counter variable. |
52 * of the number of nodes it has passed in a counter-variable. |
| 53 * Each node, regardless of the number of passes, is counted only once. |
53 * Each node, regardless of the number of passes, is counted only once. |
| 54 * |
54 * |
| 55 * @note Objects that are pointed to by an iterator are mutable through that |
55 * @note Objects that are pointed to by an iterator are mutable through that |
| 56 * iterator. However, if the |
56 * iterator. However, if the |
| 57 * underlying data structure is mutated by other means than this iterator (e.g. |
57 * underlying data structure is mutated by other means than this iterator (e.g., |
| 58 * elements added or removed), the iterator becomes invalid (regardless of what |
58 * elements added or removed), the iterator becomes invalid (regardless of what |
| 59 * cxIteratorValid() returns). |
59 * cxIteratorValid() returns). |
| 60 * |
60 * |
| 61 * @see CxIterator |
61 * @see CxIterator |
| 62 */ |
62 */ |
| 151 * If you want to discard the iterator before, you MUST manually call |
153 * If you want to discard the iterator before, you MUST manually call |
| 152 * cxTreeVisitorDispose(). |
154 * cxTreeVisitorDispose(). |
| 153 * |
155 * |
| 154 * This iterator is not position-aware in a strict sense, as it does not assume |
156 * This iterator is not position-aware in a strict sense, as it does not assume |
| 155 * a particular order of elements in the tree. However, the iterator keeps track |
157 * a particular order of elements in the tree. However, the iterator keeps track |
| 156 * of the number of nodes it has passed in a counter variable. |
158 * of the number of nodes it has passed in a counter-variable. |
| 157 * Each node, regardless of the number of passes, is counted only once. |
159 * Each node, regardless of the number of passes, is counted only once. |
| 158 * |
160 * |
| 159 * @note Objects that are pointed to by an iterator are mutable through that |
161 * @note Objects that are pointed to by an iterator are mutable through that |
| 160 * iterator. However, if the |
162 * iterator. However, if the |
| 161 * underlying data structure is mutated by other means than this iterator (e.g. |
163 * underlying data structure is mutated by other means than this iterator (e.g., |
| 162 * elements added or removed), the iterator becomes invalid (regardless of what |
164 * elements added or removed), the iterator becomes invalid (regardless of what |
| 163 * cxIteratorValid() returns). |
165 * cxIteratorValid() returns). |
| 164 * |
166 * |
| 165 * @see CxIterator |
167 * @see CxIterator |
| 166 */ |
168 */ |
| 314 * The function should use the returned integer to indicate how close the |
293 * The function should use the returned integer to indicate how close the |
| 315 * match is, where a negative number means that it does not match at all. |
294 * match is, where a negative number means that it does not match at all. |
| 316 * Zero means exact match and a positive number is an implementation defined |
295 * Zero means exact match and a positive number is an implementation defined |
| 317 * measure for the distance to an exact match. |
296 * measure for the distance to an exact match. |
| 318 * |
297 * |
| 319 * For example if a tree stores file path information, a node that is |
298 * For example, consider a tree that stores file path information. |
| 320 * describing a parent directory of a filename that is searched, shall |
299 * A node which is describing a parent directory of a searched file shall |
| 321 * return a positive number to indicate that a child node might contain the |
300 * return a positive number to indicate that a child node might contain the |
| 322 * searched item. On the other hand, if the node denotes a path that is not a |
301 * searched item. On the other hand, if the node denotes a path that is not a |
| 323 * prefix of the searched filename, the function would return -1 to indicate |
302 * prefix of the searched filename, the function would return -1 to indicate |
| 324 * that the search does not need to be continued in that branch. |
303 * that the search does not need to be continued in that branch. |
| 325 * |
304 * |
| 326 * @param node the node that is currently investigated |
305 * @param node the node that is currently investigated |
| 327 * @param data the data that is searched for |
306 * @param data the data that is searched for |
| 328 * |
307 * |
| 329 * @return 0 if the node contains the data, |
308 * @return 0 if the node contains the data, |
| 330 * positive if one of the children might contain the data, |
309 * positive if one of the children might contain the data, |
| 331 * negative if neither the node, nor the children contains the data |
310 * negative if neither the node nor the children contains the data |
| 332 */ |
311 */ |
| 333 cx_attr_nonnull |
|
| 334 typedef int (*cx_tree_search_data_func)(const void *node, const void *data); |
312 typedef int (*cx_tree_search_data_func)(const void *node, const void *data); |
| 335 |
313 |
| 336 |
314 |
| 337 /** |
315 /** |
| 338 * Function pointer for a search function. |
316 * Function pointer for a search function. |
| 344 * The function should use the returned integer to indicate how close the |
322 * The function should use the returned integer to indicate how close the |
| 345 * match is, where a negative number means that it does not match at all. |
323 * match is, where a negative number means that it does not match at all. |
| 346 * Zero means exact match and a positive number is an implementation defined |
324 * Zero means exact match and a positive number is an implementation defined |
| 347 * measure for the distance to an exact match. |
325 * measure for the distance to an exact match. |
| 348 * |
326 * |
| 349 * For example if a tree stores file path information, a node that is |
327 * For example, consider a tree that stores file path information. |
| 350 * describing a parent directory of a filename that is searched, shall |
328 * A node which is describing a parent directory of a searched file shall |
| 351 * return a positive number to indicate that a child node might contain the |
329 * return a positive number to indicate that a child node might contain the |
| 352 * searched item. On the other hand, if the node denotes a path that is not a |
330 * searched item. On the other hand, if the node denotes a path that is not a |
| 353 * prefix of the searched filename, the function would return -1 to indicate |
331 * prefix of the searched filename, the function would return -1 to indicate |
| 354 * that the search does not need to be continued in that branch. |
332 * that the search does not need to be continued in that branch. |
| 355 * |
333 * |
| 356 * @param node the node that is currently investigated |
334 * @param node the node that is currently investigated |
| 357 * @param new_node a new node with the information which is searched |
335 * @param new_node a new node with the information which is searched |
| 358 * |
336 * |
| 359 * @return 0 if @p node contains the same data as @p new_node, |
337 * @return 0 if @p node contains the same data as @p new_node, |
| 360 * positive if one of the children might contain the data, |
338 * positive if one of the children might contain the data, |
| 361 * negative if neither the node, nor the children contains the data |
339 * negative if neither the node nor the children contains the data |
| 362 */ |
340 */ |
| 363 cx_attr_nonnull |
|
| 364 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); |
341 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); |
| 365 |
342 |
| 366 /** |
343 /** |
| 367 * Searches for data in a tree. |
344 * Searches for data in a tree. |
| 368 * |
345 * |
| 369 * When the data cannot be found exactly, the search function might return a |
346 * When the data cannot be found exactly, the search function might return the |
| 370 * closest result which might be a good starting point for adding a new node |
347 * closest result, which might be a good starting point for adding a new node |
| 371 * to the tree (see also #cx_tree_add()). |
348 * to the tree (see also #cx_tree_add()). |
| 372 * |
349 * |
| 373 * Depending on the tree structure it is not necessarily guaranteed that the |
350 * Depending on the tree structure, it is not necessarily guaranteed that the |
| 374 * "closest" match is uniquely defined. This function will search for a node |
351 * "closest" match is uniquely defined. This function will search for a node |
| 375 * with the best match according to the @p sfunc (meaning: the return value of |
352 * with the best match according to the @p sfunc (meaning: the return value of |
| 376 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
353 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
| 377 * node matching the criteria is returned. |
354 * node matching the criteria is returned. |
| 378 * |
355 * |
| 385 * @param loc_next offset in the node struct for the next pointer |
362 * @param loc_next offset in the node struct for the next pointer |
| 386 * @return zero if the node was found exactly, positive if a node was found that |
363 * @return zero if the node was found exactly, positive if a node was found that |
| 387 * could contain the node (but doesn't right now), negative if the tree does not |
364 * could contain the node (but doesn't right now), negative if the tree does not |
| 388 * contain any node that might be related to the searched data |
365 * contain any node that might be related to the searched data |
| 389 */ |
366 */ |
| 390 cx_attr_nonnull |
367 cx_attr_nonnull cx_attr_access_w(5) |
| 391 cx_attr_access_w(5) |
368 CX_EXPORT int cx_tree_search_data(const void *root, size_t depth, |
| 392 cx_attr_export |
369 const void *data, cx_tree_search_data_func sfunc, |
| 393 int cx_tree_search_data( |
370 void **result, ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 394 const void *root, |
|
| 395 size_t depth, |
|
| 396 const void *data, |
|
| 397 cx_tree_search_data_func sfunc, |
|
| 398 void **result, |
|
| 399 ptrdiff_t loc_children, |
|
| 400 ptrdiff_t loc_next |
|
| 401 ); |
|
| 402 |
371 |
| 403 /** |
372 /** |
| 404 * Searches for a node in a tree. |
373 * Searches for a node in a tree. |
| 405 * |
374 * |
| 406 * When no node with the same data can be found, the search function might |
375 * When no node with the same data can be found, the search function might |
| 407 * return a closest result which might be a good starting point for adding the |
376 * return the closest result, which might be a good starting point for adding the |
| 408 * new node to the tree (see also #cx_tree_add()). |
377 * new node to the tree (see also #cx_tree_add()). |
| 409 * |
378 * |
| 410 * Depending on the tree structure it is not necessarily guaranteed that the |
379 * Depending on the tree structure, it is not necessarily guaranteed that the |
| 411 * "closest" match is uniquely defined. This function will search for a node |
380 * "closest" match is uniquely defined. This function will search for a node |
| 412 * with the best match according to the @p sfunc (meaning: the return value of |
381 * with the best match according to the @p sfunc (meaning: the return value of |
| 413 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
382 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
| 414 * node matching the criteria is returned. |
383 * node matching the criteria is returned. |
| 415 * |
384 * |
| 422 * @param loc_next offset in the node struct for the next pointer |
391 * @param loc_next offset in the node struct for the next pointer |
| 423 * @return zero if the node was found exactly, positive if a node was found that |
392 * @return zero if the node was found exactly, positive if a node was found that |
| 424 * could contain the node (but doesn't right now), negative if the tree does not |
393 * could contain the node (but doesn't right now), negative if the tree does not |
| 425 * contain any node that might be related to the searched data |
394 * contain any node that might be related to the searched data |
| 426 */ |
395 */ |
| 427 cx_attr_nonnull |
396 cx_attr_nonnull cx_attr_access_w(5) |
| 428 cx_attr_access_w(5) |
397 CX_EXPORT int cx_tree_search(const void *root, size_t depth, |
| 429 cx_attr_export |
398 const void *node, cx_tree_search_func sfunc, |
| 430 int cx_tree_search( |
399 void **result, ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 431 const void *root, |
|
| 432 size_t depth, |
|
| 433 const void *node, |
|
| 434 cx_tree_search_func sfunc, |
|
| 435 void **result, |
|
| 436 ptrdiff_t loc_children, |
|
| 437 ptrdiff_t loc_next |
|
| 438 ); |
|
| 439 |
400 |
| 440 /** |
401 /** |
| 441 * Creates a depth-first iterator for a tree with the specified root node. |
402 * Creates a depth-first iterator for a tree with the specified root node. |
| 442 * |
403 * |
| 443 * @note A tree iterator needs to maintain a stack of visited nodes, which is |
404 * @note A tree iterator needs to maintain a stack of visited nodes, which is |
| 444 * allocated using stdlib malloc(). |
405 * allocated using the cxDefaultAllocator. |
| 445 * When the iterator becomes invalid, this memory is automatically released. |
406 * When the iterator becomes invalid, this memory is automatically released. |
| 446 * However, if you wish to cancel the iteration before the iterator becomes |
407 * However, if you wish to cancel the iteration before the iterator becomes |
| 447 * invalid by itself, you MUST call cxTreeIteratorDispose() manually to release |
408 * invalid by itself, you MUST call cxTreeIteratorDispose() manually to release |
| 448 * the memory. |
409 * the memory. |
| 449 * |
410 * |
| 456 * @param loc_next offset in the node struct for the next pointer |
417 * @param loc_next offset in the node struct for the next pointer |
| 457 * @return the new tree iterator |
418 * @return the new tree iterator |
| 458 * @see cxTreeIteratorDispose() |
419 * @see cxTreeIteratorDispose() |
| 459 */ |
420 */ |
| 460 cx_attr_nodiscard |
421 cx_attr_nodiscard |
| 461 cx_attr_export |
422 CX_EXPORT CxTreeIterator cx_tree_iterator(void *root, bool visit_on_exit, |
| 462 CxTreeIterator cx_tree_iterator( |
423 ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 463 void *root, |
|
| 464 bool visit_on_exit, |
|
| 465 ptrdiff_t loc_children, |
|
| 466 ptrdiff_t loc_next |
|
| 467 ); |
|
| 468 |
424 |
| 469 /** |
425 /** |
| 470 * Creates a breadth-first iterator for a tree with the specified root node. |
426 * Creates a breadth-first iterator for a tree with the specified root node. |
| 471 * |
427 * |
| 472 * @note A tree visitor needs to maintain a queue of to be visited nodes, which |
428 * @note A tree visitor needs to maintain a queue of to-be visited nodes, which |
| 473 * is allocated using stdlib malloc(). |
429 * is allocated using the cxDefaultAllocator. |
| 474 * When the visitor becomes invalid, this memory is automatically released. |
430 * When the visitor becomes invalid, this memory is automatically released. |
| 475 * However, if you wish to cancel the iteration before the visitor becomes |
431 * However, if you wish to cancel the iteration before the visitor becomes |
| 476 * invalid by itself, you MUST call cxTreeVisitorDispose() manually to release |
432 * invalid by itself, you MUST call cxTreeVisitorDispose() manually to release |
| 477 * the memory. |
433 * the memory. |
| 478 * |
434 * |
| 483 * @param loc_next offset in the node struct for the next pointer |
439 * @param loc_next offset in the node struct for the next pointer |
| 484 * @return the new tree visitor |
440 * @return the new tree visitor |
| 485 * @see cxTreeVisitorDispose() |
441 * @see cxTreeVisitorDispose() |
| 486 */ |
442 */ |
| 487 cx_attr_nodiscard |
443 cx_attr_nodiscard |
| 488 cx_attr_export |
444 CX_EXPORT CxTreeVisitor cx_tree_visitor(void *root, |
| 489 CxTreeVisitor cx_tree_visitor( |
445 ptrdiff_t loc_children, ptrdiff_t loc_next); |
| 490 void *root, |
|
| 491 ptrdiff_t loc_children, |
|
| 492 ptrdiff_t loc_next |
|
| 493 ); |
|
| 494 |
446 |
| 495 /** |
447 /** |
| 496 * Describes a function that creates a tree node from the specified data. |
448 * Describes a function that creates a tree node from the specified data. |
| 497 * The first argument points to the data the node shall contain and |
449 * The first argument points to the data the node shall contain, and |
| 498 * the second argument may be used for additional data (e.g. an allocator). |
450 * the second argument may be used for additional data (e.g., an allocator). |
| 499 * Functions of this type shall either return a new pointer to a newly |
451 * Functions of this type shall either return a new pointer to a newly |
| 500 * created node or @c NULL when allocation fails. |
452 * created node or @c NULL when allocation fails. |
| 501 * |
453 * |
| 502 * @note the function may leave the node pointers in the struct uninitialized. |
454 * @note the function may leave the node pointers in the struct uninitialized. |
| 503 * The caller is responsible to set them according to the intended use case. |
455 * The caller is responsible to set them according to the intended use case. |
| 504 */ |
456 */ |
| 505 cx_attr_nonnull_arg(1) |
|
| 506 typedef void *(*cx_tree_node_create_func)(const void *, void *); |
457 typedef void *(*cx_tree_node_create_func)(const void *, void *); |
| 507 |
458 |
| 508 /** |
459 /** |
| 509 * The local search depth for a new subtree when adding multiple elements. |
460 * The local search depth for a new subtree when adding multiple elements. |
| 510 * The default value is 3. |
461 * The default value is 3. |
| 511 * This variable is used by #cx_tree_add_array() and #cx_tree_add_iter() to |
462 * This variable is used by #cx_tree_add_array() and #cx_tree_add_iter() to |
| 512 * implement optimized insertion of multiple elements into a tree. |
463 * implement optimized insertion of multiple elements into a tree. |
| 513 */ |
464 */ |
| 514 cx_attr_export |
465 CX_EXPORT extern unsigned int cx_tree_add_look_around_depth; |
| 515 extern unsigned int cx_tree_add_look_around_depth; |
|
| 516 |
466 |
| 517 /** |
467 /** |
| 518 * Adds multiple elements efficiently to a tree. |
468 * Adds multiple elements efficiently to a tree. |
| 519 * |
469 * |
| 520 * Once an element cannot be added to the tree, this function returns, leaving |
470 * Once an element cannot be added to the tree, this function returns, leaving |
| 550 * @param loc_prev optional offset in the node struct for the prev pointer |
500 * @param loc_prev optional offset in the node struct for the prev pointer |
| 551 * @param loc_next offset in the node struct for the next pointer |
501 * @param loc_next offset in the node struct for the next pointer |
| 552 * @return the number of nodes created and added |
502 * @return the number of nodes created and added |
| 553 * @see cx_tree_add() |
503 * @see cx_tree_add() |
| 554 */ |
504 */ |
| 555 cx_attr_nonnull_arg(1, 3, 4, 6, 7) |
505 cx_attr_nonnull_arg(1, 3, 4, 6, 7) cx_attr_access_w(6) |
| 556 cx_attr_access_w(6) |
506 CX_EXPORT size_t cx_tree_add_iter(struct cx_iterator_base_s *iter, size_t num, |
| 557 cx_attr_export |
507 cx_tree_search_func sfunc, cx_tree_node_create_func cfunc, |
| 558 size_t cx_tree_add_iter( |
508 void *cdata, void **failed, void *root, |
| 559 struct cx_iterator_base_s *iter, |
509 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 560 size_t num, |
510 ptrdiff_t loc_prev, ptrdiff_t loc_next); |
| 561 cx_tree_search_func sfunc, |
|
| 562 cx_tree_node_create_func cfunc, |
|
| 563 void *cdata, |
|
| 564 void **failed, |
|
| 565 void *root, |
|
| 566 ptrdiff_t loc_parent, |
|
| 567 ptrdiff_t loc_children, |
|
| 568 ptrdiff_t loc_last_child, |
|
| 569 ptrdiff_t loc_prev, |
|
| 570 ptrdiff_t loc_next |
|
| 571 ); |
|
| 572 |
511 |
| 573 /** |
512 /** |
| 574 * Adds multiple elements efficiently to a tree. |
513 * Adds multiple elements efficiently to a tree. |
| 575 * |
514 * |
| 576 * Once an element cannot be added to the tree, this function returns, storing |
515 * Once an element cannot be added to the tree, this function returns, storing |
| 605 * @param loc_prev optional offset in the node struct for the prev pointer |
544 * @param loc_prev optional offset in the node struct for the prev pointer |
| 606 * @param loc_next offset in the node struct for the next pointer |
545 * @param loc_next offset in the node struct for the next pointer |
| 607 * @return the number of array elements successfully processed |
546 * @return the number of array elements successfully processed |
| 608 * @see cx_tree_add() |
547 * @see cx_tree_add() |
| 609 */ |
548 */ |
| 610 cx_attr_nonnull_arg(1, 4, 5, 7, 8) |
549 cx_attr_nonnull_arg(1, 4, 5, 7, 8) cx_attr_access_w(7) |
| 611 cx_attr_access_w(7) |
550 CX_EXPORT size_t cx_tree_add_array(const void *src, size_t num, size_t elem_size, |
| 612 cx_attr_export |
551 cx_tree_search_func sfunc, cx_tree_node_create_func cfunc, |
| 613 size_t cx_tree_add_array( |
552 void *cdata, void **failed, void *root, |
| 614 const void *src, |
553 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 615 size_t num, |
554 ptrdiff_t loc_prev, ptrdiff_t loc_next); |
| 616 size_t elem_size, |
|
| 617 cx_tree_search_func sfunc, |
|
| 618 cx_tree_node_create_func cfunc, |
|
| 619 void *cdata, |
|
| 620 void **failed, |
|
| 621 void *root, |
|
| 622 ptrdiff_t loc_parent, |
|
| 623 ptrdiff_t loc_children, |
|
| 624 ptrdiff_t loc_last_child, |
|
| 625 ptrdiff_t loc_prev, |
|
| 626 ptrdiff_t loc_next |
|
| 627 ); |
|
| 628 |
555 |
| 629 /** |
556 /** |
| 630 * Adds data to a tree. |
557 * Adds data to a tree. |
| 631 * |
558 * |
| 632 * An adequate location where to add the new tree node is searched with the |
559 * An adequate location where to add the new tree node is searched with the |
| 633 * specified @p sfunc. |
560 * specified @p sfunc. |
| 634 * |
561 * |
| 635 * When a location is found, the @p cfunc will be invoked with @p cdata. |
562 * When a location is found, the @p cfunc will be invoked with @p cdata. |
| 636 * |
563 * |
| 637 * The node returned by @p cfunc will be linked into the tree. |
564 * The node returned by @p cfunc will be linked into the tree. |
| 638 * When @p sfunc returned a positive integer, the new node will be linked as a |
565 * When @p sfunc returns a positive integer, the new node will be linked as a |
| 639 * child. The other children (now siblings of the new node) are then checked |
566 * child. The other children (now siblings of the new node) are then checked |
| 640 * with @p sfunc, whether they could be children of the new node and re-linked |
567 * with @p sfunc, whether they could be children of the new node and re-linked |
| 641 * accordingly. |
568 * accordingly. |
| 642 * |
569 * |
| 643 * When @p sfunc returned zero and the found node has a parent, the new |
570 * When @p sfunc returns zero and the found node has a parent, the new |
| 644 * node will be added as sibling - otherwise, the new node will be added |
571 * node will be added as a sibling - otherwise, the new node will be added |
| 645 * as a child. |
572 * as a child. |
| 646 * |
573 * |
| 647 * When @p sfunc returned a negative value, the new node will not be added to |
574 * When @p sfunc returns a negative value, the new node will not be added to |
| 648 * the tree and this function returns a non-zero value. |
575 * the tree, and this function returns a non-zero value. |
| 649 * The caller should check if @p cnode contains a node pointer and deal with the |
576 * The caller should check if @p cnode contains a node pointer and deal with the |
| 650 * node that could not be added. |
577 * node that could not be added. |
| 651 * |
578 * |
| 652 * This function also returns a non-zero value when @p cfunc tries to allocate |
579 * This function also returns a non-zero value when @p cfunc tries to allocate |
| 653 * a new node but fails to do so. In that case, the pointer stored to @p cnode |
580 * a new node but fails to do so. In that case, the pointer stored to @p cnode |
| 669 * @param loc_prev optional offset in the node struct for the prev pointer |
596 * @param loc_prev optional offset in the node struct for the prev pointer |
| 670 * @param loc_next offset in the node struct for the next pointer |
597 * @param loc_next offset in the node struct for the next pointer |
| 671 * @return zero when a new node was created and added to the tree, |
598 * @return zero when a new node was created and added to the tree, |
| 672 * non-zero otherwise |
599 * non-zero otherwise |
| 673 */ |
600 */ |
| 674 cx_attr_nonnull_arg(1, 2, 3, 5, 6) |
601 cx_attr_nonnull_arg(1, 2, 3, 5, 6) cx_attr_access_w(5) |
| 675 cx_attr_access_w(5) |
602 CX_EXPORT int cx_tree_add(const void *src, |
| 676 cx_attr_export |
603 cx_tree_search_func sfunc, cx_tree_node_create_func cfunc, |
| 677 int cx_tree_add( |
604 void *cdata, void **cnode, void *root, |
| 678 const void *src, |
605 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 679 cx_tree_search_func sfunc, |
606 ptrdiff_t loc_prev, ptrdiff_t loc_next); |
| 680 cx_tree_node_create_func cfunc, |
|
| 681 void *cdata, |
|
| 682 void **cnode, |
|
| 683 void *root, |
|
| 684 ptrdiff_t loc_parent, |
|
| 685 ptrdiff_t loc_children, |
|
| 686 ptrdiff_t loc_last_child, |
|
| 687 ptrdiff_t loc_prev, |
|
| 688 ptrdiff_t loc_next |
|
| 689 ); |
|
| 690 |
607 |
| 691 |
608 |
| 692 /** |
609 /** |
| 693 * Tree class type. |
610 * Tree class type. |
| 694 */ |
611 */ |
| 846 * Member function for inserting a single element. |
763 * Member function for inserting a single element. |
| 847 * |
764 * |
| 848 * Implementations SHALL NOT simply invoke @p insert_many as this comes |
765 * Implementations SHALL NOT simply invoke @p insert_many as this comes |
| 849 * with too much overhead. |
766 * with too much overhead. |
| 850 */ |
767 */ |
| 851 int (*insert_element)( |
768 int (*insert_element)(struct cx_tree_s *tree, const void *data); |
| 852 struct cx_tree_s *tree, |
|
| 853 const void *data |
|
| 854 ); |
|
| 855 |
769 |
| 856 /** |
770 /** |
| 857 * Member function for inserting multiple elements. |
771 * Member function for inserting multiple elements. |
| 858 * |
772 * |
| 859 * Implementations SHALL avoid to perform a full search in the tree for |
773 * Implementations SHALL avoid performing a full search in the tree for |
| 860 * every element even though the source data MAY be unsorted. |
774 * every element even though the source data MAY be unsorted. |
| 861 */ |
775 */ |
| 862 size_t (*insert_many)( |
776 size_t (*insert_many)(struct cx_tree_s *tree, struct cx_iterator_base_s *iter, size_t n); |
| 863 struct cx_tree_s *tree, |
|
| 864 struct cx_iterator_base_s *iter, |
|
| 865 size_t n |
|
| 866 ); |
|
| 867 |
777 |
| 868 /** |
778 /** |
| 869 * Member function for finding a node. |
779 * Member function for finding a node. |
| 870 */ |
780 */ |
| 871 void *(*find)( |
781 void *(*find)(struct cx_tree_s *tree, const void *subtree, const void *data, size_t depth); |
| 872 struct cx_tree_s *tree, |
|
| 873 const void *subtree, |
|
| 874 const void *data, |
|
| 875 size_t depth |
|
| 876 ); |
|
| 877 }; |
782 }; |
| 878 |
783 |
| 879 /** |
784 /** |
| 880 * Common type for all tree implementations. |
785 * Common type for all tree implementations. |
| 881 */ |
786 */ |
| 882 typedef struct cx_tree_s CxTree; |
787 typedef struct cx_tree_s CxTree; |
| 883 |
788 |
| 884 |
789 |
| 885 /** |
790 /** |
| 886 * Destroys a node and it's subtree. |
791 * Destroys a node and its subtree. |
| 887 * |
792 * |
| 888 * It is guaranteed that the simple destructor is invoked before |
793 * It is guaranteed that the simple destructor is invoked before |
| 889 * the advanced destructor, starting with the leaf nodes of the subtree. |
794 * the advanced destructor, starting with the leaf nodes of the subtree. |
| 890 * |
795 * |
| 891 * When this function is invoked on the root node of the tree, it destroys the |
796 * When this function is invoked on the root node of the tree, it destroys the |
| 968 * @param loc_next offset in the node struct for the next pointer |
871 * @param loc_next offset in the node struct for the next pointer |
| 969 * @return the new tree |
872 * @return the new tree |
| 970 * @see cxTreeCreateSimple() |
873 * @see cxTreeCreateSimple() |
| 971 * @see cxTreeCreateWrapped() |
874 * @see cxTreeCreateWrapped() |
| 972 */ |
875 */ |
| 973 cx_attr_nonnull_arg(2, 3, 4) |
876 cx_attr_nonnull_arg(2, 3, 4) cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxTreeFree, 1) |
| 974 cx_attr_nodiscard |
877 CX_EXPORT CxTree *cxTreeCreate(const CxAllocator *allocator, cx_tree_node_create_func create_func, |
| 975 cx_attr_malloc |
878 cx_tree_search_func search_func, cx_tree_search_data_func search_data_func, |
| 976 cx_attr_dealloc(cxTreeFree, 1) |
879 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 977 cx_attr_export |
880 ptrdiff_t loc_prev, ptrdiff_t loc_next); |
| 978 CxTree *cxTreeCreate( |
|
| 979 const CxAllocator *allocator, |
|
| 980 cx_tree_node_create_func create_func, |
|
| 981 cx_tree_search_func search_func, |
|
| 982 cx_tree_search_data_func search_data_func, |
|
| 983 ptrdiff_t loc_parent, |
|
| 984 ptrdiff_t loc_children, |
|
| 985 ptrdiff_t loc_last_child, |
|
| 986 ptrdiff_t loc_prev, |
|
| 987 ptrdiff_t loc_next |
|
| 988 ); |
|
| 989 |
881 |
| 990 /** |
882 /** |
| 991 * Creates a new tree structure based on a default layout. |
883 * Creates a new tree structure based on a default layout. |
| 992 * |
884 * |
| 993 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as first |
885 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as the first |
| 994 * member (or at least respect the default offsets specified in the tree |
886 * member (or at least respect the default offsets specified in the tree |
| 995 * struct) and they MUST be allocated with the specified allocator. |
887 * struct), and they MUST be allocated with the specified allocator. |
| 996 * |
888 * |
| 997 * @note This function will also register an advanced destructor which |
889 * @note This function will also register an advanced destructor which |
| 998 * will free the nodes with the allocator's free() method. |
890 * will free the nodes with the allocator's free() method. |
| 999 * |
891 * |
| 1000 * @param allocator (@c CxAllocator*) the allocator that shall be used |
892 * @param allocator (@c CxAllocator*) the allocator that shall be used |
| 1002 * @param search_func (@c cx_tree_search_func) a function that compares two nodes |
894 * @param search_func (@c cx_tree_search_func) a function that compares two nodes |
| 1003 * @param search_data_func (@c cx_tree_search_data_func) a function that compares a node with data |
895 * @param search_data_func (@c cx_tree_search_data_func) a function that compares a node with data |
| 1004 * @return (@c CxTree*) the new tree |
896 * @return (@c CxTree*) the new tree |
| 1005 * @see cxTreeCreate() |
897 * @see cxTreeCreate() |
| 1006 */ |
898 */ |
| 1007 #define cxTreeCreateSimple(\ |
899 #define cxTreeCreateSimple(allocator, create_func, search_func, search_data_func) \ |
| 1008 allocator, create_func, search_func, search_data_func \ |
900 cxTreeCreate(allocator, create_func, search_func, search_data_func, cx_tree_node_base_layout) |
| 1009 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \ |
|
| 1010 cx_tree_node_base_layout) |
|
| 1011 |
901 |
| 1012 /** |
902 /** |
| 1013 * Creates a new tree structure based on an existing tree. |
903 * Creates a new tree structure based on an existing tree. |
| 1014 * |
904 * |
| 1015 * The specified @p allocator will be used for creating the tree struct. |
905 * The specified @p allocator will be used for creating the tree struct. |
| 1016 * |
906 * |
| 1017 * @attention This function will create an incompletely defined tree structure |
907 * @attention This function will create an incompletely defined tree structure |
| 1018 * where neither the create function, the search function, nor a destructor |
908 * where neither the create function, the search function, nor a destructor |
| 1019 * will be set. If you wish to use any of this functionality for the wrapped |
909 * will be set. If you wish to use any of this functionality for the wrapped |
| 1020 * tree, you need to specify those functions afterwards. |
910 * tree, you need to specify those functions afterward. |
| 1021 * |
911 * |
| 1022 * @param allocator the allocator that was used for nodes of the wrapped tree |
912 * @param allocator the allocator that was used for nodes of the wrapped tree |
| 1023 * (if @c NULL, a default stdlib allocator is assumed) |
913 * (if @c NULL, the cxDefaultAllocator is assumed) |
| 1024 * @param root the root node of the tree that shall be wrapped |
914 * @param root the root node of the tree that shall be wrapped |
| 1025 * @param loc_parent offset in the node struct for the parent pointer |
915 * @param loc_parent offset in the node struct for the parent pointer |
| 1026 * @param loc_children offset in the node struct for the children linked list |
916 * @param loc_children offset in the node struct for the children linked list |
| 1027 * @param loc_last_child optional offset in the node struct for the pointer to |
917 * @param loc_last_child optional offset in the node struct for the pointer to |
| 1028 * the last child in the linked list (negative if there is no such pointer) |
918 * the last child in the linked list (negative if there is no such pointer) |
| 1029 * @param loc_prev optional offset in the node struct for the prev pointer |
919 * @param loc_prev optional offset in the node struct for the prev pointer |
| 1030 * @param loc_next offset in the node struct for the next pointer |
920 * @param loc_next offset in the node struct for the next pointer |
| 1031 * @return the new tree |
921 * @return the new tree |
| 1032 * @see cxTreeCreate() |
922 * @see cxTreeCreate() |
| 1033 */ |
923 */ |
| 1034 cx_attr_nonnull_arg(2) |
924 cx_attr_nonnull_arg(2) cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxTreeFree, 1) |
| 1035 cx_attr_nodiscard |
925 CX_EXPORT CxTree *cxTreeCreateWrapped(const CxAllocator *allocator, void *root, |
| 1036 cx_attr_malloc |
926 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
| 1037 cx_attr_dealloc(cxTreeFree, 1) |
927 ptrdiff_t loc_prev, ptrdiff_t loc_next); |
| 1038 cx_attr_export |
|
| 1039 CxTree *cxTreeCreateWrapped( |
|
| 1040 const CxAllocator *allocator, |
|
| 1041 void *root, |
|
| 1042 ptrdiff_t loc_parent, |
|
| 1043 ptrdiff_t loc_children, |
|
| 1044 ptrdiff_t loc_last_child, |
|
| 1045 ptrdiff_t loc_prev, |
|
| 1046 ptrdiff_t loc_next |
|
| 1047 ); |
|
| 1048 |
928 |
| 1049 /** |
929 /** |
| 1050 * Inserts data into the tree. |
930 * Inserts data into the tree. |
| 1051 * |
931 * |
| 1052 * @remark For this function to work, the tree needs specified search and |
932 * @remark For this function to work, the tree needs specified search and |
| 1150 * @param data the data to search for |
1003 * @param data the data to search for |
| 1151 * @param subtree_root the node where to start |
1004 * @param subtree_root the node where to start |
| 1152 * @param max_depth the maximum search depth |
1005 * @param max_depth the maximum search depth |
| 1153 * @return the first matching node, or @c NULL when the data cannot be found |
1006 * @return the first matching node, or @c NULL when the data cannot be found |
| 1154 */ |
1007 */ |
| 1155 cx_attr_nonnull |
1008 cx_attr_nonnull cx_attr_nodiscard |
| 1156 cx_attr_nodiscard |
1009 CX_EXPORT void *cxTreeFindInSubtree(CxTree *tree, const void *data, void *subtree_root, size_t max_depth); |
| 1157 static inline void *cxTreeFindInSubtree( |
|
| 1158 CxTree *tree, |
|
| 1159 const void *data, |
|
| 1160 void *subtree_root, |
|
| 1161 size_t max_depth |
|
| 1162 ) { |
|
| 1163 return tree->cl->find(tree, subtree_root, data, max_depth); |
|
| 1164 } |
|
| 1165 |
1010 |
| 1166 /** |
1011 /** |
| 1167 * Determines the size of the specified subtree. |
1012 * Determines the size of the specified subtree. |
| 1168 * |
1013 * |
| 1169 * @param tree the tree |
1014 * @param tree the tree |
| 1170 * @param subtree_root the root node of the subtree |
1015 * @param subtree_root the root node of the subtree |
| 1171 * @return the number of nodes in the specified subtree |
1016 * @return the number of nodes in the specified subtree |
| 1172 */ |
1017 */ |
| 1173 cx_attr_nonnull |
1018 cx_attr_nonnull cx_attr_nodiscard |
| 1174 cx_attr_nodiscard |
1019 CX_EXPORT size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
| 1175 cx_attr_export |
|
| 1176 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
|
| 1177 |
1020 |
| 1178 /** |
1021 /** |
| 1179 * Determines the depth of the specified subtree. |
1022 * Determines the depth of the specified subtree. |
| 1180 * |
1023 * |
| 1181 * @param tree the tree |
1024 * @param tree the tree |
| 1182 * @param subtree_root the root node of the subtree |
1025 * @param subtree_root the root node of the subtree |
| 1183 * @return the tree depth including the @p subtree_root |
1026 * @return the tree depth including the @p subtree_root |
| 1184 */ |
1027 */ |
| 1185 cx_attr_nonnull |
1028 cx_attr_nonnull cx_attr_nodiscard |
| 1186 cx_attr_nodiscard |
1029 CX_EXPORT size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
| 1187 cx_attr_export |
1030 |
| 1188 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
1031 /** |
| |
1032 * Determines the size of the entire tree. |
| |
1033 * |
| |
1034 * @param tree the tree |
| |
1035 * @return the tree size, counting the root as one |
| |
1036 */ |
| |
1037 cx_attr_nonnull cx_attr_nodiscard |
| |
1038 CX_EXPORT size_t cxTreeSize(CxTree *tree); |
| 1189 |
1039 |
| 1190 /** |
1040 /** |
| 1191 * Determines the depth of the entire tree. |
1041 * Determines the depth of the entire tree. |
| 1192 * |
1042 * |
| 1193 * @param tree the tree |
1043 * @param tree the tree |
| 1194 * @return the tree depth, counting the root as one |
1044 * @return the tree depth, counting the root as one |
| 1195 */ |
1045 */ |
| 1196 cx_attr_nonnull |
1046 cx_attr_nonnull cx_attr_nodiscard |
| 1197 cx_attr_nodiscard |
1047 CX_EXPORT size_t cxTreeDepth(CxTree *tree); |
| 1198 cx_attr_export |
|
| 1199 size_t cxTreeDepth(CxTree *tree); |
|
| 1200 |
1048 |
| 1201 /** |
1049 /** |
| 1202 * Creates a depth-first iterator for the specified tree starting in @p node. |
1050 * Creates a depth-first iterator for the specified tree starting in @p node. |
| 1203 * |
1051 * |
| 1204 * If the node is not part of the tree, the behavior is undefined. |
1052 * If the node is not part of the tree, the behavior is undefined. |
| 1231 * @param tree the tree to iterate |
1069 * @param tree the tree to iterate |
| 1232 * @param node the node where to start |
1070 * @param node the node where to start |
| 1233 * @return a tree visitor (a.k.a. breadth-first iterator) |
1071 * @return a tree visitor (a.k.a. breadth-first iterator) |
| 1234 * @see cxTreeIterate() |
1072 * @see cxTreeIterate() |
| 1235 */ |
1073 */ |
| 1236 cx_attr_nonnull |
1074 cx_attr_nonnull cx_attr_nodiscard |
| 1237 cx_attr_nodiscard |
1075 CX_EXPORT CxTreeVisitor cxTreeVisitSubtree(CxTree *tree, void *node); |
| 1238 static inline CxTreeVisitor cxTreeVisitSubtree(CxTree *tree, void *node) { |
|
| 1239 return cx_tree_visitor( |
|
| 1240 node, tree->loc_children, tree->loc_next |
|
| 1241 ); |
|
| 1242 } |
|
| 1243 |
1076 |
| 1244 /** |
1077 /** |
| 1245 * Creates a depth-first iterator for the specified tree. |
1078 * Creates a depth-first iterator for the specified tree. |
| 1246 * |
1079 * |
| 1247 * @param tree the tree to iterate |
1080 * @param tree the tree to iterate |
| 1248 * @param visit_on_exit true, if the iterator shall visit a node again when |
1081 * @param visit_on_exit true, if the iterator shall visit a node again when |
| 1249 * leaving the subtree |
1082 * leaving the subtree |
| 1250 * @return a tree iterator (depth-first) |
1083 * @return a tree iterator (depth-first) |
| 1251 * @see cxTreeVisit() |
1084 * @see cxTreeVisit() |
| 1252 */ |
1085 */ |
| 1253 cx_attr_nonnull |
1086 cx_attr_nonnull cx_attr_nodiscard |
| 1254 cx_attr_nodiscard |
1087 CX_EXPORT CxTreeIterator cxTreeIterate(CxTree *tree, bool visit_on_exit); |
| 1255 static inline CxTreeIterator cxTreeIterate( |
|
| 1256 CxTree *tree, |
|
| 1257 bool visit_on_exit |
|
| 1258 ) { |
|
| 1259 return cxTreeIterateSubtree(tree, tree->root, visit_on_exit); |
|
| 1260 } |
|
| 1261 |
1088 |
| 1262 /** |
1089 /** |
| 1263 * Creates a breadth-first iterator for the specified tree. |
1090 * Creates a breadth-first iterator for the specified tree. |
| 1264 * |
1091 * |
| 1265 * @param tree the tree to iterate |
1092 * @param tree the tree to iterate |
| 1266 * @return a tree visitor (a.k.a. breadth-first iterator) |
1093 * @return a tree visitor (a.k.a. breadth-first iterator) |
| 1267 * @see cxTreeIterate() |
1094 * @see cxTreeIterate() |
| 1268 */ |
1095 */ |
| 1269 cx_attr_nonnull |
1096 cx_attr_nonnull cx_attr_nodiscard |
| 1270 cx_attr_nodiscard |
1097 CxTreeVisitor cxTreeVisit(CxTree *tree); |
| 1271 static inline CxTreeVisitor cxTreeVisit(CxTree *tree) { |
|
| 1272 return cxTreeVisitSubtree(tree, tree->root); |
|
| 1273 } |
|
| 1274 |
1098 |
| 1275 /** |
1099 /** |
| 1276 * Sets the (new) parent of the specified child. |
1100 * Sets the (new) parent of the specified child. |
| 1277 * |
1101 * |
| 1278 * If the @p child is not already member of the tree, this function behaves |
1102 * If the @p child is not already a member of the tree, this function behaves |
| 1279 * as #cxTreeAddChildNode(). |
1103 * as #cxTreeAddChildNode(). |
| 1280 * |
1104 * |
| 1281 * @param tree the tree |
1105 * @param tree the tree |
| 1282 * @param parent the (new) parent of the child |
1106 * @param parent the (new) parent of the child |
| 1283 * @param child the node to add |
1107 * @param child the node to add |
| 1284 * @see cxTreeAddChildNode() |
1108 * @see cxTreeAddChildNode() |
| 1285 */ |
1109 */ |
| 1286 cx_attr_nonnull |
1110 cx_attr_nonnull |
| 1287 cx_attr_export |
1111 CX_EXPORT void cxTreeSetParent(CxTree *tree, void *parent, void *child); |
| 1288 void cxTreeSetParent( |
|
| 1289 CxTree *tree, |
|
| 1290 void *parent, |
|
| 1291 void *child |
|
| 1292 ); |
|
| 1293 |
1112 |
| 1294 /** |
1113 /** |
| 1295 * Adds a new node to the tree. |
1114 * Adds a new node to the tree. |
| 1296 * |
1115 * |
| 1297 * If the @p child is already member of the tree, the behavior is undefined. |
1116 * If the @p child is already a member of the tree, the behavior is undefined. |
| 1298 * Use #cxTreeSetParent() if you want to move a subtree to another location. |
1117 * Use #cxTreeSetParent() if you want to move a subtree to another location. |
| 1299 * |
1118 * |
| 1300 * @attention The node may be externally created, but MUST obey the same rules |
1119 * @attention The node may be externally created, but MUST obey the same rules |
| 1301 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use |
1120 * as if it was created by the tree itself with #cxTreeAddChild() (e.g., use |
| 1302 * the same allocator). |
1121 * the same allocator). |
| 1303 * |
1122 * |
| 1304 * @param tree the tree |
1123 * @param tree the tree |
| 1305 * @param parent the parent of the node to add |
1124 * @param parent the parent of the node to add |
| 1306 * @param child the node to add |
1125 * @param child the node to add |
| 1307 * @see cxTreeSetParent() |
1126 * @see cxTreeSetParent() |
| 1308 */ |
1127 */ |
| 1309 cx_attr_nonnull |
1128 cx_attr_nonnull |
| 1310 cx_attr_export |
1129 CX_EXPORT void cxTreeAddChildNode(CxTree *tree, void *parent, void *child); |
| 1311 void cxTreeAddChildNode( |
|
| 1312 CxTree *tree, |
|
| 1313 void *parent, |
|
| 1314 void *child |
|
| 1315 ); |
|
| 1316 |
1130 |
| 1317 /** |
1131 /** |
| 1318 * Creates a new node and adds it to the tree. |
1132 * Creates a new node and adds it to the tree. |
| 1319 * |
1133 * |
| 1320 * With this function you can decide where exactly the new node shall be added. |
1134 * With this function you can decide where exactly the new node shall be added. |
| 1321 * If you specified an appropriate search function, you may want to consider |
1135 * If you specified an appropriate search function, you may want to consider |
| 1322 * leaving this task to the tree by using #cxTreeInsert(). |
1136 * leaving this task to the tree by using #cxTreeInsert(). |
| 1323 * |
1137 * |
| 1324 * Be aware that adding nodes at arbitrary locations in the tree might cause |
1138 * Be aware that adding nodes at arbitrary locations in the tree might cause |
| 1325 * wrong or undesired results when subsequently invoking #cxTreeInsert() and |
1139 * wrong or undesired results when subsequently invoking #cxTreeInsert(), and |
| 1326 * the invariant imposed by the search function does not hold any longer. |
1140 * the invariant imposed by the search function does not hold any longer. |
| 1327 * |
1141 * |
| 1328 * @param tree the tree |
1142 * @param tree the tree |
| 1329 * @param parent the parent node of the new node |
1143 * @param parent the parent node of the new node |
| 1330 * @param data the data that will be submitted to the create function |
1144 * @param data the data that will be submitted to the create function |
| 1331 * @return zero when the new node was created, non-zero on allocation failure |
1145 * @return zero when the new node was created, non-zero on allocation failure |
| 1332 * @see cxTreeInsert() |
1146 * @see cxTreeInsert() |
| 1333 */ |
1147 */ |
| 1334 cx_attr_nonnull |
1148 cx_attr_nonnull |
| 1335 cx_attr_export |
1149 CX_EXPORT int cxTreeAddChild(CxTree *tree, void *parent, const void *data); |
| 1336 int cxTreeAddChild( |
|
| 1337 CxTree *tree, |
|
| 1338 void *parent, |
|
| 1339 const void *data |
|
| 1340 ); |
|
| 1341 |
1150 |
| 1342 /** |
1151 /** |
| 1343 * A function that is invoked when a node needs to be re-linked to a new parent. |
1152 * A function that is invoked when a node needs to be re-linked to a new parent. |
| 1344 * |
1153 * |
| 1345 * When a node is re-linked, sometimes the contents need to be updated. |
1154 * When a node is re-linked, sometimes the contents need to be updated. |
| 1371 * @param relink_func optional callback to update the content of each re-linked |
1179 * @param relink_func optional callback to update the content of each re-linked |
| 1372 * node |
1180 * node |
| 1373 * @return zero on success, non-zero if @p node is the root node of the tree |
1181 * @return zero on success, non-zero if @p node is the root node of the tree |
| 1374 */ |
1182 */ |
| 1375 cx_attr_nonnull_arg(1, 2) |
1183 cx_attr_nonnull_arg(1, 2) |
| 1376 cx_attr_export |
1184 CX_EXPORT int cxTreeRemoveNode(CxTree *tree, void *node, cx_tree_relink_func relink_func); |
| 1377 int cxTreeRemoveNode( |
1185 |
| 1378 CxTree *tree, |
1186 /** |
| 1379 void *node, |
1187 * Removes a node and its subtree from the tree. |
| 1380 cx_tree_relink_func relink_func |
|
| 1381 ); |
|
| 1382 |
|
| 1383 /** |
|
| 1384 * Removes a node and it's subtree from the tree. |
|
| 1385 * |
1188 * |
| 1386 * If the node is not part of the tree, the behavior is undefined. |
1189 * If the node is not part of the tree, the behavior is undefined. |
| 1387 * |
1190 * |
| 1388 * @note The destructor function, if any, will @em not be invoked. That means |
1191 * @note The destructor function, if any, will @em not be invoked. That means |
| 1389 * you will need to free the removed subtree by yourself, eventually. |
1192 * you will need to free the removed subtree by yourself, eventually. |
| 1390 * |
1193 * |
| 1391 * @param tree the tree |
1194 * @param tree the tree |
| 1392 * @param node the node to remove |
1195 * @param node the node to remove |
| 1393 */ |
1196 */ |
| 1394 cx_attr_nonnull |
1197 cx_attr_nonnull |
| 1395 cx_attr_export |
1198 CX_EXPORT void cxTreeRemoveSubtree(CxTree *tree, void *node); |
| 1396 void cxTreeRemoveSubtree(CxTree *tree, void *node); |
|
| 1397 |
1199 |
| 1398 /** |
1200 /** |
| 1399 * Destroys a node and re-links its children to its former parent. |
1201 * Destroys a node and re-links its children to its former parent. |
| 1400 * |
1202 * |
| 1401 * If the node is not part of the tree, the behavior is undefined. |
1203 * If the node is not part of the tree, the behavior is undefined. |