1 /** 2 * D binding to C++ <memory>. 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/memory.d) 10 */ 11 12 module core.stdcpp.memory; 13 14 // LDC: empty module for unsupported C++ runtimes 15 version (CppRuntime_Microsoft) version = Supported; 16 else version (CppRuntime_Gcc) version = Supported; 17 else version (CppRuntime_Clang) version = Supported; 18 version (Supported): 19 20 public import core.stdcpp.allocator; 21 22 import core.stdcpp.xutility : StdNamespace; 23 24 extern(C++, (StdNamespace)): 25 26 /// 27 unique_ptr!T make_unique(T, Args...)(auto ref Args args) 28 { 29 import core.lifetime : forward; 30 import core.stdcpp.new_ : cpp_new; 31 32 return unique_ptr!T(cpp_new!T(forward!args)); 33 } 34 35 /// 36 struct default_delete(T) 37 { 38 /// 39 alias pointer = ClassOrPtr!T; 40 41 /// 42 void opCall()(pointer ptr) const 43 { 44 import core.stdcpp.new_ : cpp_delete; 45 46 cpp_delete(ptr); 47 } 48 } 49 50 /// 51 extern(C++, class) 52 struct unique_ptr(T, Deleter = default_delete!T) 53 { 54 extern(D): 55 /// 56 this(this) @disable; 57 58 /// 59 ~this() 60 { 61 reset(); 62 } 63 64 /// 65 ref unique_ptr opAssign(typeof(null)) 66 { 67 reset(); 68 return this; 69 } 70 71 /// 72 void reset(pointer p = null) 73 { 74 pointer t = __ptr(); 75 __ptr() = p; 76 if (t) 77 get_deleter()(t); 78 } 79 80 nothrow pure @safe @nogc: 81 /// 82 alias pointer = ClassOrPtr!T; 83 /// 84 alias element_type = T; 85 /// 86 alias deleter_type = Deleter; 87 88 /// 89 this(pointer ptr) 90 { 91 __ptr() = ptr; 92 } 93 94 /// 95 inout(pointer) get() inout nothrow 96 { 97 return __ptr(); 98 } 99 100 /// 101 bool opCast(T : bool)() const nothrow 102 { 103 return __ptr() != null; 104 } 105 106 /// 107 pointer release() nothrow 108 { 109 pointer t = __ptr(); 110 __ptr() = null; 111 return t; 112 } 113 114 // void swap(ref unique_ptr u) nothrow 115 // { 116 // __ptr_.swap(__u.__ptr_); 117 // } 118 119 version (CppRuntime_Microsoft) 120 { 121 /// 122 ref inout(deleter_type) get_deleter() inout nothrow { return _Mypair._Myval1; } 123 124 private: 125 import core.stdcpp.xutility : _Compressed_pair; 126 127 ref pointer __ptr() nothrow { return _Mypair._Myval2; } 128 inout(pointer) __ptr() inout nothrow { return _Mypair._Myval2; } 129 130 _Compressed_pair!(Deleter, pointer) _Mypair; 131 } 132 else version (CppRuntime_Gcc) 133 { 134 /// 135 ref inout(deleter_type) get_deleter() inout nothrow { return _M_t.get!1; } 136 137 private: 138 import core.stdcpp.tuple : tuple, get; 139 140 ref pointer __ptr() nothrow { return _M_t.get!0; } 141 inout(pointer) __ptr() inout nothrow { return _M_t.get!0; } 142 143 tuple!(pointer, Deleter) _M_t; 144 } 145 else version (CppRuntime_Clang) 146 { 147 /// 148 ref inout(deleter_type) get_deleter() inout nothrow { return __ptr_.second; } 149 150 private: 151 import core.stdcpp.xutility : __compressed_pair; 152 153 ref pointer __ptr() nothrow { return __ptr_.first; } 154 inout(pointer) __ptr() inout nothrow { return __ptr_.first; } 155 156 __compressed_pair!(pointer, deleter_type) __ptr_; 157 } 158 } 159 160 161 private: 162 163 template ClassOrPtr(T) 164 { 165 static if (is(T == class)) 166 alias ClassOrPtr = T; 167 else 168 alias ClassOrPtr = T*; 169 }