1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #ifndef _ANDROID_UTILS_REFLIST_H 13 #define _ANDROID_UTILS_REFLIST_H 14 15 #include "android/utils/system.h" 16 17 /* definitions for a smart list of references to generic objects. 18 * supports safe deletion and addition while they are being iterated 19 * with AREFLIST_FOREACH() macro 20 */ 21 22 typedef struct ARefList { 23 uint16_t count, max; 24 uint16_t iteration; 25 union { 26 struct ARefList* next; 27 void* item0; 28 void** items; 29 } u; 30 } ARefList; 31 32 AINLINED void 33 areflist_init(ARefList* l) 34 { 35 l->count = 0; 36 l->max = 1; 37 l->iteration = 0; 38 } 39 40 void areflist_setEmpty(ARefList* l); 41 42 AINLINED void 43 areflist_done(ARefList* l) 44 { 45 areflist_setEmpty(l); 46 } 47 48 AINLINED ABool 49 areflist_isEmpty(ARefList* l) 50 { 51 return (l->count == 0); 52 } 53 54 int areflist_indexOf(ARefList* l, void* item); 55 56 AINLINED ABool 57 areflist_has(ARefList* l, void* item) 58 { 59 return areflist_indexOf(l, item) >= 0; 60 } 61 62 /* if 'item' is not NULL, append it to the list. An item 63 * can be added several times to a list */ 64 void areflist_add(ARefList* l, void* item); 65 66 /* if 'item' is not NULL, try to remove it from the list */ 67 /* returns TRUE iff the item was found in the list */ 68 ABool areflist_del(ARefList* l, void* item); 69 70 AINLINED void 71 areflist_push(ARefList* l, void* item) 72 { 73 areflist_add(l, item); 74 } 75 76 void* areflist_pop(ARefList* l); 77 78 AINLINED void** 79 areflist_items(ARefList* l) 80 { 81 return (l->max == 1) ? &l->u.item0 : l->u.items; 82 } 83 84 AINLINED int 85 areflist_count(ARefList* l) 86 { 87 return l->count; 88 } 89 90 /* return a pointer to the n-th list array entry, 91 or NULL in case of invalid index */ 92 void** areflist_at(ARefList* l, int n); 93 94 /* return the n-th array entry, or NULL in case of invalid index */ 95 void* areflist_get(ARefList* l, int n); 96 97 /* used internally */ 98 void _areflist_remove_deferred(ARefList* l); 99 100 #define AREFLIST_FOREACH(list_,item_,statement_) \ 101 ({ ARefList* _reflist = (list_); \ 102 int _reflist_i = 0; \ 103 int _reflist_n = _reflist->count; \ 104 _reflist->iteration += 2; \ 105 for ( ; _reflist_i < _reflist_n; _reflist_i++ ) { \ 106 void** __reflist_at = areflist_at(_reflist, _reflist_i); \ 107 void* item_ = *__reflist_at; \ 108 if (item_ != NULL) { \ 109 statement_; \ 110 } \ 111 } \ 112 _reflist->iteration -= 2; \ 113 if (_reflist->iteration == 1) \ 114 _areflist_remove_deferred(_reflist); \ 115 }) 116 117 /* use this to delete the currently iterated element */ 118 #define AREFLIST_DEL_ITERATED() \ 119 ({ *_reflist_at = NULL; \ 120 _reflist->iteration |= 1; }) 121 122 /* use this to replace the currently iterated element */ 123 #define AREFLIST_SET_ITERATED(item) \ 124 ({ *_reflist_at = (item); \ 125 if (item == NULL) _reflist->iteration |= 1; }) 126 127 void areflist_copy(ARefList* dst, ARefList* src); 128 129 #endif /* _ANDROID_UTILS_REFLIST_H */ 130