/* Copyright (C) 2007-2008 The Android Open Source Project ** ** This software is licensed under the terms of the GNU General Public ** License version 2, as published by the Free Software Foundation, and ** may be copied, distributed, and modified under those terms. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. */ #ifndef _ANDROID_UTILS_REFLIST_H #define _ANDROID_UTILS_REFLIST_H #include "android/utils/system.h" /* definitions for a smart list of references to generic objects. * supports safe deletion and addition while they are being iterated * with AREFLIST_FOREACH() macro */ typedef struct ARefList { uint16_t count, max; uint16_t iteration; union { struct ARefList* next; void* item0; void** items; } u; } ARefList; AINLINED void areflist_init(ARefList* l) { l->count = 0; l->max = 1; l->iteration = 0; } void areflist_setEmpty(ARefList* l); AINLINED void areflist_done(ARefList* l) { areflist_setEmpty(l); } AINLINED ABool areflist_isEmpty(ARefList* l) { return (l->count == 0); } int areflist_indexOf(ARefList* l, void* item); AINLINED ABool areflist_has(ARefList* l, void* item) { return areflist_indexOf(l, item) >= 0; } /* if 'item' is not NULL, append it to the list. An item * can be added several times to a list */ void areflist_add(ARefList* l, void* item); /* if 'item' is not NULL, try to remove it from the list */ /* returns TRUE iff the item was found in the list */ ABool areflist_del(ARefList* l, void* item); AINLINED void areflist_push(ARefList* l, void* item) { areflist_add(l, item); } void* areflist_pop(ARefList* l); AINLINED void** areflist_items(ARefList* l) { return (l->max == 1) ? &l->u.item0 : l->u.items; } AINLINED int areflist_count(ARefList* l) { return l->count; } /* return a pointer to the n-th list array entry, or NULL in case of invalid index */ void** areflist_at(ARefList* l, int n); /* return the n-th array entry, or NULL in case of invalid index */ void* areflist_get(ARefList* l, int n); /* used internally */ void _areflist_remove_deferred(ARefList* l); #define AREFLIST_FOREACH(list_,item_,statement_) \ ({ ARefList* _reflist = (list_); \ int _reflist_i = 0; \ int _reflist_n = _reflist->count; \ _reflist->iteration += 2; \ for ( ; _reflist_i < _reflist_n; _reflist_i++ ) { \ void** __reflist_at = areflist_at(_reflist, _reflist_i); \ void* item_ = *__reflist_at; \ if (item_ != NULL) { \ statement_; \ } \ } \ _reflist->iteration -= 2; \ if (_reflist->iteration == 1) \ _areflist_remove_deferred(_reflist); \ }) /* use this to delete the currently iterated element */ #define AREFLIST_DEL_ITERATED() \ ({ *_reflist_at = NULL; \ _reflist->iteration |= 1; }) /* use this to replace the currently iterated element */ #define AREFLIST_SET_ITERATED(item) \ ({ *_reflist_at = (item); \ if (item == NULL) _reflist->iteration |= 1; }) void areflist_copy(ARefList* dst, ARefList* src); #endif /* _ANDROID_UTILS_REFLIST_H */