1 module numem.core.cpp;
2 import numem.core.traits;
3 import numem.core.lifetime;
4 
5 /**
6     Allocates a new C++ type on the heap using its default constructor.
7 
8     Notes:
9         $(D doXCtor) is used to specify whether to also call any D mangled
10         constructors defined for the C++ type.
11 
12     Params:
13         args = The arguments to pass to the type's constructor.
14     
15     Returns:
16         A newly allocated and instantiated C++ object using the
17         C++ Runtime.
18 */
19 Ref!T _nu_cpp_new(T, bool doXCtor, Args...)(auto ref Args args) @nogc if (isCPP!T) {
20     static if (isClasslike!T) {
21         Ref!T result = cast(Ref!T)__cpp_new(__traits(classInstanceSize, T));
22 
23         static if (doXCtor)
24             emplace(result, forward!args);
25     } else {
26         Ref!T result = cast(Ref!T)__cpp_new(T.sizeof);
27 
28         static if (doXCtor)
29             emplace(*result, forward!args);
30     }
31     return result;
32 }
33 
34 /**
35     Deletes a C++ object on the heap.
36 
37     Notes:
38         $(D doXDtor) is used to specify whether to also call any D mangled
39         destructors defined for the C++ type.
40 
41     Params:
42         ptr = The object to delete.
43 */
44 void _nu_cpp_delete(T, bool doXDtor)(ref T ptr) @nogc if (isCPP!T) {
45     if (ptr is null)
46         return;
47     
48     static if (doXDtor)
49         destruct!(T, false)(ptr);
50     
51     __cpp_delete(cast(void*)ptr);
52     ptr = null;
53 }
54 
55 private extern(C++) @nogc:
56 version (CppRuntime_Microsoft) {
57     version(D_LP64) {
58         
59         pragma(mangle, "??2@YAPEAX_K@Z")
60         void* __cpp_new(size_t bytes);
61 
62         pragma(mangle, "??3@YAXPEAX@Z")
63         void __cpp_delete(void* ptr);
64     } else {
65         
66         pragma(mangle, "??2@YAPAXI@Z")
67         void* __cpp_new(size_t bytes);
68 
69         pragma(mangle, "??3@YAXPAX@Z")
70         void __cpp_delete(void* ptr);
71     }
72 } else {
73     version(D_LP64) {
74         
75         pragma(mangle, "_Znwm")
76         void* __cpp_new(size_t bytes);
77 
78         pragma(mangle, "_ZdlPv")
79         void __cpp_delete(void* ptr);
80     } else {
81         
82         pragma(mangle, "_Znwj")
83         void* __cpp_new(size_t bytes);
84 
85         pragma(mangle, "_ZdlPv")
86         void __cpp_delete(void* ptr);
87     }
88 }