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 }