The OpenD Programming Language

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 }