thisistherk / fast_obj

Fast C OBJ parser
MIT License
636 stars 47 forks source link

Proposal: allow setting memory functions through callbacks (in addition to macros) #49

Open laurelkeys opened 1 month ago

laurelkeys commented 1 month ago

Passing a function pointer to the library gives greater flexibility than through the #defines for FAST_OBJ_REALLOC/_FREE, as it's a choice that can be made (and changed) at runtime.

This PR adds a new (optional) fast_obj_set_memory_functions API for that, to set three new global variables in the FAST_OBJ_IMPLEMENTATION:

static fastObjRealloc memory_realloc = default_memory_realloc;
static fastObjFree memory_dealloc = default_memory_dealloc;
static void* memory_context = 0;

By default, these will fallback to calling FAST_OBJ_REALLOC and FAST_OBJ_FREE, so this is not a breaking change (I have still bumped the version to 1.4).

The two typedefs -- fastObjRealloc and fastObjFree -- take a void* context which allows for passing user data to the memory functions. Also, realloc takes both the new size and old size, to avoid the need of externally keeping track of allocation sizes. I'd meant to do the same for the dealloc function (see https://nullprogram.com/blog/2023/12/17/), but ended up deciding against it as the majority of users will continue to use libc's free, thus leading to unnecessary strlen computations.


For context: the motivation behind this is that it will make it easier/cleaner to integrate fast_obj with arena allocators (where fastObjFree is usually a no-op). If this isn't deemed useful in the general case, feel free not to accept the PR 🙂