ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

arc_list.h (1510B)


      1 
      2 #pragma once
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include "utils.h"
      6 
      7 typedef struct ArcList {
      8 	size_t refcount;
      9 	size_t len;
     10 	size_t cap;
     11 	size_t element_size;
     12 	unsigned char* data;
     13 } ArcList;
     14 
     15 static inline ArcList*
     16 arc_list_new(size_t elem_size)
     17 {
     18 	ArcList* l = calloc(1, sizeof(*l));
     19 	if (!l) panic("arc list cannot alloc");
     20 	l->refcount = 1;
     21 	l->len = l->cap = 0;
     22 	l->element_size = elem_size;
     23 	l->data = NULL;
     24 	return l;
     25 }
     26 
     27 static inline void
     28 arc_list_retain(ArcList* l)
     29 {
     30 	if (!l) return;
     31 	l->refcount++;
     32 }
     33 
     34 static inline void
     35 arc_list_release(ArcList* l, void (*elem_release)(void* elem))
     36 {
     37 	if (!l) return;
     38 	if (--l->refcount == 0) {
     39 		if (elem_release) {
     40 			for (size_t i = 0; i < l->len; i++) {
     41 				elem_release(l->data + i * l->element_size);
     42 			}
     43 		}
     44 		free(l->data);
     45 		free(l);
     46 	}
     47 }
     48 
     49 static inline void
     50 arc_list_grow(ArcList* l, size_t min_cap)
     51 {
     52 	size_t new_cap = l->cap ? l->cap * 2 : 16;
     53 	if (new_cap < min_cap) new_cap = min_cap;
     54 	unsigned char* new_data = realloc(l->data, new_cap * l->element_size);
     55 	if (!new_data) panic("arc list grow, could not alloc");
     56 	l->data = new_data;
     57 	l->cap = new_cap;
     58 }
     59 
     60 static inline void
     61 arc_list_push(ArcList* l, const void* elem)
     62 {
     63 	if (l->len == l->cap) { arc_list_grow(l, l->len + 1); }
     64 	memcpy(l->data + l->len * l->element_size, elem, l->element_size);
     65 	l->len++;
     66 }
     67 
     68 static inline void*
     69 arc_list_get(ArcList* l, size_t idx)
     70 {
     71 	if (idx < l->len) { panic("arc_list_get_ptr: fetching array out of bounds"); }
     72 	return l->data + idx * l->element_size;
     73 }