Commit | Line | Data |
---|---|---|
a7868768 BA |
1 | /** |
2 | * @file Vector.h | |
3 | */ | |
4 | ||
5 | #ifndef CGDS_VECTOR_H | |
6 | #define CGDS_VECTOR_H | |
7 | ||
8 | #include <stdlib.h> | |
9 | #include <string.h> | |
10 | #include "cgds/safe_alloc.h" | |
11 | #include "cgds/types.h" | |
12 | ||
13 | //************* | |
14 | // Vector logic | |
15 | //************* | |
16 | ||
17 | /** | |
18 | * @brief Generic resizable array. | |
19 | */ | |
20 | typedef struct Vector { | |
e45132ac BA |
21 | void** datas; ///< Data array of fixed length (reallocated if needed). |
22 | size_t dataSize; ///< Size in bytes of a vector element. | |
23 | UInt size; ///< Count elements in the vector. | |
24 | UInt capacity; ///< Current maximal capacity; always larger than size. | |
a7868768 BA |
25 | } Vector; |
26 | ||
27 | /** | |
28 | * @brief Initialize an empty vector. | |
29 | */ | |
30 | void _vector_init( | |
e45132ac BA |
31 | Vector* vector, ///< "this" pointer. |
32 | size_t dataSize ///< Size in bytes of a vector element. | |
a7868768 BA |
33 | ); |
34 | ||
35 | /** | |
36 | * @brief Return an allocated and initialized vector. | |
37 | */ | |
38 | Vector* _vector_new( | |
e45132ac | 39 | size_t dataSize ///< Size in bytes of a vector element. |
a7868768 BA |
40 | ); |
41 | ||
42 | /** | |
43 | * @brief Return an allocated and initialized vector. | |
44 | * @param type Type of a vector element (int, char*, ...). | |
1ff641f9 | 45 | * |
a7868768 BA |
46 | * Usage: Vector* vector_new(<Type> type) |
47 | */ | |
48 | #define vector_new(type) \ | |
e45132ac BA |
49 | { \ |
50 | _vector_new(sizeof(type)); \ | |
51 | } | |
a7868768 BA |
52 | |
53 | /** | |
1ff641f9 | 54 | * @brief Copy constructor (shallow copy, ok for basic types). |
a7868768 BA |
55 | */ |
56 | Vector* vector_copy( | |
e45132ac | 57 | Vector* vector ///< "this" pointer. |
a7868768 BA |
58 | ); |
59 | ||
60 | /** | |
61 | * @brief Check if the vector is empty. | |
62 | */ | |
1ff641f9 | 63 | bool vector_empty( |
e45132ac | 64 | Vector* vector ///< "this" pointer. |
a7868768 BA |
65 | ); |
66 | ||
67 | /** | |
68 | * @brief Return current size. | |
69 | */ | |
70 | UInt vector_size( | |
e45132ac | 71 | Vector* vector ///< "this" pointer. |
a7868768 BA |
72 | ); |
73 | ||
74 | /** | |
75 | * @brief Reallocate internal array. | |
76 | */ | |
77 | void _vector_realloc( | |
e45132ac BA |
78 | Vector* vector, ///< "this" pointer. |
79 | UInt newCapacity ///< New capacity of the vector (in number of elements). | |
a7868768 BA |
80 | ); |
81 | ||
82 | /** | |
83 | * @brief Add data at the end. | |
84 | */ | |
85 | void _vector_push( | |
e45132ac BA |
86 | Vector* vector, ///< "this" pointer. |
87 | void* data ///< Data to be added. | |
a7868768 BA |
88 | ); |
89 | ||
90 | /** | |
91 | * @brief Add data at the end. | |
92 | * @param vector "this" pointer. | |
93 | * @param data Data to be added. | |
1ff641f9 | 94 | * |
a7868768 BA |
95 | * Usage: void vector_push(Vector* vector, void data) |
96 | */ | |
97 | #define vector_push(vector, data) \ | |
98 | { \ | |
e45132ac BA |
99 | typeof((data)) tmp = data; \ |
100 | _vector_push(vector,&tmp); \ | |
a7868768 BA |
101 | } |
102 | ||
103 | /** | |
104 | * @brief Remove the last pushed element. | |
105 | */ | |
106 | void vector_pop( | |
e45132ac | 107 | Vector* vector ///< "this" pointer. |
a7868768 BA |
108 | ); |
109 | ||
110 | /** | |
111 | * @brief Get the element at given index. | |
112 | */ | |
113 | void* _vector_get( | |
e45132ac BA |
114 | Vector* vector, ///< "this" pointer. |
115 | UInt index ///< Index of the element to retrieve. | |
a7868768 BA |
116 | ); |
117 | ||
118 | /** | |
119 | * @brief Get the element at given index. | |
120 | * @param vector "this" pointer. | |
121 | * @param index Index of the element to retrieve. | |
122 | * @param data 'out' variable to contain the result. | |
1ff641f9 | 123 | * |
a7868768 BA |
124 | * Usage: void vector_get(Vector* vector, size_t index, void data) |
125 | */ | |
126 | #define vector_get(vector, index, data) \ | |
127 | { \ | |
e45132ac BA |
128 | void* pData = _vector_get(vector,index); \ |
129 | data = *((typeof(&data))pData); \ | |
a7868768 BA |
130 | } |
131 | ||
132 | /** | |
133 | * @brief Set the element at given index. | |
134 | */ | |
135 | void _vector_set( | |
e45132ac BA |
136 | Vector* vector, ///< "this" pointer. |
137 | UInt index, ///< Index of the element to be modified. | |
138 | void* data ///< Pointer to new data at given index. | |
a7868768 BA |
139 | ); |
140 | ||
141 | /** | |
142 | * @brief Set the element at given index. | |
143 | * @param vector "this" pointer. | |
144 | * @param index Index of the element to be modified. | |
145 | * @param data New data at given index. | |
1ff641f9 | 146 | * |
a7868768 BA |
147 | * Usage: void vector_set(Vector* vector, size_t index, void data) |
148 | */ | |
149 | #define vector_set(vector, index, data) \ | |
150 | { \ | |
e45132ac BA |
151 | typeof((data)) tmp = data; \ |
152 | _vector_set(vector,index,&tmp); \ | |
a7868768 BA |
153 | } |
154 | ||
155 | /** | |
156 | * @brief Clear the entire vector. | |
157 | */ | |
158 | void vector_clear( | |
e45132ac | 159 | Vector* vector ///< "this" pointer. |
a7868768 BA |
160 | ); |
161 | ||
162 | /** | |
163 | * @brief Destroy the vector: clear it, and free 'vector' pointer. | |
164 | */ | |
165 | void vector_destroy( | |
e45132ac | 166 | Vector* vector ///< "this" pointer. |
a7868768 BA |
167 | ); |
168 | ||
169 | //*************** | |
170 | // Iterator logic | |
171 | //*************** | |
172 | ||
173 | /** | |
174 | * @brief Iterator on a generic vector. | |
175 | */ | |
176 | typedef struct VectorIterator { | |
e45132ac BA |
177 | Vector* vector; ///< Vector to be iterated. |
178 | void** current; ///< Current vector element. | |
a7868768 BA |
179 | } VectorIterator; |
180 | ||
181 | /** | |
182 | * @brief Obtain an iterator object, starting at vector beginning (index 0). | |
183 | */ | |
184 | VectorIterator* vector_get_iterator( | |
e45132ac | 185 | Vector* vector ///< Pointer to the vector to iterate over. |
a7868768 BA |
186 | ); |
187 | ||
188 | /** | |
189 | * @brief (Re)set current position inside vector to beginning (0). | |
190 | */ | |
191 | void vectorI_reset_begin( | |
e45132ac | 192 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
193 | ); |
194 | ||
195 | /** | |
196 | * @brief (Re)set current position inside vector to end (vector->size-1). | |
197 | */ | |
198 | void vectorI_reset_end( | |
e45132ac | 199 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
200 | ); |
201 | ||
202 | /** | |
203 | * @brief Tell if there is some data at the current index. | |
204 | */ | |
1ff641f9 | 205 | bool vectorI_has_data( |
e45132ac | 206 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
207 | ); |
208 | ||
209 | /** | |
210 | * @brief Get data contained at the current index. | |
211 | */ | |
212 | void* _vectorI_get( | |
e45132ac | 213 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
214 | ); |
215 | ||
216 | /** | |
217 | * @brief Get data contained at the current index. | |
218 | * @param vectorI "this" pointer. | |
219 | * @param data 'out' variable to contain the result. | |
1ff641f9 | 220 | * |
a7868768 BA |
221 | * Usage: void vectorI_get(VectorIterator* vectorI, void data); |
222 | */ | |
223 | #define vectorI_get(vectorI, data) \ | |
224 | { \ | |
e45132ac BA |
225 | void* pData = _vectorI_get(vectorI); \ |
226 | data = *((typeof(&data))pData); \ | |
a7868768 BA |
227 | } |
228 | ||
229 | /** | |
230 | * @brief Set the element at current index. | |
231 | */ | |
232 | void _vectorI_set( | |
e45132ac BA |
233 | VectorIterator* vectorI, ///< "this" pointer. |
234 | void* data ///< Data to be assigned. | |
a7868768 BA |
235 | ); |
236 | ||
237 | /** | |
238 | * @brief Set the element at current index. | |
239 | * @param vectorI "this" pointer. | |
240 | * @param data Data to be assigned. | |
1ff641f9 | 241 | * |
a7868768 BA |
242 | * Usage: void vectorI_set(VectorIterator* vectorI, void data) |
243 | */ | |
244 | #define vectorI_set(vectorI, data) \ | |
245 | { \ | |
e45132ac BA |
246 | typeof((data)) tmp = data; \ |
247 | _vectorI_set(vectorI,&tmp); \ | |
a7868768 BA |
248 | } |
249 | ||
250 | /** | |
251 | * @brief Move current iterator position forward (toward last index). | |
252 | */ | |
253 | void vectorI_move_next( | |
e45132ac | 254 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
255 | ); |
256 | ||
257 | /** | |
258 | * @brief Move current iterator position backward (toward first index). | |
259 | */ | |
260 | void vectorI_move_prev( | |
e45132ac | 261 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
262 | ); |
263 | ||
264 | /** | |
265 | * @brief Free memory allocated for the iterator. | |
266 | */ | |
267 | void vectorI_destroy( | |
e45132ac | 268 | VectorIterator* vectorI ///< "this" pointer. |
a7868768 BA |
269 | ); |
270 | ||
271 | #endif |