| module std.internal.memory; |
| |
| package(std): |
| |
| version (D_Exceptions) |
| { |
| import core.exception : onOutOfMemoryError; |
| private enum allocationFailed = `onOutOfMemoryError();`; |
| } |
| else |
| { |
| private enum allocationFailed = `assert(0, "Memory allocation failed");`; |
| } |
| |
| // (below comments are non-DDOC, but are written in similar style) |
| |
| /+ |
| Mnemonic for `enforce!OutOfMemoryError(malloc(size))` that (unlike malloc) |
| can be considered pure because it causes the program to abort if the result |
| of the allocation is null, with the consequence that errno will not be |
| visibly changed by calling this function. Note that `malloc` can also |
| return `null` in non-failure situations if given an argument of 0. Hence, |
| it is a programmer error to use this function if the requested allocation |
| size is logically permitted to be zero. `enforceCalloc` and `enforceRealloc` |
| work analogously. |
| |
| All these functions are usable in `betterC`. |
| +/ |
| void* enforceMalloc()(size_t size) @nogc nothrow pure @safe |
| { |
| auto result = fakePureMalloc(size); |
| if (!result) mixin(allocationFailed); |
| return result; |
| } |
| |
| // ditto |
| void* enforceCalloc()(size_t nmemb, size_t size) @nogc nothrow pure @safe |
| { |
| auto result = fakePureCalloc(nmemb, size); |
| if (!result) mixin(allocationFailed); |
| return result; |
| } |
| |
| // ditto |
| void* enforceRealloc()(return scope void* ptr, size_t size) @nogc nothrow pure @system |
| { |
| auto result = fakePureRealloc(ptr, size); |
| if (!result) mixin(allocationFailed); |
| return result; |
| } |
| |
| // Purified for local use only. |
| extern (C) @nogc nothrow pure private |
| { |
| pragma(mangle, "malloc") void* fakePureMalloc(size_t) @safe; |
| pragma(mangle, "calloc") void* fakePureCalloc(size_t nmemb, size_t size) @safe; |
| pragma(mangle, "realloc") void* fakePureRealloc(return scope void* ptr, size_t size) @system; |
| } |