/* [ʞ] src/type.h * ~ lexi hale * 🄯 AGPLv3 * ? miscellaneous useful types & macros */ #pragma once #define _strDynSz(a) \ __builtin_choose_expr( \ /* if */ __builtin_types_compatible_p(typeof(a), pstr), \ /* then */ ((pstr*)&(a))->sz, \ /* else */ strlen(*(char const**)&(a))) #define _strDynMem(a) \ __builtin_choose_expr( \ /* if */ __builtin_types_compatible_p(typeof(a), pstr), \ /* then */ ((pstr*)&(a))->v, \ /* else */ *(char**)&(a)) #define _pstrOf(a) ((pstr){.v=_strDynMem(a), .sz=_strDynSz(a)}) #define _array(t) struct {t* v; size_t sz;} typedef _array(char) pstr; #define _pstrLit(a) ((pstr){.v=(a),.sz=sizeof(a)-1}) #define _drop(x) { \ if (x.v) { \ _free (x.v); \ x.v = nullptr; \ x.sz = 0; \ } \ } #define _new(T, n) ((T){ \ .v = _alloc( typeof( *((typeof(T)) {}).v ), n), \ .sz = n, \ }) static inline pstr pstrDup(pstr p) { if (p.v == nullptr) return p; if (p.sz == 0) p.sz = strlen(p.v); auto n = _new(pstr, p.sz + 1); memcpy(n.v, p.v, p.sz); n.v[p.sz] = 0; n.sz = p.sz; return n; }