src/ucx/list.c

changeset 504
c094afcdfb27
parent 490
d218607f5a7e
equal deleted inserted replaced
503:aeaf7db26fac 504:c094afcdfb27
193 list->cl = &cx_pointer_list_class; 193 list->cl = &cx_pointer_list_class;
194 } 194 }
195 195
196 // </editor-fold> 196 // </editor-fold>
197 197
198 // <editor-fold desc="empty list implementation">
199
200 static void cx_emptyl_noop(__attribute__((__unused__)) CxList *list) {
201 // this is a noop, but MUST be implemented
202 }
203
204 static void *cx_emptyl_at(
205 __attribute__((__unused__)) struct cx_list_s const *list,
206 __attribute__((__unused__)) size_t index
207 ) {
208 return NULL;
209 }
210
211 static ssize_t cx_emptyl_find(
212 __attribute__((__unused__)) struct cx_list_s const *list,
213 __attribute__((__unused__)) void const *elem
214 ) {
215 return -1;
216 }
217
218 static int cx_emptyl_compare(
219 __attribute__((__unused__)) struct cx_list_s const *list,
220 struct cx_list_s const *other
221 ) {
222 if (other->size == 0) return 0;
223 return -1;
224 }
225
226 static bool cx_emptyl_iter_valid(__attribute__((__unused__)) void const *iter) {
227 return false;
228 }
229
230 static CxIterator cx_emptyl_iterator(
231 struct cx_list_s const *list,
232 size_t index,
233 __attribute__((__unused__)) bool backwards
234 ) {
235 CxIterator iter = {0};
236 iter.src_handle = list;
237 iter.index = index;
238 iter.base.valid = cx_emptyl_iter_valid;
239 return iter;
240 }
241
242 static cx_list_class cx_empty_list_class = {
243 cx_emptyl_noop,
244 NULL,
245 NULL,
246 NULL,
247 NULL,
248 cx_emptyl_noop,
249 NULL,
250 cx_emptyl_at,
251 cx_emptyl_find,
252 cx_emptyl_noop,
253 cx_emptyl_compare,
254 cx_emptyl_noop,
255 cx_emptyl_iterator,
256 };
257
258 CxList cx_empty_list = {
259 NULL,
260 NULL,
261 0,
262 0,
263 NULL,
264 NULL,
265 NULL,
266 false,
267 &cx_empty_list_class,
268 NULL
269 };
270
271 CxList *const cxEmptyList = &cx_empty_list;
272
273 // </editor-fold>
274
198 void cxListDestroy(CxList *list) { 275 void cxListDestroy(CxList *list) {
199 if (list->simple_destructor) {
200 CxIterator iter = cxListIterator(list);
201 cx_foreach(void*, elem, iter) {
202 // already correctly resolved pointer - immediately invoke dtor
203 list->simple_destructor(elem);
204 }
205 }
206 if (list->advanced_destructor) {
207 CxIterator iter = cxListIterator(list);
208 cx_foreach(void*, elem, iter) {
209 // already correctly resolved pointer - immediately invoke dtor
210 list->advanced_destructor(list->destructor_data, elem);
211 }
212 }
213
214 list->cl->destructor(list); 276 list->cl->destructor(list);
215 cxFree(list->allocator, list);
216 } 277 }
217 278
218 int cxListCompare( 279 int cxListCompare(
219 CxList const *list, 280 CxList const *list,
220 CxList const *other 281 CxList const *other
221 ) { 282 ) {
222 if ((list->store_pointer ^ other->store_pointer) || 283 if (
223 ((list->climpl == NULL) ^ (other->climpl != NULL)) || 284 // if one is storing pointers but the other is not
285 (list->store_pointer ^ other->store_pointer) ||
286
287 // if one class is wrapped but the other is not
288 ((list->climpl == NULL) ^ (other->climpl == NULL)) ||
289
290 // if the resolved compare functions are not the same
224 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) != 291 ((list->climpl != NULL ? list->climpl->compare : list->cl->compare) !=
225 (other->climpl != NULL ? other->climpl->compare : other->cl->compare))) { 292 (other->climpl != NULL ? other->climpl->compare : other->cl->compare))
293 ) {
226 // lists are definitely different - cannot use internal compare function 294 // lists are definitely different - cannot use internal compare function
227 if (list->size == other->size) { 295 if (list->size == other->size) {
228 CxIterator left = cxListIterator(list); 296 CxIterator left = cxListIterator(list);
229 CxIterator right = cxListIterator(other); 297 CxIterator right = cxListIterator(other);
230 for (size_t i = 0; i < list->size; i++) { 298 for (size_t i = 0; i < list->size; i++) {

mercurial