#ifndef	V_LLTREE_H
#define	V_LLTREE_H

/*
 * Template for N-Way tree implementation with linux linked lists.
 */

/* this macro must be issued somewhere in object definition */
#define	DEFINE_TREE_LINK(container_class) \
    container_class *parent; \
	struct list_head siblings, children; \
    DEFINE_TREE_DEPTH

/* ... this - after allocation of 'self' (parent _can_ be NULL) */
#define	LINK_TREE_NODE(self,parent_of_self) \
	(self)->parent = (parent_of_self); \
	INIT_LIST_HEAD(&(self)->siblings); \
	INIT_LIST_HEAD(&(self)->children); \
	SET_TREE_DEPTH(self,(self)->parent) \
	if((self)->parent) \
		list_add(&(self)->siblings,&(self)->parent->children);

/* ... this - before deallocation of 'self' */
#define	UNLINK_TREE_NODE(self) \
	list_del(&(self)->siblings);

/* this is the declatarion of variable required by next macro */
#define	TREE_ITERATOR \
	struct list_head *tree_iterator

/* macro for loop though children of 'root' */
#define	TREE_FOR_EACH_CHILD(root) \
	list_for_each(tree_iterator,&(root)->children)

#define	TREE_FOR_EACH_CHILD_BACKWARD(root) \
	list_for_each_backward(tree_iterator,&(root)->children)

/* macro for access child of type 'container_class' from within loop */
#define	TREE_NODE(container_class) \
	list_entry(tree_iterator,container_class,siblings)

#ifdef	DEBUG_TREE_DEPTH

#define	DEFINE_TREE_DEPTH int depth;

#define	SET_TREE_DEPTH(self,parent) \
	if(parent) \
		(self)->depth = (parent)->depth + 1; \
	else \
		(self)->depth = 0;

#define	TREE_DEPTH(self)	(self)->depth

#else	/* !DEBUG_TREE_DEPTH */

#define	DEFINE_TREE_DEPTH
#define	SET_TREE_DEPTH(self,parent)
#define	TREE_DEPTH(self)	0

#endif	/* !DEBUG_TREE_DEPTH */

/*
 * Sample 'int' N-way tree implementation:

typedef struct tnode_s
{
	int data;
	DEFINE_TREE_LINK(struct tnode_s)
} tnode_t, *tnode_p;

tnode_p add_node(int data,tnode_p parent)
{
	tnode_p self = (tnode_p)memAllocZ(sizeof(*self));
	LINK_TREE_NODE(self,parent);
	self->data = data;
	return self;
}

void traverse_from_root(tnode_p root,void (*proc)(tnode_p))
{
	TREE_ITERATOR;
   	proc(root);
   	TREE_FOR_EACH_CHILD(root)
	{
    	tnode_p ptr = TREE_NODE(tnode_t);
    	traverse_from_root(ptr,proc);
    }
}

void traverse_from_children(tnode_p root,void (*proc)(tnode_p))
{
	TREE_ITERATOR;
   	TREE_FOR_EACH_CHILD(root)
	{
    	tnode_p ptr = TREE_NODE(tnode_t);
    	traverse_from_children(ptr,proc);
    }
   	proc(root);
}

void remove_subtree(tnode_p subtree_root)
{
	TREE_ITERATOR;
   	TREE_FOR_EACH_CHILD(subtree_root)
    	remove_subtree(TREE_NODE(tnode_t));
   	UNLINK_TREE_NODE(subtree_root);
   	memFree(subtree_root);
}

*/

#endif	/* V_LLTREE_H */
