AllocatorMode :: enum { using Allocator_Mode; // Compatability Allocate :: ALLOCATE; Resize :: RESIZE; Free :: FREE; Startup :: STARTUP; Shutdown :: SHUTDOWN; ThreadStart :: THREAD_START; ThreadStop :: THREAD_STOP; CreateHeap :: CREATE_HEAP; DestroyHeap :: DESTROY_HEAP; IsThisYours :: IS_THIS_YOURS; Capabilities :: CAPS; } /// PanicAllocator causes the program to panic when used. PanicAllocator :: () -> Allocator { return .{ proc = xx PanicAllocatorProc }; } TrySetAllocator :: (thing: *$T, allocator := context.allocator) #modify { info := T.(*Type_Info_Struct); ok := false; if info.type == .STRUCT { ok = true; } if ok for info.members if it.name == "allocator" && it.type == Allocator.(*Type_Info) { ok = true; break; } return ok, "can only set allocator on struct with an allocator field or dynamic array"; } #expand { if thing.allocator.proc == null { thing.allocator = allocator; } } TrySetAllocator :: (array: *[..]$T, allocator := context.allocator) #expand { if array.allocator.proc == null { array.allocator = allocator; } } #scope_module PanicAllocatorProc :: (mode: AllocatorMode, new_size: int, old_size: int, ptr: *void, allocator_data: *void) -> *void { if mode == { case .Allocate; if new_size > 0 { Panic("jc: allocation using the PanicAllocator"); } case .Resize; if new_size > 0 { Panic("jc: reallocation using the PanicAllocator"); } case .Free; if ptr != null { Panic("jc: free using the PanicAllocator"); } case .ThreadStart; #through; case .ThreadStop; Panic("jc: start/stop thread using the PanicAllocator"); case .CreateHeap; #through; case .DestroyHeap; Panic("jc: create/destroy heap using the PanicAllocator"); } return null; } @jc.nodocs