diff options
| author | Thomas Voss <mail@thomasvoss.com> | 2024-10-03 00:36:26 +0200 | 
|---|---|---|
| committer | Thomas Voss <mail@thomasvoss.com> | 2024-10-03 00:36:26 +0200 | 
| commit | d874d01e8e9a30f0073a6e559cbae07244dec7bf (patch) | |
| tree | dbde18d7ada337b74fe6cfb8ccc35b52008e6aa0 /include | |
| parent | 1e721a413f1d4fc7f7f4e1e691a0a37168f3b302 (diff) | |
Huge library overhaul
Diffstat (limited to 'include')
| -rw-r--r-- | include/_alloc_fn.h | 7 | ||||
| -rw-r--r-- | include/_allocator.h | 22 | ||||
| -rw-r--r-- | include/alloc.h | 125 | ||||
| -rw-r--r-- | include/array.h | 63 | ||||
| -rw-r--r-- | include/dynarr.h | 81 | ||||
| -rw-r--r-- | include/unicode/string.h | 51 | 
6 files changed, 186 insertions, 163 deletions
| diff --git a/include/_alloc_fn.h b/include/_alloc_fn.h deleted file mode 100644 index aae4bd0..0000000 --- a/include/_alloc_fn.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef MLIB__ALLOC_FN_H -#define MLIB__ALLOC_FN_H - -typedef void *(*alloc_fn)(void *ctx, void *ptr, size_t old, size_t new, -                          size_t elemsz, size_t align); - -#endif /* !MLIB__ALLOC_FN_H */ diff --git a/include/_allocator.h b/include/_allocator.h new file mode 100644 index 0000000..3bd78b2 --- /dev/null +++ b/include/_allocator.h @@ -0,0 +1,22 @@ +#ifndef MLIB__ALLOCATOR_H +#define MLIB__ALLOCATOR_H + +#include <setjmp.h> +#include <stddef.h> + +typedef enum { +	ALLOC_NEW, +	ALLOC_RESIZE, +	ALLOC_FREE, +	ALLOC_FREEALL, +} alloc_mode_t; + +typedef struct allocator { +	void *(*alloc)(struct allocator mem, alloc_mode_t mode, void *ptr, +		ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz, +		ptrdiff_t align); +	jmp_buf *err; +	void    *ctx; +} allocator_t; + +#endif /* !MLIB__ALLOCATOR_H */ diff --git a/include/alloc.h b/include/alloc.h index 8004cd0..2786757 100644 --- a/include/alloc.h +++ b/include/alloc.h @@ -1,60 +1,95 @@  #ifndef MLIB_ALLOC_H  #define MLIB_ALLOC_H -#include <setjmp.h> -#include <stddef.h> - +#include "_allocator.h"  #include "_attrs.h" -#ifndef MLIB_ARENA_BLKSIZE -#	define MLIB_ARENA_BLKSIZE (8 * 1024) -#endif +typedef enum { +	ALLOC_OOM, +} alloc_err_t; + +typedef struct arena_blk arena_blk_t; -struct _region { -	size_t len, cap; -	void *data, *last; -	struct _region *next; -}; +typedef struct { +	ptrdiff_t blksz; +	struct arena_blk *_head; +} arena_ctx_t;  typedef struct { -	struct _region *_head; -	size_t _init; -} arena; +	void     *buf; +	ptrdiff_t len; +} st_buf_t; -/* Heap allocation functions */ -[[nodiscard, gnu::returns_nonnull]] void *bufalloc(void *, size_t, size_t); -[[nodiscard]] void *bufalloc_noterm(void *, size_t, size_t); +#define new(mem, T, n)                                                          \ +	((typeof(T) *)((mem).alloc((mem),                                           \ +		ALLOC_NEW,                                                              \ +		nullptr,                                                                \ +		0,                                                                      \ +		(n),                                                                    \ +		sizeof(T),                                                              \ +		alignof(T)))) +#define resz(mem, p, o, n)                                                      \ +	((typeof(p))((mem).alloc((mem),                                             \ +		ALLOC_RESIZE,                                                           \ +		(p),                                                                    \ +		(o),                                                                    \ +		(n),                                                                    \ +		sizeof(*(p)),                                                           \ +		alignof(typeof(*(p)))))) +#define delete(mem, p, sz)                                                      \ +	(mem).alloc((mem),                                                          \ +		ALLOC_FREE,                                                             \ +		(p),                                                                    \ +		(sz),                                                                   \ +		0,                                                                      \ +		sizeof(*(p)),                                                           \ +		alignof(typeof(*p))) +#define deleteall(mem)                                                          \ +	((mem).alloc((mem),                                                         \ +		ALLOC_FREEALL,                                                          \ +		nullptr,                                                                \ +		0,                                                                      \ +		0,                                                                      \ +		0,                                                                      \ +		0)) -[[_mlib_pure, _mlib_inline]] -static inline arena -mkarena(size_t n) +void *arena_alloc(allocator_t mem, alloc_mode_t mode, void *ptr, +				  ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz, +				  ptrdiff_t align); +void *heap_alloc(allocator_t mem, alloc_mode_t mode, void *ptr, +				 ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz, +				 ptrdiff_t align); +void *static_scratch_alloc(allocator_t mem, alloc_mode_t mode, void *ptr, +						   ptrdiff_t oldnmemb, ptrdiff_t newnmemb, ptrdiff_t elemsz, +						   ptrdiff_t align); + +[[_mlib_inline]] static inline allocator_t +init_arena_allocator(arena_ctx_t *ctx, jmp_buf *jmp)  { -	return (arena){._init = n ? n : MLIB_ARENA_BLKSIZE}; +	return (allocator_t){ +		.alloc = arena_alloc,	 +		.err = jmp, +		.ctx = ctx, +	};  } -/* Arena allocation functions */ -[[nodiscard, gnu::malloc, gnu::alloc_size(2, 3), gnu::alloc_align(4)]] -void *arena_alloc(arena *, size_t, size_t, size_t); -[[nodiscard]] -void *arena_realloc(arena *, void *, size_t, size_t, size_t, size_t); -void arena_zero(arena *); -void arena_free(arena *); - -/* Arena allocation macro wrappers */ -#define arena_new(a, T, n) ((T *)arena_alloc((a), (n), sizeof(T), alignof(T))) -#define arena_resz(a, T, p, n)                                                 \ -	((T *)arena_realloc((a), (p), (n), sizeof(T), alignof(T))) - -/* Memory allocator callbacks for memory-allocating functions */ -struct arena_ctx { -	arena *a; -	jmp_buf *jmp; -}; -struct heap_ctx { -	jmp_buf *jmp; -}; - -[[nodiscard]] void *alloc_arena(void *, void *, size_t, size_t, size_t, size_t); -[[nodiscard]] void *alloc_heap(void *, void *, size_t, size_t, size_t, size_t); +[[_mlib_inline]] static inline allocator_t +init_heap_allocator(jmp_buf *jmp) +{ +	return (allocator_t){ +		.alloc = heap_alloc, +		.err = jmp, +	}; +} + +[[_mlib_inline]] static inline allocator_t +init_static_scratch_allocator(st_buf_t *ctx, jmp_buf *jmp) +{ +	return (allocator_t){ +		.alloc = static_scratch_alloc, +		.err = jmp, +		.ctx = ctx, +	}; +}  #endif /* !MLIB_ALLOC_H */ diff --git a/include/array.h b/include/array.h new file mode 100644 index 0000000..de45a65 --- /dev/null +++ b/include/array.h @@ -0,0 +1,63 @@ +#ifndef MLIB_ARRAY_H +#define MLIB_ARRAY_H + +#include <stddef.h> +#include <string.h> + +#include "_allocator.h" +#include "_attrs.h" + +typedef struct { +	ptrdiff_t len, cap; +	allocator_t mem; +} _mlib_arr_hdr_t; + +[[_mlib_inline]] +static inline _mlib_arr_hdr_t * +_mlib_array_hdr(void *p, ptrdiff_t align) +{ +	ptrdiff_t pad = -sizeof(_mlib_arr_hdr_t) & (align - 1); +	return (_mlib_arr_hdr_t *)((char *)p - pad - sizeof(_mlib_arr_hdr_t)); +} + +#define array_hdr(p) (_mlib_array_hdr(p, alignof(typeof(*(p))))) +#define array_len(p) (_mlib_array_hdr(p, alignof(typeof(*(p))))->len) +#define array_cap(p) (_mlib_array_hdr(p, alignof(typeof(*(p))))->cap) + +#define array_new(mem, T, n)                                                    \ +	((T *)array_new((mem), (n), sizeof(T), alignof(T))) +#define array_resz(p, cap)                                                      \ +	((typeof(p))array_resz((p), (cap), sizeof(*(p)), alignof(typeof(*(p))))) +#define array_free(p)                                                           \ +	array_free((p), sizeof(*(p)), alignof(typeof(*(p)))) + +#define array_push(p, x)                                                        \ +	do {                                                                        \ +		_mlib_arr_hdr_t *hdr = _mlib_array_hdr(*(p), alignof(typeof(**(p))));   \ +		if (hdr->len == hdr->cap) {                                             \ +			*(p) = array_resz(*(p), hdr->len * 2);                              \ +			hdr = _mlib_array_hdr(*(p), alignof(typeof(**(p))));                \ +		}                                                                       \ +		(*(p))[hdr->len++] = (x);                                               \ +	} while (false) + +/* TODO: Make the resizing not bad */ +#define array_extend(p, xs, n)                                                  \ +	do {                                                                        \ +		_mlib_arr_hdr_t *hdr = _mlib_array_hdr((p), alignof(typeof(*(p))));     \ +		if (hdr->len + (n) <= hdr->cap) {                                       \ +			(p) = array_resz((p), hdr->len * 2 + (n));                          \ +			hdr = _mlib_array_hdr((p), alignof(typeof(*(p))));                  \ +		}                                                                       \ +		memcpy(&(p)[hdr->len], (xs), (n) * sizeof(*xs));                        \ +		hdr->len += (n);                                                        \ +	} while (false) + +#define array_foreach(p, i) for (typeof(p) i = (p); i < (p) + array_len(p); i++) +	 +void *(array_new)(allocator_t mem, ptrdiff_t nmemb, ptrdiff_t elemsz, +	ptrdiff_t align); +void *(array_resz)(void *ptr, ptrdiff_t ncap, ptrdiff_t elemsz, ptrdiff_t align); +void (array_free)(void *ptr, ptrdiff_t elemsz, ptrdiff_t align); + +#endif /* !MLIB_ARRAY_H */ diff --git a/include/dynarr.h b/include/dynarr.h deleted file mode 100644 index 75bdcc8..0000000 --- a/include/dynarr.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef MLIB_DYNARR_H -#define MLIB_DYNARR_H - -#include <stdbit.h> -#include <string.h> - -#include "_alloc_fn.h" -#include "alloc.h" - -/* This is required because alignof() only portably works with types and not -   expressions… */ -/* clang-format off */ -#ifdef __GNUC__ -#	define _mlib_da_alignof(expr) __extension__ alignof(expr) -#else -#	include <stddef.h> -#	define _mlib_da_alignof(expr) \ -		((size_t) &((struct {char x; typeof(expr) y;} *)0)->y) -#endif -/* clang-format on */ - -#define dafields(T)                                                            \ -	T *buf;                                                                    \ -	size_t len, cap;                                                           \ -	alloc_fn alloc;                                                            \ -	void *ctx - -#define dynarr(T)                                                              \ -	struct {                                                                   \ -		dafields(T);                                                           \ -	} - -#define DAPUSH(da, x)                                                          \ -	do {                                                                       \ -		if (++(da)->len > (da)->cap) {                                         \ -			size_t ncap = stdc_bit_ceil((da)->len);                            \ -			(da)->buf = (da)->alloc((da)->ctx, (da)->buf, (da)->cap, ncap,     \ -			                        sizeof(*(da)->buf),                        \ -			                        _mlib_da_alignof(*(da)->buf));             \ -			(da)->cap = ncap;                                                  \ -		}                                                                      \ -		(da)->buf[(da)->len - 1] = (x);                                        \ -	} while (false) - -#define DAEXTEND(da, xs, n)                                                    \ -	do {                                                                       \ -		if (((da)->len += (n)) > (da)->cap) {                                  \ -			size_t ncap = stdc_bit_ceil((da)->len);                            \ -			(da)->buf = (da)->alloc((da)->ctx, (da)->buf, (da)->cap, ncap,     \ -			                        sizeof(*(da)->buf),                        \ -			                        _mlib_da_alignof(*(da)->buf));             \ -			(da)->cap = ncap;                                                  \ -		}                                                                      \ -		memcpy((da)->buf + (da)->len - (n), (xs), (n) * sizeof(*(da)->buf));   \ -	} while (false) - -#define DAGROW(da, n)                                                          \ -	do {                                                                       \ -		if ((n) > (da)->cap) {                                                 \ -			(da)->buf = (da)->alloc((da)->ctx, (da)->buf, (da)->cap, (n),      \ -			                        sizeof(*(da)->buf),                        \ -			                        _mlib_da_alignof(*(da)->buf));             \ -			(da)->cap = (n);                                                   \ -		}                                                                      \ -	} while (false) - -#define DAPOP(da) ((da)->buf[--(da)->len]) - -#define DAREMOVE(da, i) DA_REMOVE_RANGE((da), (i), (i) + 1) - -#define DA_REMOVE_RANGE(da, i, j)                                              \ -	do {                                                                       \ -		memmove((da)->buf + (i), (da)->buf + (j),                              \ -		        ((da)->len - (j)) * sizeof(*(da)->buf));                       \ -		(da)->len -= j - i;                                                    \ -	} while (false) - -#define da_foreach(da, p)                                                      \ -	for (auto p = (da).buf; (size_t)(p - (da).buf) < (da).len; p++) - -#endif /* !MLIB_DYNARR_H */ diff --git a/include/unicode/string.h b/include/unicode/string.h index 7d62171..077a45a 100644 --- a/include/unicode/string.h +++ b/include/unicode/string.h @@ -3,22 +3,22 @@  #include <stddef.h> -#include "_alloc_fn.h" +#include "_allocator.h"  #include "_charN_t.h"  #include "_uNview.h"  /* clang-format off */ -enum [[clang::flag_enum]] caseflags { +typedef enum [[clang::flag_enum]] {  	CF_LANG_AZ = 1 << 0, /* Azeri; alias for CF_LANG_TR */  	CF_LANG_TR = 1 << 0, /* Turkish; alias for CF_LANG_AZ */  	CF_LANG_LT = 1 << 1, /* Lithuanian */  	CF_LANG_NL = 1 << 2, /* Dutch */  	CF_SS      = 1 << 3, /* Use ‘ẞ’ as the uppercase of ‘ß’; alias for CF_ẞ */  	CF_ẞ       = 1 << 3, /* Use ‘ẞ’ as the uppercase of ‘ß’; alias for CF_SS */ -}; +} caseflags_t; -enum normform { +typedef enum {  	/* If bit 0 is set, then composition is performed after decomposition.  If  	   bit-1 is set then compatibility (de)composition is used as opposed to  	   canonical (de)composition. */ @@ -26,7 +26,7 @@ enum normform {  	NF_NFC  = 0b01,  	NF_NFKD = 0b10,  	NF_NFKC = 0b11, -}; +} normform_t;  /* clang-format on */ @@ -37,16 +37,11 @@ enum normform {  size_t u8gnext(u8view_t *, u8view_t *);  size_t u8wnext(u8view_t *, u8view_t *);  size_t u8wnext_human(u8view_t *, u8view_t *); -[[nodiscard]] char8_t *u8casefold(size_t *, u8view_t, enum caseflags, -                                  alloc_fn, void *); -[[nodiscard]] char8_t *u8lower(size_t *, u8view_t, enum caseflags, -                               alloc_fn, void *); -[[nodiscard]] char8_t *u8title(size_t *, u8view_t, enum caseflags, -                               alloc_fn, void *); -[[nodiscard]] char8_t *u8upper(size_t *, u8view_t, enum caseflags, -                               alloc_fn, void *); -[[nodiscard]] char8_t *u8norm(size_t *, u8view_t, alloc_fn, void *, -                              enum normform); +[[nodiscard]] char8_t *u8casefold(size_t *, u8view_t, caseflags_t, allocator_t); +[[nodiscard]] char8_t *u8lower(size_t *, u8view_t, caseflags_t, allocator_t); +[[nodiscard]] char8_t *u8title(size_t *, u8view_t, caseflags_t, allocator_t); +[[nodiscard]] char8_t *u8upper(size_t *, u8view_t, caseflags_t, allocator_t); +[[nodiscard]] char8_t *u8norm(size_t *, u8view_t, allocator_t, normform_t);  /* Encoding-generic macros */  #define ucswdth(sv, ts)   _Generic((sv), u8view_t: u8wdth)((sv), (ts)) @@ -55,22 +50,18 @@ size_t u8wnext_human(u8view_t *, u8view_t *);  #define ucswcnt_human(sv) _Generic((sv), u8view_t: u8wcnt_human)((sv))  #define ucsgnext(g, sv)   _Generic((sv), u8view_t *: u8gnext)((g), (sv))  #define ucswnext(g, sv)   _Generic((sv), u8view_t *: u8wnext)((g), (sv)) -#define ucswnext_human(g, sv)                                                  \ +#define ucswnext_human(g, sv) \  	_Generic((sv), u8view_t *: u8wnext_human)((g), (sv)) -#define ucscasefold(dstn, sv, flags, alloc, ctx)                               \ -	_Generic((sv), u8view_t: u8casefold)((dstn), (sv), (flags), (alloc),  \ -	                                          (ctx)) -#define ucslower(dstn, sv, flags, alloc, ctx)                                  \ -	_Generic((sv), u8view_t: u8lower)((dstn), (sv), (flags), (alloc),     \ -	                                       (ctx)) -#define ucstitle(dstn, sv, flags, alloc, ctx)                                  \ -	_Generic((sv), u8view_t: u8title)((dstn), (sv), (flags), (alloc),     \ -	                                       (ctx)) -#define ucsupper(dstn, sv, flags, alloc, ctx)                                  \ -	_Generic((sv), u8view_t: u8upper)((dstn), (sv), (flags), (alloc),     \ -	                                       (ctx)) -#define ucsnorm(dstn, sv, alloc, ctx, nf)                                      \ -	_Generic((sv), u8view_t: u8norm)((dstn), (sv), (alloc), (ctx), (nf)) +#define ucscasefold(dstn, sv, flags, mem) \ +	_Generic((sv), u8view_t: u8casefold)((dstn), (sv), (flags), (mem)) +#define ucslower(dstn, sv, flags, mem) \ +	_Generic((sv), u8view_t: u8lower)((dstn), (sv), (flags), (mem)) +#define ucstitle(dstn, sv, flags, mem) \ +	_Generic((sv), u8view_t: u8title)((dstn), (sv), (flags), (mem)) +#define ucsupper(dstn, sv, flags, mem) \ +	_Generic((sv), u8view_t: u8upper)((dstn), (sv), (flags), (mem)) +#define ucsnorm(dstn, sv, mem, nf) \ +	_Generic((sv), u8view_t: u8norm)((dstn), (sv), (mem), (nf))  constexpr double U8CASEFOLD_SCALE = 3;  constexpr double U8LOWER_SCALE = 1.5; |