1 | #ifndef __INLINE_ARRAY_H__ |
2 | #define __INLINE_ARRAY_H__ |
3 | |
4 | #define DEFINE_INLINE_ARRAY(Type, prefix, ElementType) \ |
5 | typedef struct _##Type { \ |
6 | gsize len; \ |
7 | gsize allocated; \ |
8 | ElementType *items; \ |
9 | } Type; \ |
10 | \ |
11 | static inline void \ |
12 | prefix##_init (Type *ar, \ |
13 | gsize initial_size) \ |
14 | { \ |
15 | ar->len = 0; \ |
16 | ar->allocated = initial_size ? initial_size : 16; \ |
17 | ar->items = g_new0 (ElementType, ar->allocated); \ |
18 | } \ |
19 | \ |
20 | static inline void \ |
21 | prefix##_clear (Type *ar) \ |
22 | { \ |
23 | ar->len = 0; \ |
24 | ar->allocated = 0; \ |
25 | g_clear_pointer (&ar->items, g_free); \ |
26 | } \ |
27 | \ |
28 | static inline ElementType * \ |
29 | prefix##_head (Type *ar) \ |
30 | { \ |
31 | return &ar->items[0]; \ |
32 | } \ |
33 | \ |
34 | static inline ElementType * \ |
35 | prefix##_tail (Type *ar) \ |
36 | { \ |
37 | return &ar->items[ar->len-1]; \ |
38 | } \ |
39 | \ |
40 | static inline ElementType * \ |
41 | prefix##_append (Type *ar) \ |
42 | { \ |
43 | if G_UNLIKELY (ar->len == ar->allocated) \ |
44 | { \ |
45 | ar->allocated *= 2; \ |
46 | ar->items = g_renew (ElementType, ar->items, ar->allocated);\ |
47 | } \ |
48 | \ |
49 | ar->len++; \ |
50 | \ |
51 | return prefix##_tail (ar); \ |
52 | } \ |
53 | \ |
54 | static inline ElementType * \ |
55 | prefix##_append_n (Type *ar, \ |
56 | gsize n) \ |
57 | { \ |
58 | if G_UNLIKELY ((ar->len + n) > ar->allocated) \ |
59 | { \ |
60 | while ((ar->len + n) > ar->allocated) \ |
61 | ar->allocated *= 2; \ |
62 | ar->items = g_renew (ElementType, ar->items, ar->allocated);\ |
63 | } \ |
64 | \ |
65 | ar->len += n; \ |
66 | \ |
67 | return &ar->items[ar->len-n]; \ |
68 | } \ |
69 | \ |
70 | static inline gsize \ |
71 | prefix##_index_of (Type *ar, \ |
72 | const ElementType *element) \ |
73 | { \ |
74 | return element - &ar->items[0]; \ |
75 | } |
76 | |
77 | #endif /* __INLINE_ARRAY_H__ */ |
78 | |