1 module std.internal.memory;
2
package(std)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 +/
enforceMalloc()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
enforceCalloc()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
enforceRealloc()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