1 module jive.internal; 2 3 /** 4 * For internal use in the other modules of jive. 5 */ 6 7 import core.exception : onOutOfMemoryError; 8 import core.memory : GC; 9 import std.functional : binaryFun; 10 //import std.typecons; 11 //import std.typetuple; 12 import std.traits : hasIndirections; 13 14 private extern(C) 15 { 16 // TODO: switch to core.memory.pureMalloc/pureFree when https://github.com/dlang/druntime/pull/1836 is resolved 17 void* malloc(size_t) @system pure @nogc nothrow; 18 void free(void*) @system pure @nogc nothrow; 19 } 20 21 /** 22 * Wrappers around malloc/free that 23 * - cast to appropriate type 24 * - call GC.addRange/removeRange when neccessary 25 */ 26 T* jiveMalloc(T)(size_t n) @trusted /*pure*/ @nogc nothrow 27 { 28 if(n == 0) 29 return null; 30 auto ptr = cast(T*)malloc(T.sizeof * n); 31 if(ptr is null) 32 onOutOfMemoryError(); 33 static if(hasIndirections!T) 34 GC.addRange(ptr, T.sizeof * n); 35 return ptr; 36 } 37 38 void jiveFree(T)(T* ptr) @trusted /*pure*/ @nogc nothrow 39 { 40 if(ptr is null) 41 return; 42 static if(hasIndirections!T) 43 GC.removeRange(ptr); 44 free(ptr); 45 } 46 47 /** 48 * Workaround to make somewhat nice out-of-bounds errors in @nogc code. 49 * TODO: remove when DIP1008 is implemented which should make a simple 50 * 'throw new RangeError(file, line)' work even in @nogc code. 51 */ 52 template boundsCheckMsg(string file, int line) 53 { 54 import std.format : format; 55 static immutable string boundsCheckMsg = format("Array out-of-bounds at %s(%s)", file, line); 56 } 57 58 version(D_NoBoundsChecks) 59 enum boundsChecks = false; 60 else 61 enum boundsChecks = true; 62 63 template PredicateHelper(alias p, V) 64 { 65 static if(__traits(compiles, binaryFun!p(V.init, V.init))) 66 { 67 enum dynamicPred = false; 68 alias pred = binaryFun!p; 69 } 70 else static if(__traits(compiles, p.init(V.init, V.init))) 71 { 72 enum dynamicPred = true; 73 p pred; 74 } 75 else 76 { 77 enum dynamicPred = false; // for better error messasge 78 79 static assert(false, "invalid predicate: "~p.stringof); 80 } 81 } 82 83 size_t roundToPowerOfTwo(size_t x) pure 84 { 85 size_t y = 1; 86 while(y < x) 87 y *= 2; 88 return y; 89 }