Files @ b7792cb187f7
Branch filter:

Location: MD/arcos/include/tree.h

greta
Edited file README via RhodeCode
/** @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