00001 /* A vector 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: vector.h,v 1.2 2004/01/26 17:54:53 chappell Exp $ 00019 */ 00020 00021 #ifndef VECTOR_H 00022 #define VECTOR_H 00023 00024 #include <pool.h> 00025 00026 struct vector 00027 { 00028 pool pool; 00029 size_t size; 00030 void *data; 00031 int used, allocated; 00032 }; 00033 00034 typedef struct vector *vector; 00035 00036 /* Function: new_vector - allocate a new vector 00037 * Function: _vector_new 00038 * 00039 * Allocate a new vector in @code{pool} of type @code{type}. The 00040 * first form is just a macro which evaluates the size of @code{type}. 00041 * The second form creates a vector with elements of the given 00042 * @code{size} directly. 00043 */ 00044 #define new_vector(pool,type) _vector_new ((pool), sizeof (type)) 00045 extern vector _vector_new (pool, size_t size); 00046 00047 /* Function: copy_vector - copy a vector 00048 * Function: new_subvector 00049 * 00050 * Copy a vector @code{v} into pool @code{pool}. If the vector 00051 * contains pointers, then this function will not copy the pointed-to 00052 * data as well: you will need to copy this yourself if appropriate. 00053 * 00054 * @code{new_subvector} creates a copy of part of an existing vector. 00055 * The new vector contains the @code{j-i} elements of the old vector 00056 * starting at element number @code{i} and finishing at element number 00057 * @code{j-1}. 00058 */ 00059 extern vector copy_vector (pool, vector v); 00060 extern vector new_subvector (pool, vector v, int i, int j); 00061 00062 /* Function: vector_push_back - push and pop objects into and out of vectors 00063 * Function: _vector_push_back 00064 * Function: vector_pop_back 00065 * Function: _vector_pop_back 00066 * Function: vector_push_front 00067 * Function: _vector_push_front 00068 * Function: vector_pop_front 00069 * Function: _vector_pop_front 00070 * 00071 * The @code{*_push_*} functions push objects onto vectors. 00072 * 00073 * The @code{*_pop_*} functions pop objects off vectors into local variables. 00074 * 00075 * The @code{*_front} functions push and pop objects off the front 00076 * of a vector. This type of operation is not very efficient, because 00077 * it involves moving all other elements of the vector up or down 00078 * by one place. 00079 * 00080 * The @code{*_back} functions push and pop elements 00081 * off the end of the vector, which is efficient. 00082 * 00083 * Each function has two forms: a macro version and an underlying 00084 * function. 00085 * 00086 * Array indexes are checked. You cannot pop an empty vector. If 00087 * @code{ptr} is @code{NULL} then the popped object is discarded. 00088 */ 00089 #define vector_push_back(v,obj) _vector_push_back((v),&(obj)) 00090 extern void _vector_push_back (vector, const void *ptr); 00091 #define vector_pop_back(v,obj) _vector_pop_back((v),&(obj)) 00092 extern void _vector_pop_back (vector, void *ptr); 00093 #define vector_push_front(v,obj) _vector_push_front((v),&(obj)) 00094 extern void _vector_push_front (vector, const void *ptr); 00095 #define vector_pop_front(v,obj) _vector_pop_front((v),&(obj)) 00096 extern void _vector_pop_front (vector, void *ptr); 00097 00098 /* Function: vector_push_back_vector - push list of objects on to vector 00099 * Function: vector_push_front_vector 00100 * 00101 * @code{vector_push_back_vector} appends the elements of vector 00102 * @code{w} on to the end of vector @code{v}. 00103 * 00104 * @code{vector_push_front_vector} prepends the elements of vector 00105 * @code{w} on to the front of vector @code{v}. 00106 * 00107 * In both cases, vector @code{w} is left unchanged. 00108 * 00109 * See also: @ref{vector_push_back(3)}, @ref{vector_push_front(3)}. 00110 */ 00111 extern void vector_push_back_vector (vector v, const vector w); 00112 extern void vector_push_front_vector (vector v, const vector w); 00113 00114 /* Function: vector_get - array-style indexing for vectors 00115 * Function: _vector_get 00116 * Function: vector_get_ptr 00117 * Function: _vector_get_ptr 00118 * 00119 * @code{vector_get} copies the element at index @code{v[i]} into 00120 * local variable @code{obj}. The vector is unaffected. 00121 * 00122 * @code{_vector_get} copies the element into the memory pointed 00123 * to by @code{ptr}. If @code{ptr} is @code{NULL} then the effect 00124 * is simply to check that element @code{v[i]} exists. 00125 * 00126 * @code{vector_get_ptr} and @code{_vector_get_ptr} are used to 00127 * get a pointer to an element in the vector. This pointer actually 00128 * points to the vector's internal data array. It is only valid 00129 * as long as the user does not cause the internal data array to 00130 * be reallocated or moved - typically this can happen when the 00131 * user performs some operation which inserts more elements into 00132 * the array. 00133 * 00134 * Array indexes are checked. An attempt to access an out-of-bounds 00135 * element will result in a call to @ref{abort(3)}. 00136 */ 00137 #define vector_get(v,i,obj) _vector_get((v),(i),&(obj)) 00138 extern void _vector_get (vector, int i, void *ptr); 00139 #define vector_get_ptr(v,i,ptr) (ptr) =((typeof (ptr))_vector_get_ptr((v),(i))) 00140 extern const void *_vector_get_ptr (vector, int i); 00141 00142 /* Function: vector_insert - insert elements into a vector 00143 * Function: _vector_insert 00144 * Function: vector_insert_array 00145 * 00146 * @code{vector_insert} inserts a single object @code{obj} before element 00147 * @code{i}. All other elements are moved up to make space. 00148 * 00149 * @code{vector_insert_array} inserts an array of @code{n} objects 00150 * starting at address @code{ptr} into the vector before index 00151 * @code{i}. 00152 * 00153 * Array indexes are checked. 00154 */ 00155 #define vector_insert(v,i,obj) _vector_insert((v),(i),&(obj)) 00156 extern void _vector_insert (vector, int i, const void *ptr); 00157 extern void vector_insert_array (vector v, int i, const void *ptr, int n); 00158 00159 /* Function: vector_replace - replace elements of a vector 00160 * Function: _vector_replace 00161 * Function: vector_replace_array 00162 * 00163 * @code{vector_replace} replaces the single element at 00164 * @code{v[i]} with object @code{obj}. 00165 * 00166 * @code{vector_replace_array} replaces the @code{n} elements 00167 * in the vector starting at index @code{i} with the @code{n} 00168 * elements from the array @code{ptr}. 00169 * 00170 * Array indexes are checked. 00171 */ 00172 #define vector_replace(v,i,obj) _vector_replace((v),(i),&(obj)) 00173 extern void _vector_replace (vector, int i, const void *ptr); 00174 extern void vector_replace_array (vector v, int i, const void *ptr, int n); 00175 00176 /* Function: vector_erase - erase elements of a vector 00177 * Function: vector_erase_range 00178 * Function: vector_clear 00179 * 00180 * @code{vector_erase} removes the element @code{v[i]}, shuffling 00181 * the later elements down by one place to fill the space. 00182 * 00183 * @code{vector_erase_range} removes a range of elements @code{v[i]} 00184 * to @code{v[j-1]} (@code{i <= j}), shuffling later elements down 00185 * to fill the space. 00186 * 00187 * @code{vector_clear} removes all elements from the vector, setting 00188 * its size to @code{0}. 00189 * 00190 * Array indexes are checked. 00191 */ 00192 extern void vector_erase (vector v, int i); 00193 extern void vector_erase_range (vector v, int i, int j); 00194 extern void vector_clear (vector v); 00195 00196 /* Function: vector_fill - fill a vector with identical elements 00197 * Function: _vector_fill 00198 * 00199 * @code{vector_fill} appends @code{n} identical copies of 00200 * @code{obj} to the vector. It is equivalent to calling 00201 * @ref{vector_push_back(3)} in a loop @code{n} times. 00202 */ 00203 #define vector_fill(v,obj,n) _vector_fill((v),&(obj),(n)) 00204 extern void _vector_fill (vector, const void *ptr, int n); 00205 00206 /* Function: vector_size - return the size of a vector 00207 * 00208 * Return the size (ie. number of elements) in the vector. 00209 */ 00210 #define vector_size(v) ((v)->used) 00211 00212 /* Function: vector_allocated - return the space allocated to a vector 00213 * 00214 * Return the amount of space which has been allocated for storing 00215 * elements of the vector. This is different from the number of 00216 * elements actually stored by the vector (see @ref{vector_size(3)}) 00217 * and also different from the size of each element in bytes 00218 * (see @ref{vector_element_size(3)}). 00219 */ 00220 #define vector_allocated(v) ((v)->allocated) 00221 00222 /* Function: vector_element_size - return the size of each element of a vector 00223 * 00224 * Return the size in bytes of each element in vector. 00225 */ 00226 #define vector_element_size(v) ((v)->size) 00227 00228 /* Function: vector_reallocate - change allocation for a vector 00229 * 00230 * Increase the amount of space allocated to a vector. See also 00231 * @ref{vector_allocated(3)}. This function can be used to avoid 00232 * the vector itself making too many calls to the underlying 00233 * @ref{c2_prealloc(3)}, particularly if you know in advance exactly 00234 * how many elements the vector will contain. 00235 */ 00236 extern void vector_reallocate (vector v, int n); 00237 00238 /* Function: vector_grep - produce a new vector containing elements of the old vector which match a boolean function 00239 * 00240 * This macro calls @code{match_fn(&t)} for each element @code{t} of 00241 * vector @code{v}. It constructs and returns a new vector containing 00242 * all those elements where the function returns true. 00243 */ 00244 extern vector vector_grep (pool, vector v, int (*match_fn) (const void *)); 00245 00246 /* Function: vector_grep_pool - produce a new vector containing elements of the old vector which match a boolean function 00247 * 00248 * This macro calls @code{match_fn(pool, &t)} for each element @code{t} of 00249 * vector @code{v}. It constructs and returns a new vector containing 00250 * all those elements where the function returns true. 00251 */ 00252 extern vector vector_grep_pool (pool, vector v, int (*match_fn) (pool, const void *)); 00253 00254 /* Function: vector_map - apply function to each element of a vector 00255 * Function: _vector_map 00256 * 00257 * Call @code{map_fn(&t, &r)} for each element @code{t} of vector @code{v}. 00258 * The result (@code{r}) should have type @code{result_type} 00259 * and these are concatenated to form a new vector which is returned. 00260 */ 00261 #define vector_map(pool,v,map_fn,result_type) _vector_map ((pool), (v), (map_fn), sizeof (result_type)) 00262 extern vector _vector_map (pool, vector v, void (*map_fn) (const void *, void *), size_t result_size); 00263 00264 /* Function: vector_map_pool - apply function to each element of a vector 00265 * Function: _vector_map_pool 00266 * 00267 * Call @code{map_fn(pool, &t, &r)} for each element @code{t} of vector 00268 * @code{v}. The result (@code{r}) should have type @code{result_type} 00269 * and these are concatenated to form a new vector which is returned. 00270 */ 00271 #define vector_map_pool(pool,v,map_fn,result_type) _vector_map_pool ((pool), (v), (map_fn), sizeof (result_type)) 00272 extern vector _vector_map_pool (pool, vector v, void (*map_fn_pool) (pool, const void *, void *), size_t result_size); 00273 00274 /* Function: vector_sort - sort a vector in-place 00275 * Function: _vector_sort 00276 * 00277 * Sort a vector in-place, comparing elements using @code{compare_fn}. 00278 */ 00279 #define vector_sort(v,compare_fn) _vector_sort ((v), (int (*)(const void *,const void *)) (compare_fn)) 00280 extern void _vector_sort (vector v, int (*compare_fn) (const void *, const void *)); 00281 00282 /* Function: vector_compare - compare two vectors 00283 * Function: _vector_compare 00284 * 00285 * Compare two vectors. This returns 0 if the two vectors are 00286 * identical. It returns > 0 if @code{v1} > @code{v2}. This 00287 * returns < 0 if @code{v1} < @code{v2}. 00288 */ 00289 #define vector_compare(v1,v2,compare_fn) _vector_compare ((v1), (v2), (int (*)(const void *,const void *)) (compare_fn)) 00290 extern int _vector_compare (vector, vector, int (*compare_fn) (const void *, const void *)); 00291 00292 /* Function: vector_reverse - reverse the elements of a vector in-place 00293 * 00294 * Reverse the elements of a vector in-place. 00295 */ 00296 extern void vector_reverse (vector v); 00297 00298 /* Function: vector_swap - swap two elements of a vector 00299 * 00300 * Swap elements @code{i} and @code{j} of vector @code{v}. 00301 */ 00302 extern void vector_swap (vector v, int i, int j); 00303 00304 #endif /* VECTOR_H */