blob: dffaef823e0630f9858c9c9b492c89c59265accf [file] [log] [blame]
Jean-Baptiste Queru46e568c2009-10-27 09:08:42 -07001/* 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
22typedef 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
32AINLINED void
33areflist_init(ARefList* l)
34{
35 l->count = 0;
36 l->max = 1;
37 l->iteration = 0;
38}
39
40void areflist_setEmpty(ARefList* l);
41
42AINLINED void
43areflist_done(ARefList* l)
44{
45 areflist_setEmpty(l);
46}
47
48AINLINED ABool
49areflist_isEmpty(ARefList* l)
50{
51 return (l->count == 0);
52}
53
54int areflist_indexOf(ARefList* l, void* item);
55
56AINLINED ABool
57areflist_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 */
64void 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 */
68ABool areflist_del(ARefList* l, void* item);
69
70AINLINED void
71areflist_push(ARefList* l, void* item)
72{
73 areflist_add(l, item);
74}
75
76void* areflist_pop(ARefList* l);
77
78AINLINED void**
79areflist_items(ARefList* l)
80{
81 return (l->max == 1) ? &l->u.item0 : l->u.items;
82}
83
84AINLINED int
85areflist_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 */
92void** areflist_at(ARefList* l, int n);
93
94/* return the n-th array entry, or NULL in case of invalid index */
95void* areflist_get(ARefList* l, int n);
96
97/* used internally */
98void _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
127void areflist_copy(ARefList* dst, ARefList* src);
128
129#endif /* _ANDROID_UTILS_REFLIST_H */