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 */