/** @file tree.h * @brief Structures and function definitions to handle a tree structure. */ /*!< These fields are included as the first fields of any structure that * we want to convert into leaves of a tree. For people familiar with object * orientation, this is equivalent to defining a class @a leaf and make * other structures derive from it. * The idea here is that we can share the code for the management of * the tree structure of the grids both for the poisson and the cdr parts. */ #ifndef _TREE_H_ #define LEAF_FIELDS(X) \ X *parent; \ X *next; \ X *first_child; \ int level; \ #define LEAF_ROOT 0 /*!< Iterate over all childs of a node. Simply write * * leaf_t leaf; * * iter_childs (node, leaf) { * do_something (leaf); * } */ #define iter_childs(ROOT, LEAF) for (LEAF = ROOT->first_child; LEAF; \ LEAF = LEAF->next) /*!< iter_child may not work if in the loop body we make free(LEAF) * (though this will go unnoticed most of the time). So when * freeing grids, the following macro has to be used instead: */ #define free_childs(ROOT, LEAF, FREE) do { \ grid_t *next__; \ for (LEAF = ROOT->first_child; LEAF; LEAF = (typeof(LEAF)) next__) { \ next__ = ((grid_t *) LEAF)->next; \ FREE (LEAF); \ } \ } while(0) /*!< This is used to put into a leaf any set of values. */ #define set_leaf(LEAF, PARENT, NEXT, FIRST_CHILD, LEVEL) do { \ LEAF->parent = PARENT; \ LEAF->next = NEXT; \ LEAF->first_child = FIRST_CHILD; \ LEAF->level = LEVEL; \ } while(0) #define init_leaf(LEAF) set_leaf(LEAF, NULL, NULL, NULL, -1) /*!< Sometimes we have to remove all of a leaf's children. After freeing * them with free_childs, call this one. */ #define set_childless(LEAF) (LEAF)->first_child = NULL /*!< Adds a child to a given leaf. */ #define add_child(PARENT, CHILD) do { \ set_leaf(CHILD, PARENT, PARENT->first_child, CHILD->first_child, \ PARENT->level + 1); \ PARENT->first_child = CHILD; \ } while(0) /*!< Given a function name, creates a function with the same name plus `_r' * that (tail- in the second case) recursively calls the first. * Can only be applied on functions that receive as single parameter a * grid of type `type'. */ #define mk_recursive(func, type) \ void func ## _r (type *grid_) \ { \ type *child_; \ func (grid_); \ iter_childs (grid_, child_) { \ func ## _r (child_); \ } \ } #define mk_tail_recursive(func, type) \ void func ## _r (type *grid_) \ { \ type *child_; \ iter_childs (grid_, child_) { \ func ## _r (child_); \ } \ func (grid_); \ } #define _TREE_H_ #endif