00001 /* Part of the culibs project, <http://www.eideticdew.org/culibs/>. 00002 * Copyright (C) 2006--2009 Petter Urkedal <urkedal@nbi.dk> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program 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 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef CUCON_ARRAY_H 00019 #define CUCON_ARRAY_H 00020 00021 #include <cucon/fwd.h> 00022 #include <stdint.h> 00023 00024 CU_BEGIN_DECLARATIONS 00025 /** \defgroup cucon_array_h cucon/array.h: Generic Array 00026 ** @{ \ingroup cucon_linear_mod 00027 ** 00028 ** This header provides generic arrays of inlined elements. All sizes and 00029 ** indices are measured in bytes, and must be scaled with the element size. 00030 ** 00031 ** \see \ref cucon_bitarray_h 00032 ** \see \ref cucon_parray_h 00033 **/ 00034 00035 struct cucon_array 00036 { 00037 size_t size; 00038 size_t cap; 00039 char *carr; 00040 }; 00041 00042 /** Construct an array of initially \a size bytes. If true is passed for \a 00043 ** is_atomic, then atomic allocation will be used for the array data. */ 00044 void cucon_array_init(cucon_array_t arr, cu_bool_t is_atomic, size_t size); 00045 00046 /** Returns an array of initially \a size bytes. If true is passed for \a 00047 ** is_atomic, then atomic allocation will be used for the array data. */ 00048 cucon_array_t cucon_array_new(cu_bool_t is_atomic, size_t size); 00049 00050 /** Swap the values of \a arr0 and \a arr1. */ 00051 void cucon_array_swap(cucon_array_t arr0, cucon_array_t arr1); 00052 00053 /** The size of \a arr. */ 00054 CU_SINLINE size_t 00055 cucon_array_size(cucon_array_t arr) { return arr->size; } 00056 00057 /** Pointer to entry at \a index in \a arr. 00058 ** \pre \a arr is least \a index + 1 long. */ 00059 CU_SINLINE void * 00060 cucon_array_ref_at(cucon_array_t arr, size_t index) 00061 { return arr->carr + index; } 00062 00063 /** Returns a plain memory fragment with the data stored in the array and 00064 ** invalidates \a arr. The memory fragment may be reallocated and copied if 00065 ** the capacity of \a arr is larger than its size. */ 00066 void *cucon_array_detach(cucon_array_t arr); 00067 00068 /** Resize \a arr to \a size, changing the capacity in geometric progression if 00069 ** necessary. */ 00070 void cucon_array_resize_gp(cucon_array_t arr, size_t size); 00071 00072 /** Resize \a arr to \a size, increasing capacity geometrically if necessary. 00073 ** This call never decrease the capacity. */ 00074 void cucon_array_resize_gpmax(cucon_array_t arr, size_t size); 00075 00076 /** Resize \a arr to \a size, changing the capacity to match the size. If you 00077 ** are growing an array, \ref cucon_array_resize_gp gives better amortised 00078 ** time-complexity. */ 00079 void cucon_array_resize_exact(cucon_array_t arr, size_t size); 00080 00081 /** Resize \a arr to \a size, increasing capacity to match the size if 00082 ** necesary. This call never decrease the capacity. If you are growing an 00083 ** array, \ref cucon_array_resize_gpmax gives better amortised time-complexity. 00084 **/ 00085 void cucon_array_resize_exactmax(cucon_array_t arr, size_t size); 00086 00087 /** Extend \a arr with \a size entries, and return a pointer to the first one. 00088 ** The array capacity is increased geometrically. */ 00089 CU_SINLINE void * 00090 cucon_array_extend_gp(cucon_array_t arr, size_t size) 00091 { 00092 size_t old_size = arr->size; 00093 cucon_array_resize_gpmax(arr, old_size + size); 00094 return arr->carr + old_size; 00095 } 00096 00097 /** Extend \a arr with \a size entries, and return a pointer to the first one. 00098 ** The array capacity is increased to exactly match \a size if needed. If you 00099 ** are calling this many times, use \ref cucon_array_extend_gp for better time 00100 ** complexity. */ 00101 CU_SINLINE void * 00102 cucon_array_extend_exact(cucon_array_t arr, size_t size) 00103 { 00104 size_t old_size = arr->size; 00105 cucon_array_resize_exactmax(arr, old_size + size); 00106 return arr->carr + old_size; 00107 } 00108 00109 /** A pointer to the start of the internal array. If converted to an 00110 ** appropriate pointer type, it can be used as an iterator. 00111 ** \see cucon_array_end */ 00112 CU_SINLINE void *cucon_array_begin(cucon_array_t arr) 00113 { return arr->carr; } 00114 00115 /** A pointer past the end of the internal array. 00116 ** \see cucon_array_begin */ 00117 CU_SINLINE void *cucon_array_end(cucon_array_t arr) 00118 { return arr->carr + arr->size; } 00119 00120 /** @} */ 00121 CU_END_DECLARATIONS 00122 00123 #endif