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 12module core.stdcpp.memory; 13 14public import core.stdcpp.allocator; 15 16import core.stdcpp.xutility : StdNamespace; 17 18extern(C++, (StdNamespace)): 19 20/// 21unique_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/// 30struct 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/// 45extern(C++, class) 46struct unique_ptr(T, Deleter = default_delete!T) 47{ 48extern(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 74nothrow 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 155private: 156 157template ClassOrPtr(T) 158{ 159 static if (is(T == class)) 160 alias ClassOrPtr = T; 161 else 162 alias ClassOrPtr = T*; 163} 164