X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Futil%2Frb_tree.h;h=8b354c091f532873fbf2a225e1e293672fa4d367;hp=e8750b32d0e91676c57d9410ba3bc0e5ad5b0a04;hb=HEAD;hpb=2602ea89d55cd1004bbec46c8ff1ac1ad1510940 diff --git a/src/util/rb_tree.h b/src/util/rb_tree.h index e8750b32d0e..8b354c091f5 100644 --- a/src/util/rb_tree.h +++ b/src/util/rb_tree.h @@ -55,7 +55,7 @@ struct rb_node { static inline struct rb_node * rb_node_parent(struct rb_node *n) { - return (struct rb_node *)(n->parent & ~1ull); + return (struct rb_node *)(n->parent & ~(uintptr_t)1); } /** A red-black tree @@ -127,7 +127,7 @@ rb_tree_insert(struct rb_tree *T, struct rb_node *node, bool left = false; while (x != NULL) { y = x; - left = cmp(node, x) < 0; + left = cmp(x, node) < 0; if (left) x = x->left; else @@ -167,9 +167,9 @@ rb_tree_search(struct rb_tree *T, const void *key, while (x != NULL) { int c = cmp(x, key); if (c < 0) - x = x->right; - else if (c > 0) x = x->left; + else if (c > 0) + x = x->right; else return x; } @@ -205,9 +205,9 @@ rb_tree_search_sloppy(struct rb_tree *T, const void *key, y = x; int c = cmp(x, key); if (c < 0) - x = x->right; - else if (c > 0) x = x->left; + else if (c > 0) + x = x->right; else return x; } @@ -227,6 +227,9 @@ 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); +#define rb_node_next_or_null(n) ((n) == NULL ? NULL : rb_node_next(n)) +#define rb_node_prev_or_null(n) ((n) == NULL ? NULL : rb_node_prev(n)) + /** Iterate over the nodes in the tree * * \param type The type of the containing data structure @@ -238,10 +241,31 @@ struct rb_node *rb_node_prev(struct rb_node *node); * * \param field The rb_node field in containing data structure */ -#define rb_tree_foreach(type, node, T, field) \ - for (type *node = rb_node_data(type, rb_tree_first(T), field); \ - &node->field != NULL; \ - node = rb_node_data(type, rb_node_next(&node->field), field)) +#define rb_tree_foreach(type, iter, T, field) \ + for (type *iter, *__node = (type *)rb_tree_first(T); \ + __node != NULL && \ + (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ + __node = (type *)rb_node_next((struct rb_node *)__node)) + +/** 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, iter, T, field) \ + for (type *iter, \ + *__node = (type *)rb_tree_first(T), \ + *__next = (type *)rb_node_next_or_null((struct rb_node *)__node); \ + __node != NULL && \ + (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ + __node = __next, \ + __next = (type *)rb_node_next_or_null((struct rb_node *)__node)) /** Iterate over the nodes in the tree in reverse * @@ -254,10 +278,31 @@ struct rb_node *rb_node_prev(struct rb_node *node); * * \param field The rb_node field in containing data structure */ -#define rb_tree_foreach_rev(type, node, T, field) \ - for (type *node = rb_node_data(type, rb_tree_last(T), field); \ - &node->field != NULL; \ - node = rb_node_data(type, rb_node_prev(&node->field), field)) +#define rb_tree_foreach_rev(type, iter, T, field) \ + for (type *iter, *__node = (type *)rb_tree_last(T); \ + __node != NULL && \ + (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ + __node = (type *)rb_node_prev((struct rb_node *)__node)) + +/** 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, iter, T, field) \ + for (type *iter, \ + *__node = (type *)rb_tree_last(T), \ + *__prev = (type *)rb_node_prev_or_null((struct rb_node *)__node); \ + __node != NULL && \ + (iter = rb_node_data(type, (struct rb_node *)__node, field), true); \ + __node = __prev, \ + __prev = (type *)rb_node_prev_or_null((struct rb_node *)__node)) /** Validate a red-black tree *