From 6a299d9e7d9c3353394790b8048284a984fdfdc6 Mon Sep 17 00:00:00 2001 From: Mistivia Date: Sun, 28 Dec 2025 19:57:33 +0800 Subject: def as and impl as --- pqueue.h | 80 ++++++++++++++++++++++++++++++++++------------------------------ vec.h | 80 ++++++++++++++++++++++++++++++++++------------------------------ 2 files changed, 84 insertions(+), 76 deletions(-) diff --git a/pqueue.h b/pqueue.h index b9b683d..94ef0fc 100644 --- a/pqueue.h +++ b/pqueue.h @@ -3,17 +3,19 @@ #include "vec.h" -#define PQUEUE_DEF(T) \ +#define PQUEUE_DEF_AS(T, TV, A) \ typedef struct { \ - T##Vector vec; \ - } T##PQueue; \ - void T##PQueue_init(T##PQueue *self); \ - T##PQueue T##PQueue_create(); \ - void T##PQueue_push(T##PQueue *self, T elem); \ - void T##PQueue_pop(T##PQueue *self); \ - T* T##PQueue_top(T##PQueue *self); \ - T##PQueue T##PQueue_move(T##PQueue *self); \ - void T##PQueue_free(T##PQueue *self); \ + TV vec; \ + } A; \ + void A##_init(A *self); \ + A A##_create(); \ + void A##_push(A *self, T elem); \ + void A##_pop(A *self); \ + T* A##_top(A *self); \ + A A##_move(A *self); \ + void A##_free(A *self); + +#define PQUEUE_DEF(T) PQUEUE_DEF_AS(T, T##Vector, T##PQueue) PQUEUE_DEF(Int); PQUEUE_DEF(Bool); @@ -26,60 +28,62 @@ PQUEUE_DEF(Float); PQUEUE_DEF(String); PQUEUE_DEF(VoidPtr); -#define PQUEUE_IMPL(T) \ - static int T##PQueue_cmp(T##PQueue *self, int a, int b) { \ - return T##_cmp(*T##Vector_ref(&self->vec, a), *T##Vector_ref(&self->vec, b)); \ +#define PQUEUE_IMPL_AS(T, TV, A) \ + static int A##_cmp(A *self, int a, int b) { \ + return T##_cmp(*TV##_ref(&self->vec, a), *TV##_ref(&self->vec, b)); \ } \ - void T##PQueue_init(T##PQueue *self) { \ - T##Vector_init(&self->vec); \ + void A##_init(A *self) { \ + TV##_init(&self->vec); \ } \ - T##PQueue T##PQueue_create() { \ - T##PQueue self; \ - T##PQueue_init(&self); \ + A A##_create() { \ + A self; \ + A##_init(&self); \ return self; \ } \ - void T##PQueue_push(T##PQueue *self, T elem) { \ - T##Vector_push_back(&self->vec, elem); \ + void A##_push(A *self, T elem) { \ + TV##_push_back(&self->vec, elem); \ int i = self->vec.size - 1; \ - while (i > 0 && T##PQueue_cmp(self, i, i / 2) > 0) { \ - T##Vector_swap(&self->vec, i, i / 2); \ + while (i > 0 && A##_cmp(self, i, i / 2) > 0) { \ + TV##_swap(&self->vec, i, i / 2); \ i /= 2; \ } \ } \ - static void T##PQueue_heapify(T##PQueue *self, int idx) { \ + static void A##_heapify(A *self, int idx) { \ int left, right, largest; \ left = 2 * idx + 1; \ right = 2 * idx + 2; \ - if (left < self->vec.size && T##PQueue_cmp(self, left, idx) > 0) { \ + if (left < self->vec.size && A##_cmp(self, left, idx) > 0) { \ largest = left; \ } else { \ largest = idx; \ } \ - if (right < self->vec.size && T##PQueue_cmp(self, right, largest) > 0) { \ + if (right < self->vec.size && A##_cmp(self, right, largest) > 0) { \ largest = right; \ } \ if (largest != idx) { \ - T##Vector_swap(&self->vec, largest, idx); \ - T##PQueue_heapify(self, largest); \ + TV##_swap(&self->vec, largest, idx); \ + A##_heapify(self, largest); \ } \ } \ - void T##PQueue_pop(T##PQueue *self) { \ + void A##_pop(A *self) { \ if (self->vec.size == 0) return; \ - memcpy(T##Vector_ref(&self->vec, 0), T##Vector_ref(&self->vec, self->vec.size - 1), sizeof(T)); \ - T##Vector_pop(&self->vec); \ - T##PQueue_heapify(self, 0); \ + memcpy(TV##_ref(&self->vec, 0), TV##_ref(&self->vec, self->vec.size - 1), sizeof(T)); \ + TV##_pop(&self->vec); \ + A##_heapify(self, 0); \ } \ - T* T##PQueue_top(T##PQueue *self) { \ + T* A##_top(A *self) { \ if (self->vec.size == 0) return NULL; \ return self->vec.buffer; \ } \ - T##PQueue T##PQueue_move(T##PQueue *self) { \ - T##PQueue dup; \ - dup.vec = T##Vector_move(&self->vec); \ + A A##_move(A *self) { \ + A dup; \ + dup.vec = TV##_move(&self->vec); \ return dup; \ } \ - void T##PQueue_free(T##PQueue *self) { \ - T##Vector_free(&self->vec); \ - } \ + void A##_free(A *self) { \ + TV##_free(&self->vec); \ + } + +#define PQUEUE_IMPL(T) PQUEUE_IMPL_AS(T, T##Vector, T##PQueue) #endif diff --git a/vec.h b/vec.h index e040936..3273774 100644 --- a/vec.h +++ b/vec.h @@ -7,42 +7,44 @@ #include "type_alias.h" -#define VECTOR_DEF(T) \ +#define VECTOR_DEF_AS(T, A) \ typedef struct { \ T* buffer; \ int size; \ int cap; \ - } T##Vector; \ + } A; \ \ - void T##Vector_init(T##Vector *self); \ - T##Vector T##Vector_create(); \ - void T##Vector_push_back(T##Vector *self, T elem); \ - void T##Vector_insert_before(T##Vector *self, int n, T elem); \ - void T##Vector_pop(T##Vector *self); \ - bool T##Vector_empty(T##Vector *self); \ - void T##Vector_remove(T##Vector *self, size_t n); \ - size_t T##Vector_len(T##Vector *self); \ - T* T##Vector_begin(T##Vector *self); \ - T* T##Vector_last(T##Vector *self); \ - T* T##Vector_end(T##Vector *self); \ - T* T##Vector_ref(T##Vector *self, size_t n); \ - void T##Vector_swap(T##Vector *self, int i, int j); \ - T##Vector T##Vector_move(T##Vector *self); \ - void T##Vector_show(T##Vector self, FILE* fp); \ - void T##Vector_free(T##Vector *self); + void A##_init(A *self); \ + A A##_create(); \ + void A##_push_back(A *self, T elem); \ + void A##_insert_before(A *self, int n, T elem); \ + void A##_pop(A *self); \ + bool A##_empty(A *self); \ + void A##_remove(A *self, size_t n); \ + size_t A##_len(A *self); \ + T* A##_begin(A *self); \ + T* A##_last(A *self); \ + T* A##_end(A *self); \ + T* A##_ref(A *self, size_t n); \ + void A##_swap(A *self, int i, int j); \ + A A##_move(A *self); \ + void A##_show(A self, FILE* fp); \ + void A##_free(A *self); -#define VECTOR_IMPL(T) \ - void T##Vector_init(T##Vector *self) { \ +#define VECTOR_DEF(T) VECTOR_DEF_AS(T, T##Vector) + +#define VECTOR_IMPL_AS(T, A) \ + void A##_init(A *self) { \ self->buffer = (T*)malloc(sizeof(T) * 16); \ self->cap = 16; \ self->size = 0; \ } \ - T##Vector T##Vector_create() { \ - T##Vector self; \ - T##Vector_init(&self); \ + A A##_create() { \ + A self; \ + A##_init(&self); \ return self; \ } \ - void T##Vector_push_back(T##Vector *self, T elem) { \ + void A##_push_back(A *self, T elem) { \ if (self->size + 1 > self->cap) { \ self->buffer = realloc(self->buffer, sizeof(T) * self->cap * 2); \ self->cap *= 2; \ @@ -50,7 +52,7 @@ self->buffer[self->size] = elem; \ self->size += 1; \ } \ - void T##Vector_insert_before(T##Vector *self, int n, T elem) { \ + void A##_insert_before(A *self, int n, T elem) { \ if (n < 0 || n > self->size) { \ return; \ } \ @@ -66,35 +68,35 @@ self->size += 1; \ } \ } \ - void T##Vector_pop(T##Vector *self) { \ + void A##_pop(A *self) { \ self->size -= 1; \ } \ - void T##Vector_remove(T##Vector *self, size_t n) { \ + void A##_remove(A *self, size_t n) { \ if (n < 0 || n >= self->size) return; \ memmove(self->buffer + n, \ self->buffer + n + 1, \ sizeof(T) * self->size - n - 1); \ self->size -= 1; \ } \ - T* T##Vector_begin(T##Vector *self) { return self->buffer; } \ - bool T##Vector_empty(T##Vector *self) { return self->size == 0; } \ - T* T##Vector_end(T##Vector *self) { return self->buffer + self->size; } \ - T* T##Vector_last(T##Vector *self) { return self->buffer + self->size - 1; } \ - T* T##Vector_ref(T##Vector *self, size_t n) { return self->buffer + n; } \ - void T##Vector_swap(T##Vector *self, int i, int j) { \ + T* A##_begin(A *self) { return self->buffer; } \ + bool A##_empty(A *self) { return self->size == 0; } \ + T* A##_end(A *self) { return self->buffer + self->size; } \ + T* A##_last(A *self) { return self->buffer + self->size - 1; } \ + T* A##_ref(A *self, size_t n) { return self->buffer + n; } \ + void A##_swap(A *self, int i, int j) { \ T buf; \ memcpy(&buf, self->buffer + i, sizeof(T)); \ memcpy(self->buffer + i, self->buffer + j, sizeof(T)); \ memcpy(self->buffer + j, &buf, sizeof(T)); \ } \ - T##Vector T##Vector_move(T##Vector *self) { \ - T##Vector dup = *self; \ + A A##_move(A *self) { \ + A dup = *self; \ self->buffer = NULL; \ self->size = 0; \ self->cap = 0; \ return dup; \ } \ - void T##Vector_show(T##Vector self, FILE* fp) { \ + void A##_show(A self, FILE* fp) { \ fprintf(fp, "["); \ for (int i = 0; i < self.size-1; i++) { \ T##_show(self.buffer[i], fp); \ @@ -105,8 +107,10 @@ } \ fprintf(fp, "]"); \ } \ - size_t T##Vector_len(T##Vector *self) { return self->size; } \ - void T##Vector_free(T##Vector *self) { free(self->buffer); } + size_t A##_len(A *self) { return self->size; } \ + void A##_free(A *self) { free(self->buffer); } + +#define VECTOR_IMPL(T) VECTOR_IMPL_AS(T, T##Vector) VECTOR_DEF(Int); VECTOR_DEF(Bool); -- cgit v1.0