Files
LinuxDev2020/08_TestingCoverage/buf.h
2020-11-04 16:49:27 +03:00

87 lines
2.4 KiB
C

/* buf.h --- growable memory buffers for C99
* This is free and unencumbered software released into the public domain.
*
* buf_size(v) : return the number of elements in the buffer (size_t)
* buf_capacity(v) : return the total capacity of the buffer (size_t)
* buf_free(v) : destroy and free the buffer
* buf_push(v, e) : append an element E to the end
* buf_pop(v) : remove and return an element E from the end
* buf_grow(v, n) : increase buffer capactity by (ptrdiff_t) N elements
* buf_trunc(v, n) : set buffer capactity to exactly (ptrdiff_t) N elements
* buf_clear(v, n) : set buffer size to 0 (for push/pop)
*
* Note: buf_push(), buf_grow(), buf_trunc(), and buf_free() may change
* the buffer pointer, and any previously-taken pointers should be
* considered invalidated.
*
* Example usage:
*
* float *values = 0;
* for (size_t i = 0; i < 25; i++)
* buf_push(values, rand() / (float)RAND_MAX);
* for (size_t i = 0; i < buf_size(values); i++)
* printf("values[%zu] = %f\n", i, values[i]);
* buf_free(values);
*/
#ifndef _LIB_BUF_H
#define _LIB_BUF_H
#include <stddef.h>
#include <stdlib.h>
#ifndef BUF_INIT_CAPACITY
# define BUF_INIT_CAPACITY 8
#endif
#ifndef BUF_ABORT
# define BUF_ABORT abort()
#endif
struct buf {
size_t capacity;
size_t size;
char buffer[];
};
void * buf_grow1(void *v, size_t esize, ptrdiff_t n);
#define buf_ptr(v) \
((struct buf *)((char *)(v) - offsetof(struct buf, buffer)))
#define buf_free(v) \
do { \
if (v) { \
free(buf_ptr((v))); \
(v) = 0; \
} \
} while (0)
#define buf_size(v) \
((v) ? buf_ptr((v))->size : 0)
#define buf_capacity(v) \
((v) ? buf_ptr((v))->capacity : 0)
#define buf_push(v, e) \
do { \
if (buf_capacity((v)) == buf_size((v))) { \
(v) = buf_grow1(v, sizeof(*(v)), \
!buf_capacity((v)) ? \
BUF_INIT_CAPACITY : \
buf_capacity((v))); \
} \
(v)[buf_ptr((v))->size++] = (e); \
} while (0)
#define buf_pop(v) \
((v)[--buf_ptr(v)->size])
#define buf_grow(v, n) \
((v) = buf_grow1((v), sizeof(*(v)), n))
#define buf_trunc(v, n) \
((v) = buf_grow1((v), sizeof(*(v)), n - buf_capacity(v)))
#define buf_clear(v) \
((v) ? (buf_ptr((v))->size = 0) : 0)
#endif // _LIB_BUF_H