diff options
author | Lionel Landwerlin <[email protected]> | 2018-07-29 14:13:25 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2018-08-22 17:49:36 +0100 |
commit | 14a1cb37ebd3adbceb56f99f4727e45309b75ec2 (patch) | |
tree | 2dffb0f566eece202ed5920df907fced4f803736 | |
parent | 4616639b49b4bbc91e503c1c27632dccc1c2b5be (diff) |
util: rb_tree: add safe iterators
v2: Add helper to make iterators more readable (Rafael)
Fix rev iterator bug (Rafael)
Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Rafael Antognolli <[email protected]>
-rw-r--r-- | src/util/rb_tree.h | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/util/rb_tree.h b/src/util/rb_tree.h index c77e9255ea2..1e8aeb4a7b2 100644 --- a/src/util/rb_tree.h +++ b/src/util/rb_tree.h @@ -227,6 +227,30 @@ struct rb_node *rb_node_next(struct rb_node *node); /** Get the next previous (to the left) in the tree or NULL */ struct rb_node *rb_node_prev(struct rb_node *node); +/** Get the next node if available or the same node again. + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_node_next_if_available(type, node, field) \ + (&node->field != NULL) ? rb_node_data(type, rb_node_next(&node->field), field) : node + +/** Get the previous node if available or the same node again. + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_node_prev_if_available(type, node, field) \ + (&node->field != NULL) ? rb_node_data(type, rb_node_prev(&node->field), field) : node + /** Iterate over the nodes in the tree * * \param type The type of the containing data structure @@ -243,6 +267,23 @@ struct rb_node *rb_node_prev(struct rb_node *node); &node->field != NULL; \ node = rb_node_data(type, rb_node_next(&node->field), field)) +/** Iterate over the nodes in the tree, allowing the current node to be freed + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param T The red-black tree + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_foreach_safe(type, node, T, field) \ + for (type *node = rb_node_data(type, rb_tree_first(T), field), \ + *__next = rb_tree_node_next_if_available(type, node, field); \ + &node->field != NULL; \ + node = __next, __next = rb_tree_node_next_if_available(type, node, field)) + /** Iterate over the nodes in the tree in reverse * * \param type The type of the containing data structure @@ -259,6 +300,23 @@ struct rb_node *rb_node_prev(struct rb_node *node); &node->field != NULL; \ node = rb_node_data(type, rb_node_prev(&node->field), field)) +/** Iterate over the nodes in the tree in reverse, allowing the current node to be freed + * + * \param type The type of the containing data structure + * + * \param node The variable name for current node in the iteration; + * this will be declared as a pointer to \p type + * + * \param T The red-black tree + * + * \param field The rb_node field in containing data structure + */ +#define rb_tree_foreach_rev_safe(type, node, T, field) \ + for (type *node = rb_node_data(type, rb_tree_last(T), field), \ + *__prev = rb_tree_node_prev_if_available(type, node, field); \ + &node->field != NULL; \ + node = __prev, __prev = rb_tree_node_prev_if_available(type, node, field)) + /** Validate a red-black tree * * This function walks the tree and validates that this is a valid red- |