1 module more.alloc; 2 3 static import core.stdc.stdlib; 4 static import core.stdc..string; 5 6 import std.typecons : Flag, Yes, No; 7 8 T* cmalloc(T)(Flag!"zero" zero = Yes.zero) 9 { 10 void* mem = core.stdc.stdlib.malloc(T.sizeof); 11 assert(mem, "out of memory"); 12 if(zero) 13 { 14 core.stdc..string.memset(mem, 0, T.sizeof); 15 } 16 return cast(T*)mem; 17 } 18 T[] cmallocArray(T)(size_t size, Flag!"zero" zero = Yes.zero) 19 { 20 void* mem = core.stdc.stdlib.malloc(T.sizeof * size); 21 assert(mem, "out of memory"); 22 if(zero) 23 { 24 core.stdc..string.memset(mem, 0, T.sizeof * size); 25 } 26 return (cast(T*)mem)[0..size]; 27 } 28 void cfree(T)(T* mem) 29 { 30 core.stdc.stdlib.free(mem); 31 } 32 33 struct Mem 34 { 35 void* ptr; 36 size_t size; 37 } 38 39 // Always expands the memory to a power of 2 of the initial size. 40 struct GCDoubler(uint initialSize) 41 { 42 private static auto getSize(size_t currentSize, size_t requestedSize) 43 { 44 size_t size = (currentSize == 0) ? initialSize : currentSize * 2; 45 while(requestedSize > size) 46 { 47 size *= 2; 48 } 49 return size; 50 } 51 52 static T[] expand(T)(T[] array, size_t preserveSize, size_t neededSize) 53 in { assert(array.length < neededSize); } body 54 { 55 // TODO: there might be a more efficient way to do this? 56 array.length = getSize(array.length, neededSize); 57 return array; 58 } 59 60 static Mem alloc(Mem current, size_t newRequestedSize) 61 { 62 import core.memory : GC; 63 auto newSize = getSize(current.size, newRequestedSize); 64 return Mem(GC.malloc(newSize), newSize); 65 } 66 static Mem alloc(Mem current, size_t newRequestedSize, size_t copyOffset, size_t copyLimit) 67 { 68 import core.memory : GC; 69 auto newSize = getSize(current.size, newRequestedSize); 70 auto newMem = GC.malloc(newSize); 71 (cast(ubyte*)newMem)[copyOffset..copyLimit] = (cast(ubyte*)current.ptr)[copyOffset..copyLimit]; 72 return Mem(newMem, newSize); 73 } 74 } 75 76 struct MallocDoubler(uint initialSize) 77 { 78 static import core.stdc.stdlib; 79 static import core.stdc..string; 80 81 static T[] expand(T)(T[] array, size_t preserveSize, size_t neededSize) 82 in { assert(array.length < neededSize); } body 83 { 84 size_t newSize = (array.length == 0) ? initialSize : array.length * 2; 85 while(neededSize > newSize) 86 { 87 newSize *= 2; 88 } 89 auto newPtr = cast(T*)core.stdc.stdlib.malloc(T.sizeof*newSize); 90 assert(newPtr, "malloc returned null"); 91 if(preserveSize > 0) 92 { 93 core.stdc..string.memcpy(newPtr, array.ptr, T.sizeof*preserveSize); 94 } 95 if(array.ptr) 96 { 97 core.stdc.stdlib.free(array.ptr); 98 } 99 return newPtr[0..newSize]; 100 } 101 }