Main Page | Data Structures | File List | Globals

include/tree.h

00001 /* A tree class.
00002  * By Richard W.M. Jones <rich@annexia.org>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the Free
00016  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  *
00018  * $Id: tree.h,v 1.1 2003/03/28 15:51:00 chappell Exp $
00019  */
00020 
00021 #ifndef TREE_H
00022 #define TREE_H
00023 
00024 #include <pool.h>
00025 #include <vector.h>
00026 
00027 struct tree
00028 {
00029   struct vector v;              /* Vector of subnodes. */
00030   size_t size;                  /* Size of the data. */
00031   char data[0];                 /* Opaque data (used by the application). */
00032 };
00033 
00034 typedef struct tree *tree;
00035 
00036 /* Function: new_tree - allocate a new tree, node or leaf
00037  * Function: _tree_new
00038  *
00039  * Allocate a new tree / node / leaf.
00040  *
00041  * A node in the tree is defined as a list of pointers to subnodes
00042  * and some data stored in the node itself. Because of the recursive
00043  * definition of trees, a tree is just a node, the special 'root'
00044  * node. A leaf is just a node which happens to have no subnodes. You
00045  * can add subnodes to a leaf later if you want.
00046  *
00047  * The @code{new_vector} macro is used to allocate a node in the
00048  * tree storing data @code{type} in the node. It just evaluates the
00049  * size of @code{type} and calls @code{_tree_new} which actually
00050  * allocates the node.
00051  *
00052  * Unless you are very careful with types, you should always make
00053  * sure that each node in your tree has the same @code{type}.
00054  *
00055  * Returns: The tree / node (of type @code{tree}).
00056  */
00057 #define new_tree(pool,type) _tree_new ((pool), sizeof (type))
00058 extern tree _tree_new (pool, size_t size);
00059 
00060 /* Function: tree_get_data - access the data stored in a node
00061  * Function: _tree_get_data
00062  * Function: tree_set_data
00063  * Function: _tree_set_data
00064  *
00065  * These functions allow you to access the data stored in the node.
00066  *
00067  * @code{tree_get_data} copies the data out of the node into the
00068  * local variable.
00069  *
00070  * @code{tree_set_data} copies the data from the local variable into
00071  * the node.
00072  */
00073 #define tree_get_data(t,obj) _tree_get_data ((t), &(obj))
00074 extern void _tree_get_data (tree t, void *ptr);
00075 #define tree_set_data(t,obj) _tree_set_data ((t), &(obj))
00076 extern void _tree_set_data (tree t, const void *ptr);
00077 
00078 /* Function: copy_tree - make a deep copy of a tree
00079  *
00080  * Make a deep copy of tree @code{t} into pool @code{pool}. This
00081  * copies all of the nodes and the data in those nodes recursively
00082  * Note however that if the data in a node is a / contains a pointer
00083  * then the pointed-to data will not be copied.
00084  *
00085  * Returns: The copied tree (of type @code{tree}).
00086  */
00087 extern tree copy_tree (pool, tree t);
00088 
00089 /* Function: tree_push_back - add or remove subnodes to or from a node
00090  * Function: tree_pop_back
00091  * Function: tree_push_front
00092  * Function: tree_pop_front
00093  *
00094  * The @code{*_push_*} functions push subnodes into nodes.
00095  *
00096  * The @code{*_pop_*} functions pop subnodes off nodes into local variables.
00097  *
00098  * The @code{*_front} functions push and pop subnodes off the front
00099  * of a node.
00100  *
00101  * The @code{*_back} functions push and pop subnodes
00102  * off the end of the node.
00103  *
00104  * Array indexes are checked. You cannot pop a node which has
00105  * no subnodes.
00106  */
00107 #define tree_push_back(t,subnode) (vector_push_back ((vector)(t), (subnode)))
00108 #define tree_pop_back(t,subnode) (vector_pop_back ((vector)(t), (subnode)))
00109 #define tree_push_front(t,subnode) (vector_push_front ((vector)(t), (subnode)))
00110 #define tree_pop_front(t,subnode) (vector_pop_front ((vector)(t), (subnode)))
00111 
00112 /* Function: tree_get_subnode - get a particular subnode of a node
00113  * Function: tree_get
00114  *
00115  * @code{tree_get_subnode} returns the @code{i}th subnode of a node. The
00116  * node is unaffected.
00117  *
00118  * @code{tree_get} is identical.
00119  */
00120 #define tree_get_subnode(t,i,subnode) tree_get((t), (i), (subnode))
00121 #define tree_get(t,i,subnode) (vector_get ((vector)(t), (i), (subnode)))
00122 
00123 /* Function: tree_insert - insert subnodes into a tree
00124  * Function: tree_insert_array
00125  *
00126  * @code{tree_insert} inserts a single subnode @code{subnode} before subnode
00127  * @code{i}. All other subnodes are moved up to make space.
00128  *
00129  * @code{tree_insert_array} inserts an array of @code{n} subnodes
00130  * starting at address @code{ptr} into the node before index
00131  * @code{i}.
00132  *
00133  * Array indexes are checked.
00134  */
00135 #define tree_insert(t,i,subnode) (vector_insert ((vector)(t), (i), (subnode)))
00136 #define tree_insert_array(t,i,ptr,n) (vector_insert_array ((vector)(t), (i), (ptr), (n)))
00137 
00138 /* Function: tree_replace - replace subnodes of a node
00139  * Function: tree_replace_array
00140  *
00141  * @code{tree_replace} replaces the single subnode at
00142  * @code{v[i]} with @code{subnode}.
00143  *
00144  * @code{tree_replace_array} replaces the @code{n} subnodes
00145  * in the node starting at index @code{i} with the @code{n}
00146  * subnodes from the array @code{ptr}.
00147  * 
00148  * Array indexes are checked.
00149  */
00150 #define tree_replace(t,i,subnode) (vector_replace ((vector)(t), (i), (subnode)))
00151 #define tree_replace_array(t,i,ptr,n) (vector_replace_array ((vector)(t), (i), (ptr), (n)))
00152 
00153 /* Function: tree_erase - erase subnodes of a node
00154  * Function: tree_erase_range
00155  * Function: tree_clear
00156  *
00157  * @code{tree_erase} removes the subnode index @code{i}, shuffling
00158  * the later subnodes down by one place to fill the space.
00159  *
00160  * @code{tree_erase_range} removes a range of subnodes @code{i}
00161  * to @code{j-1} (@code{i <= j}), shuffling later subnodes down
00162  * to fill the space.
00163  *
00164  * @code{tree_clear} removes all subnodes from the node, setting
00165  * its size to @code{0}, and effectively making the node into a leaf.
00166  *
00167  * Array indexes are checked.
00168  */
00169 #define tree_erase(t,i) (vector_erase ((vector)(t), (i)))
00170 #define tree_erase_range(t,i,j) (vector_erase_range ((vector)(t), (i), (j)))
00171 #define tree_clear(t) (vector_clear ((vector)(t)))
00172 
00173 /* Function: tree_size - return the number of subnodes of a node
00174  * Function: tree_nr_subnodes
00175  *
00176  * Return the size (ie. number of subnodes) in the node. The
00177  * @code{tree_nr_subnodes} macro is identical.
00178  */
00179 #define tree_size(t) (vector_size ((vector)(t)))
00180 #define tree_nr_subnodes(t) tree_size(t)
00181 
00182 /* Function: tree_swap - swap the order of two subnodes of a node
00183  *
00184  * Swap subnodes @code{i} and @code{j} of tree @code{t}.
00185  */
00186 #define tree_swap(t,i,j) (vector_swap ((vector)(t), (i), (j)))
00187 
00188 #endif /* TREE_H */

Generated on Fri Feb 20 15:17:48 2004 for PPR Libraries by doxygen 1.3.5