diff options
Diffstat (limited to 'example_vec/old')
-rw-r--r-- | example_vec/old/conts.h | 22 | ||||
-rw-r--r-- | example_vec/old/main.c | 32 | ||||
-rw-r--r-- | example_vec/old/vec.h | 139 |
3 files changed, 193 insertions, 0 deletions
diff --git a/example_vec/old/conts.h b/example_vec/old/conts.h new file mode 100644 index 0000000..d175d30 --- /dev/null +++ b/example_vec/old/conts.h @@ -0,0 +1,22 @@ +#ifndef CONTS_H +#define CONTS_H + +#define CONTS_JOIN2(a, b) a##_##b +#define CONTS_JOIN(a, b) CONTS_JOIN2(a, b) + +#define CONTAINER_OF(ptr, type, member) \ + (type *)((char *)(ptr) - offsetof(type, member)) + +#if __STDC_VERSION__ >= 202311UL +# define CONTS_AUTO auto +#elif defined(__GNUC__) +# define CONTS_AUTO __auto_type +#else +# warning "iteration won't work with this compiler" +#endif + +#define foreach(name, i, s)\ + for (CONTS_AUTO i = CONTS_JOIN(name, begin)(s);\ + !CONTS_JOIN(name, end)(s, i);\ + i = CONTS_JOIN(name, next)(i)) +#endif /* CONTS_H */ diff --git a/example_vec/old/main.c b/example_vec/old/main.c new file mode 100644 index 0000000..a84096c --- /dev/null +++ b/example_vec/old/main.c @@ -0,0 +1,32 @@ +#include <assert.h> + +#define VEC_TYPE int +#define VEC_NAME ints +#include <conts/vec.h> + +int main() +{ + struct ints ints = ints_create(0); + for (int i = 0; i < 1000000; ++i) { + ints_append(&ints, i); + } + assert(ints_len(&ints) == 1000000); + + for (int i = 0; i < 1000000; ++i) { + int *v = ints_at(&ints, i); + assert(v && *v == i); + } + + int i = 0; + foreach(ints, iter, &ints) { + assert(iter && *iter == i); + i++; + } + + for (int i = 1000000 - 1; i >= 0; --i) { + ints_remove(&ints, i); + } + assert(ints_len(&ints) == 0); + + ints_destroy(&ints); +} diff --git a/example_vec/old/vec.h b/example_vec/old/vec.h new file mode 100644 index 0000000..19fd18f --- /dev/null +++ b/example_vec/old/vec.h @@ -0,0 +1,139 @@ +#ifndef VEC_TYPE +#error "Need vector type" +#endif + +#ifndef VEC_NAME +#error "Need vector name" +#endif + +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +#include "conts.h" + +#define VEC(a) CONTS_JOIN(VEC_NAME, a) + +#define VEC_STRUCT VEC_NAME +struct VEC_STRUCT { + size_t n; + size_t s; + VEC_TYPE *buf; +}; + +static inline struct VEC_STRUCT VEC(create)(size_t reserve) +{ + if (reserve == 0) + return (struct VEC_STRUCT) {.n = 0, .s = 0, .buf = NULL}; + + return (struct VEC_STRUCT) { + .n = 0, + .s = reserve, + .buf = malloc(reserve * sizeof(VEC_TYPE)), + }; +} + +static inline bool VEC(uninit)(struct VEC_STRUCT *v) +{ + return v->buf == NULL; +} + +static inline size_t VEC(len)(struct VEC_STRUCT *v) +{ + return v->n; +} + +static inline VEC_TYPE *VEC(at)(struct VEC_STRUCT *v, size_t i) +{ + assert(i < v->n && "out of vector bounds"); + return &v->buf[i]; +} + +static inline VEC_TYPE *VEC(back)(struct VEC_STRUCT *v) +{ + assert(v->n); + return &v->buf[v->n - 1]; +} + +static inline VEC_TYPE *VEC(pop)(struct VEC_STRUCT *v) +{ + assert(v->n && "attempting to pop empty vector"); + v->n--; + return &v->buf[v->n]; +} + +static inline void VEC(append)(struct VEC_STRUCT *v, VEC_TYPE n) +{ + v->n++; + if (v->n >= v->s) { + v->s = v->s == 0 ? 1 : 2 * v->s; + v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE)); + } + + v->buf[v->n - 1] = n; +} + +static inline void VEC(reset)(struct VEC_STRUCT *v) +{ + v->n = 0; +} + +static inline void VEC(destroy)(struct VEC_STRUCT *v) { + free(v->buf); +} + +typedef int (*VEC(comp_t))(VEC_TYPE *a, VEC_TYPE *b); +static inline void VEC(sort)(struct VEC_STRUCT *v, VEC(comp_t) comp) +{ + qsort(v->buf, v->n, sizeof(VEC_TYPE), (__compar_fn_t)comp); +} + +static inline void VEC(reserve)(struct VEC_STRUCT *v, size_t n) +{ + if (v->n >= n) + return; + + v->n = n; + if (v->s >= v->n) + return; + + while (v->s < v->n) + v->s = v->s == 0 ? 1 : 2 * v->s; + + v->buf = realloc(v->buf, v->s * sizeof(VEC_TYPE)); +} + +static inline void VEC(shrink)(struct VEC_STRUCT *v, size_t n) +{ + assert(v->n >= n); + v->n = n; +} + +static inline void VEC(remove)(struct VEC_STRUCT *v, size_t i) +{ + assert(v->n > i); + size_t c = sizeof(VEC_TYPE) * (v->n - i); + memcpy(&v->buf[i], &v->buf[i + 1], c); + v->n--; +} + +static inline VEC_TYPE *VEC(begin)(struct VEC_STRUCT *v) +{ + return &v->buf[0]; +} + +static inline bool VEC(end)(struct VEC_STRUCT *v, VEC_TYPE *i) +{ + return &v->buf[v->n] == i; +} + +static inline VEC_TYPE *VEC(next)(VEC_TYPE *i) +{ + return i + 1; +} + +#undef VEC +#undef VEC_TYPE +#undef VEC_NAME +#undef VEC_STRUCT |