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