1 module std.internal.memory; 2 3 package(std): 4 5 version (D_Exceptions) 6 { 7 import core.exception : onOutOfMemoryError; 8 private enum allocationFailed = `onOutOfMemoryError();`; 9 } 10 else 11 { 12 private enum allocationFailed = `assert(0, "Memory allocation failed");`; 13 } 14 15 // (below comments are non-DDOC, but are written in similar style) 16 17 /+ 18 Mnemonic for `enforce!OutOfMemoryError(malloc(size))` that (unlike malloc) 19 can be considered pure because it causes the program to abort if the result 20 of the allocation is null, with the consequence that errno will not be 21 visibly changed by calling this function. Note that `malloc` can also 22 return `null` in non-failure situations if given an argument of 0. Hence, 23 it is a programmer error to use this function if the requested allocation 24 size is logically permitted to be zero. `enforceCalloc` and `enforceRealloc` 25 work analogously. 26 27 All these functions are usable in `betterC`. 28 +/ 29 void* enforceMalloc()(size_t size) @nogc nothrow pure @safe 30 { 31 auto result = fakePureMalloc(size); 32 if (!result) mixin(allocationFailed); 33 return result; 34 } 35 36 // ditto 37 void* enforceCalloc()(size_t nmemb, size_t size) @nogc nothrow pure @safe 38 { 39 auto result = fakePureCalloc(nmemb, size); 40 if (!result) mixin(allocationFailed); 41 return result; 42 } 43 44 // ditto 45 void* enforceRealloc()(return scope void* ptr, size_t size) @nogc nothrow pure @system 46 { 47 auto result = fakePureRealloc(ptr, size); 48 if (!result) mixin(allocationFailed); 49 return result; 50 } 51 52 // Purified for local use only. 53 extern (C) @nogc nothrow pure private 54 { 55 pragma(mangle, "malloc") void* fakePureMalloc(size_t) @safe; 56 pragma(mangle, "calloc") void* fakePureCalloc(size_t nmemb, size_t size) @safe; 57 pragma(mangle, "realloc") void* fakePureRealloc(return scope void* ptr, size_t size) @system; 58 } 59