csnip  0.1
ringbuf.h
Go to the documentation of this file.
1 #ifndef CSNIP_RINGBUF_H
2 #define CSNIP_RINGBUF_H
3 
83 #include <stddef.h>
84 
85 #include <csnip/err.h>
86 #include <csnip/preproc.h>
87 
95 #define csnip_ringbuf_Init(head, len, N) \
96  do { \
97  (head) = 0; \
98  (len) = 0; \
99  } while (0)
100 
125 #define csnip_ringbuf_GetHeadIdx(head, len, N, ret, err) \
126  do { \
127  if ((len) == 0) { \
128  csnip_err_Raise(csnip_err_UNDERFLOW, err); \
129  break; \
130  } \
131  (ret) = (head); \
132  } while (0)
133 
143 #define csnip_ringbuf_GetTailIdx(head, len, N, ret, err) \
144  csnip_ringbuf__GetTailIdx((head), (len), (N), (ret), (err))
145 
147 #define csnip_ringbuf__GetTailIdx(head, len, N, ret, err) \
148  do { \
149  if (len == 0) { \
150  csnip_err_Raise(csnip_err_UNDERFLOW, err); \
151  break; \
152  } \
153  ret = csnip_ringbuf__AddWrap(N, (len - 1), head); \
154  } while (0)
168 #define csnip_ringbuf_PushHeadIdx(head, len, N, err) \
169  csnip_ringbuf__PushHeadIdx((head), (len), (N), (err))
170 
172 #define csnip_ringbuf__PushHeadIdx(head, len, N, err) \
173  do { \
174  if (len == N) { \
175  csnip_err_Raise(csnip_err_NOMEM, err); \
176  break; \
177  } \
178  csnip_ringbuf__SubWrapSet(N, 1, head); \
179  ++len; \
180  } while (0)
184 #define csnip_ringbuf_PopHeadIdx(head, len, N, err) \
185  csnip_ringbuf__PopHeadIdx((head), (len), (N), (err))
186 
188 #define csnip_ringbuf__PopHeadIdx(head, len, N, err) \
189  do { \
190  if (len == 0) { \
191  csnip_err_Raise(csnip_err_UNDERFLOW, err); \
192  break; \
193  } \
194  csnip_ringbuf__AddWrapSet(N, 1, head); \
195  --len; \
196  } while (0)
203 #define csnip_ringbuf_PushTailIdx(head, len, N, err) \
204  csnip_ringbuf__PushTailIdx((head), (len), (N), (err))
205 
207 #define csnip_ringbuf__PushTailIdx(head, len, N, err) \
208  do { \
209  if (len == N) { \
210  csnip_err_Raise(csnip_err_NOMEM, err); \
211  break; \
212  } \
213  ++len; \
214  } while (0)
218 #define csnip_ringbuf_PopTailIdx(head, len, N, err) \
219  csnip_ringbuf__PopTailIdx((head), (len), (N), (err))
220 
222 #define csnip_ringbuf__PopTailIdx(head, len, N, err) \
223  do { \
224  if (len == 0) { \
225  csnip_err_Raise(csnip_err_UNDERFLOW, err); \
226  break; \
227  } \
228  --len; \
229  } while (0)
237 #define csnip_ringbuf_IsFull(head, len, N) ((len) == (N))
238 
244 #define csnip_ringbuf_IsEmpty(head, len, N) ((len) == 0)
245 
252 #define csnip_ringbuf_CheckIdx(head, len, N, idx, err) \
253  csnip_ringbuf__CheckIdx((head), (len), (N), (idx), (err))
254 
256 #define csnip_ringbuf__CheckIdx(head, len, N, idx, err) \
257  do { \
258  if ((idx) >= (head)) { \
259  if ((idx) - (head) >= (len)) { \
260  csnip_err_Raise(csnip_err_RANGE, err); \
261  } \
262  } else { \
263  if ((idx) - (head) + (N) >= (len)) { \
264  csnip_err_Raise(csnip_err_RANGE, err); \
265  } \
266  } \
267  } while (0)
295 #define csnip_ringbuf_AddWrap(N, amount, idx) \
296  ((amount) >= 0 ? csnip_ringbuf__AddWrap((N), (amount), (idx)) \
297  : csnip_ringbuf__SubWrap((N), -(amount), (idx)))
298 
304 #define csnip_ringbuf_AddWrapSet(N, amount, idx) \
305  ((amount) >= 0 ? csnip_ringbuf__AddWrapSet((N), (amount), (idx)) \
306  : csnip_ringbuf__SubWrapSet((N), -(amount), (idx)))
307 
333 #define csnip_ringbuf_SubWrap(N, amount, idx) \
334  ((amount) >= 0 ? csnip_ringbuf__SubWrap((N), (amount), (idx)) \
335  : csnip_ringbuf__AddWrap((N), -(amount), (idx)))
336 
342 #define csnip_ringbuf_SubWrapSet(N, amount, idx) \
343  ((amount) >= 0 ? csnip_ringbuf__SubWrapSet((N), (amount), (idx)) \
344  : csnip_ringbuf__AddWrapSet((N), -(amount), (idx)sebase))
345 
347 #define csnip_ringbuf__AddWrap(N, amount, idx) \
348  (idx < N - amount ? idx + amount : amount - (N - idx))
349 
350 #define csnip_ringbuf__AddWrapSet(N, amount, idx) \
351  (idx < N - amount ? (idx += amount) \
352  : (idx = amount - (N - idx)))
353 
354 #define csnip_ringbuf__SubWrap(N, amount, idx) \
355  (idx >= amount ? idx - amount : idx - amount + N)
356 
357 #define csnip_ringbuf__SubWrapSet(N, amount, idx) \
358  (idx >= amount ? (idx -= amount) : (idx = idx - amount + N))
367 #define csnip_ringbuf_PushHead(head, len, N, arr, val, err) \
368  do { \
369  int csnip__err2 = 0; \
370  csnip_ringbuf_PushHeadIdx(head, len, N, csnip__err2); \
371  if (csnip__err2 != 0) { \
372  csnip_err_Raise(csnip__err2, err); \
373  break; \
374  } \
375  (arr)[head] = (val); \
376  } while (0)
377 
383 #define csnip_ringbuf_PopHead(head, len, N, arr, ret, err) \
384  do { \
385  (ret) = (arr)[head]; \
386  csnip_ringbuf_PopHeadIdx(head, len, N, err); \
387  } while (0)
388 
393 #define csnip_ringbuf_PushTail(head, len, N, arr, val, err) \
394  do { \
395  int csnip__err2 = 0; \
396  size_t csnip__i; \
397  csnip_ringbuf_PushTailIdx(head, len, N, csnip__err2); \
398  if (csnip__err2 != 0) { \
399  csnip_err_Raise(csnip__err2, err); \
400  break; \
401  } \
402  csnip_ringbuf_GetTailIdx(head, len, N, csnip__i, csnip__err2); \
403  if (csnip__err2 != 0) { \
404  csnip_err_Raise(csnip__err2, err); \
405  break; \
406  } \
407  (arr)[csnip__i] = (val); \
408  } while (0)
409 
414 #define csnip_ringbuf_PopTail(head, len, N, arr, ret, err) \
415  do { \
416  int csnip__err2 = 0; \
417  size_t csnip__i; \
418  csnip_ringbuf_GetTailIdx(head, len, N, csnip__i, csnip__err2); \
419  if (csnip__err2 != 0) { \
420  csnip_err_Raise(csnip__err2, err); \
421  break; \
422  } \
423  (ret) = (arr)[csnip__i]; \
424  csnip_ringbuf_PopTailIdx(head, len, N, err); \
425  } while (0)
426 
443 #define CSNIP_RINGBUF_DECL_IDX_FUNCS(scope, prefix, idx_type, gen_args) \
444  scope void prefix##init(csnip_pp_list_##gen_args); \
445  scope idx_type prefix##get_head_idx(csnip_pp_list_##gen_args); \
446  scope idx_type prefix##get_tail_idx(csnip_pp_list_##gen_args); \
447  scope void prefix##push_head_idx(csnip_pp_list_##gen_args); \
448  scope void prefix##pop_head_idx(csnip_pp_list_##gen_args); \
449  scope void prefix##push_tail_idx(csnip_pp_list_##gen_args); \
450  scope void prefix##pop_tail_idx(csnip_pp_list_##gen_args); \
451  scope int prefix##is_full(csnip_pp_list_##gen_args); \
452  scope int prefix##is_empty(csnip_pp_list_##gen_args); \
453  scope void prefix##check_idx(csnip_pp_prepend_##gen_args idx_type); \
454  scope idx_type prefix##add_wrap(csnip_pp_prepend_##gen_args \
455  idx_type, idx_type); \
456  scope idx_type prefix##sub_wrap(csnip_pp_prepend_##gen_args \
457  idx_type, idx_type); \
458 
477 #define CSNIP_RINGBUF_DECL_VAL_FUNCS(scope, prefix, val_type, gen_args) \
478  scope void prefix##push_head(csnip_pp_prepend_##gen_args \
479  val_type val); \
480  scope val_type prefix##pop_head(csnip_pp_list_##gen_args); \
481  scope void prefix##push_tail(csnip_pp_prepend_##gen_args \
482  val_type val); \
483  scope val_type prefix##pop_tail(csnip_pp_list_##gen_args);
484 
560 #define CSNIP_RINGBUF_DEF_IDX_FUNCS(scope, prefix, idx_type, gen_args, \
561  head, len, N, err) \
562  scope void prefix##init(csnip_pp_list_##gen_args) { \
563  csnip_ringbuf_Init(head, len, N); \
564  } \
565  scope idx_type prefix##get_head_idx(csnip_pp_list_##gen_args) { \
566  idx_type csnip__ret; \
567  csnip_ringbuf_GetHeadIdx(head, len, N, csnip__ret, err); \
568  return csnip__ret; \
569  } \
570  scope idx_type prefix##get_tail_idx(csnip_pp_list_##gen_args) { \
571  idx_type csnip__ret; \
572  csnip_ringbuf_GetTailIdx(head, len, N, csnip__ret, err); \
573  return csnip__ret; \
574  } \
575  scope void prefix##push_head_idx(csnip_pp_list_##gen_args) { \
576  csnip_ringbuf_PushHeadIdx(head, len, N, err); \
577  } \
578  scope void prefix##pop_head_idx(csnip_pp_list_##gen_args) { \
579  csnip_ringbuf_PopHeadIdx(head, len, N, err); \
580  } \
581  scope void prefix##push_tail_idx(csnip_pp_list_##gen_args) { \
582  csnip_ringbuf_PushTailIdx(head, len, N, err); \
583  } \
584  scope void prefix##pop_tail_idx(csnip_pp_list_##gen_args) { \
585  csnip_ringbuf_PopTailIdx(head, len, N, err); \
586  } \
587  scope int prefix##is_full(csnip_pp_list_##gen_args) { \
588  return csnip_ringbuf_IsFull(head, len, N); \
589  } \
590  scope int prefix##is_empty(csnip_pp_list_##gen_args) { \
591  return csnip_ringbuf_IsEmpty(head, len, N); \
592  } \
593  scope void prefix##check_idx(csnip_pp_prepend_##gen_args \
594  idx_type csnip__i) \
595  { \
596  csnip_ringbuf_CheckIdx(head, len, N, csnip__i, err); \
597  } \
598  scope idx_type prefix##add_wrap(csnip_pp_prepend_##gen_args \
599  idx_type csnip__amount, idx_type csnip__base) \
600  { \
601  return csnip_ringbuf_AddWrap(N, csnip__amount, csnip__base); \
602  } \
603  scope idx_type prefix##sub_wrap(csnip_pp_prepend_##gen_args \
604  idx_type csnip__amount, idx_type csnip__base) \
605  { \
606  return csnip_ringbuf_SubWrap(N, csnip__amount, csnip__base); \
607  }
608 
622 #define CSNIP_RINGBUF_DEF_VAL_FUNCS(scope, prefix, val_type, \
623  gen_args, head, len, N, arr, err) \
624  scope void prefix##push_head(csnip_pp_prepend_##gen_args \
625  val_type val) { \
626  csnip_ringbuf_PushHead(head, len, N, arr, val, err); \
627  } \
628  scope val_type prefix##pop_head(csnip_pp_list_##gen_args) { \
629  val_type csnip__ret; \
630  csnip_ringbuf_PopHead(head, len, N, arr, csnip__ret, err); \
631  return csnip__ret; \
632  } \
633  scope void prefix##push_tail(csnip_pp_prepend_##gen_args \
634  val_type val) { \
635  csnip_ringbuf_PushTail(head, len, N, arr, val, err); \
636  } \
637  scope val_type prefix##pop_tail(csnip_pp_list_##gen_args) { \
638  val_type csnip__ret; \
639  csnip_ringbuf_PopTail(head, len, N, arr, csnip__ret, err); \
640  return csnip__ret; \
641  }
642 
645 #endif /* CSNIP_RINGBUF_H */
646 
647 #if defined(CSNIP_SHORT_NAMES) && !defined(CSNIP_RINGBUF_HAVE_SHORT_NAMES)
648 #define ringbuf_Init csnip_ringbuf_Init
649 #define ringbuf_GetHeadIdx csnip_ringbuf_GetHeadIdx
650 #define ringbuf_GetTailIdx csnip_ringbuf_GetTailIdx
651 #define ringbuf_PushHeadIdx csnip_ringbuf_PushHeadIdx
652 #define ringbuf_PopHeadIdx csnip_ringbuf_PopHeadIdx
653 #define ringbuf_PushTailIdx csnip_ringbuf_PushTailIdx
654 #define ringbuf_PopTailIdx csnip_ringbuf_PopTailIdx
655 #define ringbuf_CheckIdx csnip_ringbuf_CheckIdx
656 #define ringbuf_AddWrap csnip_ringbuf_AddWrap
657 #define ringbuf_AddWrapSet csnip_ringbuf_AddWrapSet
658 #define ringbuf_SubWrap csnip_ringbuf_SubWrap
659 #define ringbuf_SubWrapSet csnip_ringbuf_SubWrapSet
660 #define ringbuf_PushHead csnip_ringbuf_PushHead
661 #define ringbuf_PopHead csnip_ringbuf_PopHead
662 #define ringbuf_PushTail csnip_ringbuf_PushTail
663 #define ringbuf_PopTail csnip_ringbuf_PopTail
664 #define CSNIP_RINGBUF_HAVE_SHORT_NAMES
665 #endif /* CSNIP_SHORT_NAMES && !CSNIP_RINGBUF_HAVE_SHORT_NAMES */
Error handling.