12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /* Philip Thrasher's Crazy Awesome Ring Buffer Macros!
- *
- * Below you will find some naughty macros for easy owning and manipulating
- * generic ring buffers. Yes, they are slightly evil in readability, but they
- * are really fast, and they work great.
- *
- * Example usage:
- *
- * #include <stdio.h>
- *
- * // So we can use this in any method, this gives us a typedef
- * // named 'intBuffer'.
- * ringBuffer_typedef(int, intBuffer);
- *
- * int main() {
- * // Declare vars.
- * intBuffer myBuffer;
- *
- * bufferInit(myBuffer,1024,int);
- *
- * // We must have the pointer. All of the macros deal with the pointer.
- * // (except for init.)
- * intBuffer* myBuffer_ptr;
- * myBuffer_ptr = &myBuffer;
- *
- * // Write two values.
- * bufferWrite(myBuffer_ptr,37);
- * bufferWrite(myBuffer_ptr,72);
- *
- * // Read a value into a local variable.
- * int first;
- * bufferRead(myBuffer_ptr,first);
- * assert(first == 37); // true
- *
- * int second;
- * bufferRead(myBuffer_ptr,second);
- * assert(second == 72); // true
- *
- * return 0;
- * }
- *
- */
- #ifndef _ringbuffer_h
- #define _ringbuffer_h
- int __mod(int a, int b)
- {
- int r = a % b;
- return r < 0 ? r + b : r;
- }
- #define ringBuffer_typedef(T, NAME) \
- typedef struct { \
- int size; \
- int start; \
- int end; \
- T* elems; \
- } NAME
- #define bufferInit(BUF, S, T) \
- BUF.size = S+1; \
- BUF.start = 0; \
- BUF.end = 0; \
- BUF.elems = (T*)calloc(BUF.size, sizeof(T))
- #define bufferDestroy(BUF) free(BUF->elems)
- #define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size)
- #define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size)
- #define isBufferEmpty(BUF) (BUF->end == BUF->start)
- #define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start)
- #define bufferGet(BUF, INDEX) (BUF->elems[__mod(BUF->end - INDEX, BUF->size)])
- #define bufferWrite(BUF, ELEM) \
- BUF->elems[BUF->end] = ELEM; \
- BUF->end = (BUF->end + 1) % BUF->size; \
- if (isBufferEmpty(BUF)) { \
- BUF->start = nextStartIndex(BUF); \
- }
- #define bufferRead(BUF, ELEM) \
- ELEM = BUF->elems[BUF->start]; \
- BUF->start = nextStartIndex(BUF);
- #endif
|