1 module as.utils;
2 import core.memory;
3 import core.stdc..string : memcpy;
4 import core.stdc.stdlib : malloc, free;
5 import std.traits;
6 import std.range.primitives : ElementType;
7 import std.stdio;
8 
9 /**
10     A D implementation of reinterpret_cast
11 */
12 T reinterpret_cast(T, U)(U item) if (T.sizeof == U.sizeof) {
13     union cst { U x; T y; }
14     return cst(item).y;
15 }
16 
17 /**
18     Allocates extra space
19 */
20 void* cMalloc(size_t size) {
21     return malloc(size);
22 }
23 
24 /**
25     Copies memory from A to B
26 */
27 void cMemCopy(T, U)(T to, U from, size_t length) {
28     memcpy(cast(void*)to, cast(void*)from, length);
29 }
30 
31 /**
32     C free routine
33 
34     Destructor will automatically be called if there is one
35 */
36 void cFree(T)(T item) {
37 
38     // Call destructor if there's one
39     destruct(item);
40 
41     // Free
42     free(cast(void*)item);
43 }
44 
45 void destruct(T)(T item) {
46     // Call destructor if there is any
47     static if (hasMember!(T, "__dtor")) {
48         item.__dtor();
49     } else static if (hasMember!(T, "dispose")) {
50         item.dispose();
51     }
52 }
53 
54 /**
55     Allocates the memory and runs constructors on the specified type
56 
57     Constructor arguments can be specified as well
58 */
59 T* cCreate(T, Args...)(Args args) {
60     import std.conv : emplace;
61 
62     // Allocate appropriate memory for the type
63     T* mem = cast(T*)cMalloc(T.sizeof);
64 
65     // Emplace the type on the memory, running constructors if neccesary
66     emplace!(T, Args)(mem, args);
67     return mem;
68 }