123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- #pragma once
- #ifndef ELL_VEC_H
- #define ELL_VEC_H
- #include <stdlib.h>
- struct ell_vec_core {
- size_t capacity;
- size_t size;
- };
- #define ELL_VEC_RAW(name, type) \
- struct name { \
- struct ell_vec_core core; \
- type; \
- }
- #define ELL_VEC_DECLARE(name, type) ELL_VEC_RAW(name, type* data)
- #define ELL_VEC_DECLARE_FP(name, ret, ...) \
- ELL_VEC_RAW(name, ret (**data)(__VA_ARGS__))
- #define ELL_VEC_DECLARE_TDEF(name, type) \
- typedef ELL_VEC_DECLARE(name, type) name
- #define ELL_VEC_RAW_TDEF(name, type) typedef ELL_VEC_RAW(name, type) name
- /* Initialization and Modifying */
- #define ELL_VEC_INIT(vec) ell__vec_init(&(vec)->core, (void**)&(vec)->data)
- #define ELL_VEC_INIT_RESERVE(vec, i) \
- do { \
- ell__vec_init(&(vec)->core, (void**)&(vec)->data); \
- ELL_VEC_RESERVE((vec), (i)); \
- } while (0)
- #define ELL_VEC_INIT_SIZE(vec, i) \
- do { \
- ell__vec_init(&(vec)->core, (void**)&(vec)->data); \
- ELL_VEC_RESIZE((vec), (i)); \
- } while (0)
- #define ELL_VEC_INIT_FILL(vec, s, i) \
- do { \
- ELL_VEC_INIT_SIZE((vec), (s)); \
- ELL_VEC_FILL((vec), (i)); \
- } while (0)
- #define ELL_VEC_PUSH(vec, value) \
- do { \
- ell__vec_ensure_capacity(&(vec)->core, (void**)&(vec)->data, \
- sizeof(*((vec)->data))); \
- (vec)->data[(vec)->core.size++] = (value); \
- } while (0)
- #define ELL_VEC_POP(vec) ((vec)->core.size--)
- #define ELL_VEC_RESET(vec) ell__vec_reset(&(vec)->core, (void**)&(vec)->data)
- #define ELL_VEC_RESERVE(vec, i) \
- ell__vec_reserve(&(vec)->core, (void**)&(vec)->data, \
- sizeof(*((vec)->data)), (i));
- #define ELL_VEC_RESIZE(vec, i) \
- ell__vec_resize(&(vec)->core, (void**)&(vec)->data, \
- sizeof(*((vec)->data)), (i));
- #define ELL_VEC_AT(vec, i) ((vec)->data[(i)])
- #define ELL_VEC_FRONT(vec) ELL_VEC_AT((vec), 0)
- #define ELL_VEC_BACK(vec) ELL_VEC_AT((vec), (vec)->core.size - 1)
- #define ELL_VEC_PTR(vec, i) ((vec)->data + (i))
- #define ELL_VEC_FILL(vec, i) \
- do { \
- if ((vec)->core.size == 0) { \
- break; \
- } \
- ((vec))->data[0] = (i); \
- ell__vec_fill_from_first(&(vec)->core, (void*)((vec)->data), \
- sizeof(*((vec)->data))); \
- } while (0)
- /* Queries */
- // XXX: build wrapper functions such that size and capacity cannot
- // be written through these macros.
- #define ELL_VEC_SIZE(vec) ((vec)->core.size)
- #define ELL_VEC_CAPACITY(vec) ((vec)->core.capacity)
- /* Implementation */
- void ell__vec_init(struct ell_vec_core* core, void** data);
- void ell__vec_ensure_capacity(struct ell_vec_core* core, void** data,
- size_t element_size);
- void ell__vec_reset(struct ell_vec_core* core, void** data);
- void ell__vec_reserve(struct ell_vec_core* core, void** data,
- size_t element_size, size_t elements);
- void ell__vec_resize(struct ell_vec_core* core, void** data,
- size_t element_size, size_t elements);
- void ell__vec_fill_from_first(struct ell_vec_core* core, void* data,
- size_t element_size);
- /* Convenience types */
- ELL_VEC_DECLARE(ell_vec_uint, unsigned int);
- ELL_VEC_DECLARE(ell_vec_int, int);
- ELL_VEC_DECLARE(ell_vec_ulong, unsigned long);
- ELL_VEC_DECLARE(ell_vec_long, long);
- ELL_VEC_DECLARE(ell_vec_float, float);
- ELL_VEC_DECLARE(ell_vec_double, double);
- #endif
|