#include #include typedef struct arena_s Arena; struct arena_s { unsigned char *tape; unsigned int count; unsigned int capacity; }; void *aalloc(Arena *arena, unsigned int size){ unsigned int pos; if(arena == NULL) return NULL; if(arena->count + size > arena->capacity) return NULL; pos = arena->count; arena->count += size; return (void *)&arena->tape[pos]; } unsigned int scpy(char *to, const char *from, unsigned int length) { unsigned int i; if(to == NULL || from == NULL) return -1; if(length == 0) return 0; for(i = 0; i < length - 1 && from[i] != '\0'; i++) to[i] = from[i]; to[i] = '\0'; return 0; } char * ascpy(Arena *arena, const char *start, unsigned int length) { char *str; if(!start) return NULL; str = (char *)aalloc(arena, length + 1); if(!str) return NULL; scpy(str, start, length); return str; } void * areturn(Arena *arena, unsigned int checkpoint, const void *src, unsigned int size) { void *dest; if(arena == NULL || src == NULL) return NULL; dest = (void *)&arena->tape[checkpoint]; if (src == dest) return dest; memmove(dest, src, size); arena->count = checkpoint + size; return dest; } #define ARENA_RETURN(arena, ckpt, src_ptr, type) \ return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type)) #define ARENA_RETURN_ARRAY(arena, ckpt, src_ptr, type, count) \ return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type) * (count)) typedef struct Point Point; struct Point { unsigned int x; unsigned int y; }; Point * Point_new(Arena *a, unsigned int x, unsigned int y) { Point *this = (Point *)aalloc(a, sizeof(Point)); this->x = x; this->y = y; return this; } char* Point_toS(Arena *a, Point *this) { unsigned int ckpt = a->count; char *s = (char*)&a->tape[a->count]; int len = sprintf(s, "[x:%d, y:%d]", this->x, this->y); s[len] = '\0'; a->count += len + 1; ARENA_RETURN_ARRAY(a, ckpt, s, char, len + 1); } typedef struct Rect Rect; struct Rect { Point top_left; Point bottom_right; unsigned int width; unsigned int height; }; Rect * Rect_new(Arena *a, Point *tl, Point *br, unsigned int width, unsigned int height) { Rect *this = (Rect *)aalloc(a, sizeof(Rect)); memcpy(&this->top_left, tl, sizeof(Point)); memcpy(&this->bottom_right, br, sizeof(Point)); this->width = width; this->height = height; return this; } char* Rect_toS(Arena *a, Rect *this) { unsigned int ckpt = a->count; char *s1 = Point_toS(a, &this->top_left); char *s2 = Point_toS(a, &this->bottom_right); char *s = (char*)&a->tape[a->count]; int len = sprintf(s, "[top_left: %s, bottom_right: %s, width:%d, height:%d]", s1, s2, this->width, this->height); s[len] = '\0'; a->count += len + 1; ARENA_RETURN_ARRAY(a, ckpt, s, char, len + 1); } Rect * create_geometry(Arena *a) { unsigned int ckpt = a->count; Rect *final_rect; Point *temp_tl; Point *temp_br; temp_tl = Point_new(a, 10, 20); temp_br = Point_new(a, 100, 200); final_rect = Rect_new(a, temp_tl, temp_br, 90, 180); ARENA_RETURN(a, ckpt, final_rect, Rect); } int main() { unsigned char tape[64000]; Arena a = {tape, 0, 64000}; Rect *r = create_geometry(&a); printf("%s\n", Rect_toS(&a, r)); return 0; }