1 /* -*- coding: utf-8 -*-
2  * ----------------------------------------------------------------------
3  * Copyright © 2011-2013, RedJack, LLC.
4  * All rights reserved.
5  *
6  * Please see the COPYING file in this distribution for license details.
7  * ----------------------------------------------------------------------
8  */
9 
10 #ifndef LIBCORK_DS_ARRAY_H
11 #define LIBCORK_DS_ARRAY_H
12 
13 
14 #include <libcork/core/api.h>
15 #include <libcork/core/callbacks.h>
16 #include <libcork/core/types.h>
17 
18 
19 /*-----------------------------------------------------------------------
20  * Resizable arrays
21  */
22 
23 struct cork_array_priv;
24 
25 struct cork_raw_array {
26     void  *items;
27     size_t  size;
28     struct cork_array_priv  *priv;
29 };
30 
31 CORK_API void
32 cork_raw_array_init(struct cork_raw_array *array, size_t element_size);
33 
34 CORK_API void
35 cork_raw_array_done(struct cork_raw_array *array);
36 
37 CORK_API void
38 cork_raw_array_set_callback_data(struct cork_raw_array *array,
39                                  void *user_data, cork_free_f free_user_data);
40 
41 CORK_API void
42 cork_raw_array_set_init(struct cork_raw_array *array, cork_init_f init);
43 
44 CORK_API void
45 cork_raw_array_set_done(struct cork_raw_array *array, cork_done_f done);
46 
47 CORK_API void
48 cork_raw_array_set_reuse(struct cork_raw_array *array, cork_init_f reuse);
49 
50 CORK_API void
51 cork_raw_array_set_remove(struct cork_raw_array *array, cork_done_f remove);
52 
53 CORK_API size_t
54 cork_raw_array_element_size(const struct cork_raw_array *array);
55 
56 CORK_API void
57 cork_raw_array_clear(struct cork_raw_array *array);
58 
59 CORK_API void *
60 cork_raw_array_elements(const struct cork_raw_array *array);
61 
62 CORK_API void *
63 cork_raw_array_at(const struct cork_raw_array *array, size_t index);
64 
65 CORK_API size_t
66 cork_raw_array_size(const struct cork_raw_array *array);
67 
68 CORK_API bool
69 cork_raw_array_is_empty(const struct cork_raw_array *array);
70 
71 CORK_API void
72 cork_raw_array_ensure_size(struct cork_raw_array *array, size_t count);
73 
74 CORK_API void *
75 cork_raw_array_append(struct cork_raw_array *array);
76 
77 CORK_API int
78 cork_raw_array_copy(struct cork_raw_array *dest,
79                     const struct cork_raw_array *src,
80                     cork_copy_f copy, void *user_data);
81 
82 
83 /*-----------------------------------------------------------------------
84  * Type-checked resizable arrays
85  */
86 
87 #define cork_array(T) \
88     struct { \
89         T  *items; \
90         size_t  size; \
91         struct cork_array_priv  *priv; \
92     }
93 
94 #define cork_array_element_size(arr)  (sizeof((arr)->items[0]))
95 #define cork_array_elements(arr)  ((arr)->items)
96 #define cork_array_at(arr, i)     ((arr)->items[(i)])
97 #define cork_array_size(arr)      ((arr)->size)
98 #define cork_array_is_empty(arr)  ((arr)->size == 0)
99 #define cork_array_to_raw(arr)    ((struct cork_raw_array *) (void *) (arr))
100 
101 #define cork_array_init(arr) \
102     (cork_raw_array_init(cork_array_to_raw(arr), cork_array_element_size(arr)))
103 #define cork_array_done(arr) \
104     (cork_raw_array_done(cork_array_to_raw(arr)))
105 
106 #define cork_array_set_callback_data(arr, ud, fud) \
107     (cork_raw_array_set_callback_data(cork_array_to_raw(arr), (ud), (fud)))
108 #define cork_array_set_init(arr, i) \
109     (cork_raw_array_set_init(cork_array_to_raw(arr), (i)))
110 #define cork_array_set_done(arr, d) \
111     (cork_raw_array_set_done(cork_array_to_raw(arr), (d)))
112 #define cork_array_set_reuse(arr, r) \
113     (cork_raw_array_set_reuse(cork_array_to_raw(arr), (r)))
114 #define cork_array_set_remove(arr, r) \
115     (cork_raw_array_set_remove(cork_array_to_raw(arr), (r)))
116 
117 #define cork_array_clear(arr) \
118     (cork_raw_array_clear(cork_array_to_raw(arr)))
119 #define cork_array_copy(d, s, c, ud) \
120     (cork_raw_array_copy(cork_array_to_raw(d), cork_array_to_raw(s), (c), (ud)))
121 
122 #define cork_array_ensure_size(arr, count) \
123     (cork_raw_array_ensure_size(cork_array_to_raw(arr), (count)))
124 
125 #define cork_array_append(arr, element) \
126     (cork_raw_array_append(cork_array_to_raw(arr)), \
127      ((arr)->items[(arr)->size - 1] = (element), (void) 0))
128 
129 #define cork_array_append_get(arr) \
130     (cork_raw_array_append(cork_array_to_raw(arr)), \
131      &(arr)->items[(arr)->size - 1])
132 
133 
134 /*-----------------------------------------------------------------------
135  * Builtin array types
136  */
137 
138 CORK_API void
139 cork_raw_pointer_array_init(struct cork_raw_array *array, cork_free_f free);
140 
141 #define cork_pointer_array_init(arr, f) \
142     (cork_raw_pointer_array_init(cork_array_to_raw(arr), (f)))
143 
144 struct cork_string_array {
145     const char  **items;
146     size_t  size;
147     struct cork_array_priv  *priv;
148 };
149 
150 CORK_API void
151 cork_string_array_init(struct cork_string_array *array);
152 
153 CORK_API void
154 cork_string_array_append(struct cork_string_array *array, const char *str);
155 
156 CORK_API void
157 cork_string_array_copy(struct cork_string_array *dest,
158                        const struct cork_string_array *src);
159 
160 
161 #endif /* LIBCORK_DS_ARRAY_H */
162