3 @brief basic buffer library
13 @addtogroup a_buf basic buffer library
18 @brief instance structure for basic buffer
22 void *ptr_
; /*!< address of memory */
23 a_size siz_
; /*!< size of a element */
24 a_size num_
; /*!< number of element */
25 a_size mem_
; /*!< memory of element */
29 @brief access address of buffer for a pointer to buffer structure
30 @param[in] ctx points to an instance of buffer structure
32 A_INTERN
void *a_buf_ptr(a_buf
const *ctx
) { return ctx
->ptr_
; }
33 #define A_BUF_PTR(T, ctx) a_cast_s(T *, a_buf_ptr(ctx))
36 @brief access size of a element for a pointer to buffer structure
37 @param[in] ctx points to an instance of buffer structure
39 A_INTERN a_size
a_buf_siz(a_buf
const *ctx
) { return ctx
->siz_
; }
42 @brief access number of element for a pointer to buffer structure
43 @param[in] ctx points to an instance of buffer structure
45 A_INTERN a_size
a_buf_num(a_buf
const *ctx
) { return ctx
->num_
; }
48 @brief access memory of element for a pointer to buffer structure
49 @param[in] ctx points to an instance of buffer structure
51 A_INTERN a_size
a_buf_mem(a_buf
const *ctx
) { return ctx
->mem_
; }
54 @brief access specified element for a pointer to buffer structure
55 @param[in] ctx points to an instance of buffer structure
56 @param[in] idx index of element less than memory
57 @note should check for out of bounds
58 @return specified element pointer
60 A_INTERN
void *a_buf_at_(a_buf
const *ctx
, a_size idx
)
62 return a_byte_(*, ctx
->ptr_
) + ctx
->siz_
* idx
;
64 #define A_BUF_AT_(T, ctx, idx) a_cast_s(T *, a_buf_at_(ctx, idx))
67 @brief access specified element for a pointer to buffer structure
68 @param[in] ctx points to an instance of buffer structure
69 @param[in] idx index of element less than memory
70 @return specified element pointer
71 @retval 0 out of bounds
73 A_INTERN
void *a_buf_at(a_buf
const *ctx
, a_size idx
)
75 return idx
< ctx
->mem_
? a_buf_at_(ctx
, idx
) : A_NULL
;
77 #define A_BUF_AT(T, ctx, idx) a_cast_s(T *, a_buf_at(ctx, idx))
80 @brief access specified element for a pointer to buffer structure
81 @param[in] ctx points to an instance of buffer structure
82 @param[in] idx index of element -memory < idx < memory
83 @return specified element pointer
84 @retval 0 out of bounds
86 A_INTERN
void *a_buf_idx(a_buf
const *ctx
, a_diff idx
)
88 a_size
const num
= idx
>= 0 ? a_size_c(idx
) : a_size_c(idx
) + ctx
->num_
;
89 return num
< ctx
->mem_
? a_buf_at_(ctx
, num
) : A_NULL
;
91 #define A_BUF_IDX(T, ctx, idx) a_cast_s(T *, a_buf_idx(ctx, idx))
94 @brief access top element for a pointer to buffer structure
95 @param[in] ctx points to an instance of buffer structure
96 @note should check if buffer is empty
97 @return specified element pointer
99 A_INTERN
void *a_buf_top_(a_buf
const *ctx
)
101 return a_byte_(*, ctx
->ptr_
) + ctx
->siz_
* (ctx
->num_
- 1);
103 #define A_BUF_TOP_(T, ctx) a_cast_s(T *, a_buf_top_(ctx))
106 @brief access top element for a pointer to buffer structure
107 @param[in] ctx points to an instance of buffer structure
108 @return specified element pointer
109 @retval 0 empty buffer
111 A_INTERN
void *a_buf_top(a_buf
const *ctx
)
113 return ctx
->num_
? a_buf_top_(ctx
) : A_NULL
;
115 #define A_BUF_TOP(T, ctx) a_cast_s(T *, a_buf_top(ctx))
118 @brief access end pointer for a pointer to buffer structure
119 @param[in] ctx points to an instance of buffer structure
120 @return buffer end pointer
122 A_INTERN
void *a_buf_end(a_buf
const *ctx
)
124 return a_byte_(*, ctx
->ptr_
) + ctx
->siz_
* ctx
->num_
;
126 #define A_BUF_END(T, ctx) a_cast_s(T *, a_buf_end(ctx))
128 #if defined(__cplusplus)
130 #endif /* __cplusplus */
133 @brief constructor for buffer structure
134 @param[in] ctx points to an instance of buffer structure
135 @param[in] ptr address of memory
136 @param[in] siz size of a element
137 @param[in] num number of element
139 A_EXTERN
void a_buf_ctor(a_buf
*ctx
, void *ptr
, a_size siz
, a_size num
);
142 @brief destructor for buffer structure
143 @param[in] ctx points to an instance of buffer structure
144 @param[in] dtor element destructor
146 A_EXTERN
void a_buf_dtor(a_buf
*ctx
, void (*dtor
)(void *));
149 @brief initialize a pointer to buffer structure by moving
150 @param[in] ctx points to an instance of buffer structure
151 @param[in] obj input source pointing to an instance
153 A_EXTERN
void a_buf_move(a_buf
*ctx
, a_buf
*obj
);
156 @brief drop all the elements for a pointer to buffer structure
157 @param[in] ctx points to an instance of buffer structure
158 @param[in] dtor current element destructor
160 A_EXTERN
void a_buf_drop(a_buf
*ctx
, void (*dtor
)(void *));
163 @brief swap elements lhs and rhs for a pointer to buffer structure
164 @param[in] ctx points to an instance of buffer structure
165 @param[in] lhs element index on the left
166 @param[in] rhs element index on the right
168 A_EXTERN
void a_buf_swap(a_buf
const *ctx
, a_size lhs
, a_size rhs
);
171 @brief sort all elements for a pointer to buffer structure
172 @param[in] ctx points to an instance of buffer structure
173 @param[in] cmp a function that compares two elements
174 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
175 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
176 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
178 A_EXTERN
void a_buf_sort(a_buf
const *ctx
, int (*cmp
)(void const *, void const *));
181 @brief insert sort foremost element for a pointer to buffer structure
183 T *obj = A_BUF_PUSH_FORE(T, ctx);
188 a_buf_sort_fore(ctx, cmp);
191 @param[in] ctx points to an instance of buffer structure
192 @param[in] cmp a function that compares two elements
193 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
194 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
195 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
197 A_EXTERN
void a_buf_sort_fore(a_buf
const *ctx
, int (*cmp
)(void const *, void const *));
200 @brief insert sort backmost element for a pointer to buffer structure
202 T *obj = A_BUF_PUSH_BACK(T, ctx);
207 a_buf_sort_back(ctx, cmp);
210 @param[in] ctx points to an instance of buffer structure
211 @param[in] cmp a function that compares two elements
212 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
213 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
214 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
216 A_EXTERN
void a_buf_sort_back(a_buf
const *ctx
, int (*cmp
)(void const *, void const *));
219 @brief push an element into the buffer and sort it
220 @param[in] ctx points to an instance of buffer structure
221 @param[in] key the key on the right for insertion sort
222 @param[in] cmp a function that compares two elements
223 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
224 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
225 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
226 @return element pointer
229 A_EXTERN
void *a_buf_push_sort(a_buf
*ctx
, void const *key
, int (*cmp
)(void const *, void const *));
230 #define A_BUF_PUSH_SORT(T, ctx, key, cmp) a_cast_s(T *, a_buf_push_sort(ctx, key, cmp))
233 @brief search the given element in this buffer
234 @param[in] ctx points to an instance of buffer structure
235 @param[in] obj object that serves as key for the search
236 @param[in] cmp a function that compares two elements
237 @arg cmp(lhs,rhs)==0 *lhs is equivalent to *rhs
238 @arg cmp(lhs,rhs)<0 *lhs goes before *rhs
239 @arg cmp(lhs,rhs)>0 *lhs goes after *rhs
240 @return matching element pointer
243 A_EXTERN
void *a_buf_search(a_buf
const *ctx
, void const *obj
, int (*cmp
)(void const *, void const *));
244 #define A_BUF_SEARCH(T, ctx, obj, cmp) a_cast_s(T *, a_buf_search(ctx, obj, cmp))
247 @brief insert an element into the buffer
248 @param[in] ctx points to an instance of buffer structure
249 @param[in] idx index of element in this buffer
250 @arg 0 a_buf_push_fore
251 @arg n a_buf_push_back
252 @return element pointer
255 A_EXTERN
void *a_buf_insert(a_buf
*ctx
, a_size idx
);
256 #define A_BUF_INSERT(T, ctx, idx) a_cast_s(T *, a_buf_insert(ctx, idx))
259 @brief remove an element from the buffer
260 @param[in] ctx points to an instance of buffer structure
261 @param[in] idx index of element in this buffer
262 @arg 0 a_buf_pull_fore
263 @arg n a_buf_pull_back
264 @return element pointer
267 A_EXTERN
void *a_buf_remove(a_buf
*ctx
, a_size idx
);
268 #define A_BUF_REMOVE(T, ctx, idx) a_cast_s(T *, a_buf_remove(ctx, idx))
271 @brief push an element into the buffer forward
272 @param[in] ctx points to an instance of buffer structure
273 @return element pointer
276 A_EXTERN
void *a_buf_push_fore(a_buf
*ctx
);
277 #define A_BUF_PUSH_FORE(T, ctx) a_cast_s(T *, a_buf_push_fore(ctx))
280 @brief push an element into the buffer backward
281 @param[in] ctx points to an instance of buffer structure
282 @return element pointer
285 A_EXTERN
void *a_buf_push_back(a_buf
*ctx
);
286 #define A_BUF_PUSH_BACK(T, ctx) a_cast_s(T *, a_buf_push_back(ctx))
289 @brief pull an element from the buffer forward
290 @param[in] ctx points to an instance of buffer structure
291 @return element pointer
294 A_EXTERN
void *a_buf_pull_fore(a_buf
*ctx
);
295 #define A_BUF_PULL_FORE(T, ctx) a_cast_s(T *, a_buf_pull_fore(ctx))
298 @brief pull an element from the buffer backward
299 @param[in] ctx points to an instance of buffer structure
300 @return element pointer
303 A_EXTERN
void *a_buf_pull_back(a_buf
*ctx
);
304 #define A_BUF_PULL_BACK(T, ctx) a_cast_s(T *, a_buf_pull_back(ctx))
306 #if defined(__cplusplus)
308 #endif /* __cplusplus */
311 @brief push an element into the buffer
312 @param[in] ctx points to an instance of buffer structure
313 @return element pointer
316 A_INTERN
void *a_buf_push(a_buf
*ctx
) { return a_buf_push_back(ctx
); }
317 #define A_BUF_PUSH(T, ctx) a_cast_s(T *, a_buf_push(ctx))
320 @brief pull an element from the buffer
321 @param[in] ctx points to an instance of buffer structure
322 @return element pointer
325 A_INTERN
void *a_buf_pull(a_buf
*ctx
) { return a_buf_pull_back(ctx
); }
326 #define A_BUF_PULL(T, ctx) a_cast_s(T *, a_buf_pull(ctx))
329 @brief iterate over a buffer
331 a_buf_forenum(i, ctx)
333 T *it = (T *)a_buf_at(ctx, i);
334 assert(a_buf_siz(ctx) == sizeof(*it));
337 @param i index of elements in the buffer
338 @param ctx points to an instance of buffer structure
340 #define a_buf_forenum(i, ctx) a_forenum(a_size, i, (ctx)->num_)
341 #define A_BUF_FORENUM(I, i, ctx) A_FORENUM(I, i, (ctx)->num_)
344 @brief iterate over a buffer in reverse
346 a_buf_forenum_reverse(i, ctx)
348 T *it = (T *)a_buf_at(ctx, i);
349 assert(a_buf_siz(ctx) == sizeof(*it));
352 @param i index of elements in the buffer
353 @param ctx points to an instance of buffer structure
355 #define a_buf_forenum_reverse(i, ctx) a_forenum_reverse(a_size, i, (ctx)->num_)
356 #define A_BUF_FORENUM_REVERSE(I, i, ctx) A_FORENUM_REVERSE(I, i, (ctx)->num_)
359 @brief iterate over a buffer
361 a_buf_foreach(T, *, it, ctx)
363 assert(a_buf_siz(ctx) == sizeof(*it));
366 @param T the prefix of the element type
367 @param S the suffix of the element type
368 @param it the &a_buf to use as a loop counter
369 @param ctx points to an instance of buffer structure
371 #define a_buf_foreach(T, S, it, ctx) a_foreach(T, S, it, (ctx)->ptr_, (ctx)->num_)
372 #define A_BUF_FOREACH(T, it, at, ctx) A_FOREACH(T, it, at, (ctx)->ptr_, (ctx)->num_)
375 @brief iterate over a buffer in reverse
377 a_buf_foreach_reverse(T, *, it, ctx)
379 assert(a_buf_siz(ctx) == sizeof(*it));
382 @param T the prefix of the element type
383 @param S the suffix of the element type
384 @param it the &a_buf to use as a loop counter
385 @param ctx points to an instance of buffer structure
387 #define a_buf_foreach_reverse(T, S, it, ctx) a_foreach_reverse(T, S, it, (ctx)->ptr_, (ctx)->num_)
388 #define A_BUF_FOREACH_REVERSE(T, it, at, ctx) A_FOREACH_REVERSE(T, it, at, (ctx)->ptr_, (ctx)->num_)