183 1, |
183 1, |
184 &arl->reallocator |
184 &arl->reallocator |
185 ); |
185 ); |
186 } |
186 } |
187 |
187 |
188 static size_t cx_arl_add_array( |
188 static size_t cx_arl_insert_array( |
189 struct cx_list_s *list, |
189 struct cx_list_s *list, |
|
190 size_t index, |
190 void const *array, |
191 void const *array, |
191 size_t n |
192 size_t n |
192 ) { |
193 ) { |
|
194 // out of bounds and special case check |
|
195 if (index > list->size || n == 0) return 0; |
|
196 |
|
197 // get a correctly typed pointer to the list |
193 cx_array_list *arl = (cx_array_list *) list; |
198 cx_array_list *arl = (cx_array_list *) list; |
|
199 |
|
200 // do we need to move some elements? |
|
201 if (index < list->size) { |
|
202 char const *first_to_move = (char const *) arl->data; |
|
203 first_to_move += index * list->itemsize; |
|
204 size_t elems_to_move = list->size - index; |
|
205 size_t start_of_moved = index + n; |
|
206 |
|
207 if (CX_ARRAY_COPY_SUCCESS != cx_array_copy( |
|
208 &arl->data, |
|
209 &list->size, |
|
210 &list->capacity, |
|
211 start_of_moved, |
|
212 first_to_move, |
|
213 list->itemsize, |
|
214 elems_to_move, |
|
215 &arl->reallocator |
|
216 )) { |
|
217 // if moving existing elems is unsuccessful, abort |
|
218 return 0; |
|
219 } |
|
220 } |
|
221 |
|
222 // note that if we had to move the elements, the following operation |
|
223 // is guaranteed to succeed, because we have the memory already allocated |
|
224 // therefore, it is impossible to leave this function with an invalid array |
|
225 |
|
226 // place the new elements |
194 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy( |
227 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy( |
195 &arl->data, |
228 &arl->data, |
196 &list->size, |
229 &list->size, |
197 &list->capacity, |
230 &list->capacity, |
198 list->size, |
231 index, |
199 array, |
232 array, |
200 list->itemsize, |
233 list->itemsize, |
201 n, |
234 n, |
202 &arl->reallocator |
235 &arl->reallocator |
203 )) { |
236 )) { |
204 return n; |
237 return n; |
205 } else { |
238 } else { |
206 // array list implementation is "all or nothing" |
239 // array list implementation is "all or nothing" |
207 return 0; |
240 return 0; |
208 } |
241 } |
|
242 } |
|
243 |
|
244 static size_t cx_arl_add_array( |
|
245 struct cx_list_s *list, |
|
246 void const *array, |
|
247 size_t n |
|
248 ) { |
|
249 return cx_arl_insert_array(list, list->size, array, n); |
209 } |
250 } |
210 |
251 |
211 static int cx_arl_insert( |
252 static int cx_arl_insert( |
212 struct cx_list_s *list, |
253 struct cx_list_s *list, |
213 size_t index, |
254 size_t index, |