1 /** 2 * D binding to C++ <new> 3 * 4 * Copyright: Copyright (c) 2019 D Language Foundation 5 * License: Distributed under the 6 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 7 * (See accompanying file LICENSE) 8 * Authors: Manu Evans 9 * Source: $(DRUNTIMESRC core/stdcpp/new_.d) 10 */ 11 12 module core.stdcpp.new_; 13 14 import core.stdcpp.xutility : __cpp_sized_deallocation, __cpp_aligned_new; 15 import core.stdcpp.exception : exception; 16 17 // TODO: this really should come from __traits(getTargetInfo, "defaultNewAlignment") 18 version (D_LP64) 19 enum size_t __STDCPP_DEFAULT_NEW_ALIGNMENT__ = 16; 20 else 21 enum size_t __STDCPP_DEFAULT_NEW_ALIGNMENT__ = 8; 22 23 extern (C++, "std") 24 { 25 /// 26 struct nothrow_t {} 27 28 /// 29 enum align_val_t : size_t { defaultAlignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__ } 30 31 /// 32 class bad_alloc : exception 33 { 34 @nogc: 35 /// 36 this() { super("bad allocation", 1); } 37 } 38 } 39 40 41 /// 42 T* cpp_new(T, Args...)(auto ref Args args) if (!is(T == class)) 43 { 44 import core.lifetime : emplace, forward; 45 46 T* mem = cast(T*)__cpp_new(T.sizeof); 47 return mem.emplace(forward!args); 48 } 49 50 /// 51 T cpp_new(T, Args...)(auto ref Args args) if (is(T == class)) 52 { 53 import core.lifetime : emplace, forward; 54 55 T mem = cast(T)__cpp_new(__traits(classInstanceSize, T)); 56 return mem.emplace(forward!args); 57 } 58 59 /// 60 void cpp_delete(T)(T* ptr) if (!is(T == class)) 61 { 62 destroy!false(*ptr); 63 __cpp_delete(ptr); 64 } 65 66 /// 67 void cpp_delete(T)(T instance) if (is(T == class)) 68 { 69 destroy!false(instance); 70 __cpp_delete(cast(void*) instance); 71 } 72 73 74 // raw C++ functions 75 extern(C++): 76 @nogc: 77 78 /// Binding for ::operator new(std::size_t count) 79 pragma(mangle, __new_mangle) 80 void* __cpp_new(size_t count); 81 82 /// Binding for ::operator new(std::size_t count, const std::nothrow_t&) 83 pragma(mangle, __new_nothrow_mangle) 84 void* __cpp_new_nothrow(size_t count, ref const(nothrow_t) = std_nothrow) nothrow; 85 86 /// Binding for ::operator delete(void* ptr) 87 pragma(mangle, __delete_mangle) 88 void __cpp_delete(void* ptr); 89 90 /// Binding for ::operator delete(void* ptr, const std::nothrow_t& tag) 91 pragma(mangle, __delete_nothrow_mangle) 92 void __cpp_delete_nothrow(void* ptr, ref const(nothrow_t) = std_nothrow) nothrow; 93 94 static if (__cpp_sized_deallocation) 95 { 96 /// Binding for ::operator delete(void* ptr, size_t size) 97 pragma(mangle, __delete_size_mangle) 98 void __cpp_delete_size(void* ptr, size_t size); 99 } 100 static if (__cpp_aligned_new) 101 { 102 /// Binding for ::operator new(std::size_t count, std::align_val_t al) 103 pragma(mangle, __new_align_mangle) 104 void* __cpp_new_aligned(size_t count, align_val_t alignment); 105 106 /// Binding for ::operator new(std::size_t count, std::align_val_t al, const std::nothrow_t&) 107 pragma(mangle, __new_aligned_nothrow_mangle) 108 void* __cpp_new_aligned_nothrow(size_t count, align_val_t alignment, ref const(nothrow_t) = std_nothrow) nothrow; 109 110 /// Binding for ::operator delete(void* ptr, std::align_val_t al) 111 pragma(mangle, __delete_align_mangle) 112 void __cpp_delete_aligned(void* ptr, align_val_t alignment); 113 114 /// Binding for ::operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& tag) 115 pragma(mangle, __delete_align_nothrow_mangle) 116 void __cpp_delete_align_nothrow(void* ptr, align_val_t alignment, ref const(nothrow_t) = std_nothrow) nothrow; 117 118 /// Binding for ::operator delete(void* ptr, size_t size, std::align_val_t al) 119 pragma(mangle, __delete_size_align_mangle) 120 void __cpp_delete_size_aligned(void* ptr, size_t size, align_val_t alignment); 121 } 122 123 private: 124 extern (D): 125 126 __gshared immutable nothrow_t std_nothrow; 127 128 // we have to hard-code the mangling for the global new/delete operators 129 version (CppRuntime_Microsoft) 130 { 131 version (D_LP64) 132 { 133 enum __new_mangle = "??2@YAPEAX_K@Z"; 134 enum __new_nothrow_mangle = "??2@YAPEAX_KAEBUnothrow_t@std@@@Z"; 135 enum __delete_mangle = "??3@YAXPEAX@Z"; 136 enum __delete_nothrow_mangle = "??3@YAXPEAXAEBUnothrow_t@std@@@Z"; 137 enum __delete_size_mangle = "??3@YAXPEAX_K@Z"; 138 enum __new_align_mangle = "??2@YAPEAX_KW4align_val_t@std@@@Z"; 139 enum __new_aligned_nothrow_mangle = "??2@YAPEAX_KW4align_val_t@std@@AEBUnothrow_t@1@@Z"; 140 enum __delete_align_mangle = "??3@YAXPEAXW4align_val_t@std@@@Z"; 141 enum __delete_align_nothrow_mangle = "??3@YAXPEAXW4align_val_t@std@@AEBUnothrow_t@1@@Z"; 142 enum __delete_size_align_mangle = "??3@YAXPEAX_KW4align_val_t@std@@@Z"; 143 } 144 else 145 { 146 enum __new_mangle = "??2@YAPAXI@Z"; 147 enum __new_nothrow_mangle = "??2@YAPAXIABUnothrow_t@std@@@Z"; 148 enum __delete_mangle = "??3@YAXPAX@Z"; 149 enum __delete_nothrow_mangle = "??3@YAXPAXABUnothrow_t@std@@@Z"; 150 enum __delete_size_mangle = "??3@YAXPAXI@Z"; 151 enum __new_align_mangle = "??2@YAPAXIW4align_val_t@std@@@Z"; 152 enum __new_aligned_nothrow_mangle = "??2@YAPAXIW4align_val_t@std@@ABUnothrow_t@1@@Z"; 153 enum __delete_align_mangle = "??3@YAXPAXW4align_val_t@std@@@Z"; 154 enum __delete_align_nothrow_mangle = "??3@YAXPAXW4align_val_t@std@@ABUnothrow_t@1@@Z"; 155 enum __delete_size_align_mangle = "??3@YAXPAXIW4align_val_t@std@@@Z"; 156 } 157 } 158 else 159 { 160 version (D_LP64) 161 { 162 enum __new_mangle = "_Znwm"; 163 enum __new_nothrow_mangle = "_ZnwmRKSt9nothrow_t"; 164 enum __delete_mangle = "_ZdlPv"; 165 enum __delete_nothrow_mangle = "_ZdlPvRKSt9nothrow_t"; 166 enum __delete_size_mangle = "_ZdlPvm"; 167 enum __new_align_mangle = "_ZnwmSt11align_val_t"; 168 enum __new_aligned_nothrow_mangle = "_ZnwmSt11align_val_tRKSt9nothrow_t"; 169 enum __delete_align_mangle = "_ZdlPvSt11align_val_t"; 170 enum __delete_align_nothrow_mangle = "_ZdlPvSt11align_val_tRKSt9nothrow_t"; 171 enum __delete_size_align_mangle = "_ZdlPvmSt11align_val_t"; 172 } 173 else 174 { 175 enum __new_mangle = "_Znwj"; 176 enum __new_nothrow_mangle = "_ZnwjRKSt9nothrow_t"; 177 enum __delete_mangle = "_ZdlPv"; 178 enum __delete_nothrow_mangle = "_ZdlPvRKSt9nothrow_t"; 179 enum __delete_size_mangle = "_ZdlPvj"; 180 enum __new_align_mangle = "_ZnwjSt11align_val_t"; 181 enum __new_aligned_nothrow_mangle = "_ZnwjSt11align_val_tRKSt9nothrow_t"; 182 enum __delete_align_mangle = "_ZdlPvSt11align_val_t"; 183 enum __delete_align_nothrow_mangle = "_ZdlPvSt11align_val_tRKSt9nothrow_t"; 184 enum __delete_size_align_mangle = "_ZdlPvjSt11align_val_t"; 185 } 186 }