Main Page | Data Structures | File List | Globals

include/vector.h

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

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