try to compile with -std=c90 4/n
[liba.git] / include / a / buf.h
blob6edab5cb0b590865f8ac6b275a506cd6169ff4ce
1 /*!
2 @file buf.h
3 @brief basic buffer library
4 */
6 #ifndef LIBA_BUF_H
7 #define LIBA_BUF_H
9 #include "a.h"
11 /*!
12 @ingroup liba
13 @addtogroup a_buf basic buffer library
17 /*!
18 @brief instance structure for basic buffer
20 typedef struct a_buf
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 */
26 } a_buf;
28 /*!
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))
35 /*!
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_; }
41 /*!
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_; }
47 /*!
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_; }
53 /*!
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))
66 /*!
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))
79 /*!
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))
93 /*!
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)
129 extern "C" {
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
182 @code{.c}
183 T *obj = A_BUF_PUSH_FORE(T, ctx);
184 if (obj)
186 CTOR(obj);
187 INIT(obj);
188 a_buf_sort_fore(ctx, cmp);
190 @endcode
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
201 @code{.c}
202 T *obj = A_BUF_PUSH_BACK(T, ctx);
203 if (obj)
205 CTOR(obj);
206 INIT(obj);
207 a_buf_sort_back(ctx, cmp);
209 @endcode
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
227 @retval 0 failure
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
241 @retval 0 failure
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
253 @retval 0 failure
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
265 @retval 0 failure
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
274 @retval 0 failure
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
283 @retval 0 failure
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
292 @retval 0 failure
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
301 @retval 0 failure
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)
307 } /* extern "C" */
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
314 @retval 0 failure
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
323 @retval 0 failure
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
330 @code{.c}
331 a_buf_forenum(i, ctx)
333 T *it = (T *)a_buf_at(ctx, i);
334 assert(a_buf_siz(ctx) == sizeof(*it));
336 @endcode
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
345 @code{.c}
346 a_buf_forenum_reverse(i, ctx)
348 T *it = (T *)a_buf_at(ctx, i);
349 assert(a_buf_siz(ctx) == sizeof(*it));
351 @endcode
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
360 @code{.c}
361 a_buf_foreach(T, *, it, ctx)
363 assert(a_buf_siz(ctx) == sizeof(*it));
365 @endcode
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
376 @code{.c}
377 a_buf_foreach_reverse(T, *, it, ctx)
379 assert(a_buf_siz(ctx) == sizeof(*it));
381 @endcode
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_)
390 /*! @} a_buf */
392 #endif /* a/buf.h */