1 /****************************************************************************
2 **
3 ** DQt - D bindings for the Qt Toolkit
4 **
5 ** GNU Lesser General Public License Usage
6 ** This file may be used under the terms of the GNU Lesser
7 ** General Public License version 3 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
9 ** packaging of this file. Please review the following information to
10 ** ensure the GNU Lesser General Public License version 3 requirements
11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
12 **
13 ****************************************************************************/
14 module qt.core.scopedpointer;
15 extern(C++):
16 
17 import qt.config;
18 import qt.core.object;
19 import qt.helpers;
20 
21 struct QScopedPointerDeleter(T)
22 {
23     static if(is(T == class))
24     {
25         alias P = T;
26         enum IsIncompleteType = !__traits(compiles, __traits(classInstanceSize, T));
27     }
28     else
29     {
30         alias P = T*;
31         enum IsIncompleteType = !__traits(compiles, T.sizeof);
32     }
33     static if(IsIncompleteType)
34         static void cleanup(P pointer);
35     else
36         pragma(inline, true) static void cleanup(P pointer)
37         {
38             import core.stdcpp.new_;
39 
40             static if(IsIncompleteType)
41                 assert(false);
42             else
43                 cpp_delete(pointer);
44         }
45 }
46 
47 /+ template <typename T>
48 struct QScopedPointerArrayDeleter
49 {
50     static inline void cleanup(T *pointer)
51     {
52         // Enforce a complete type.
53         // If you get a compile error here, read the section on forward declared
54         // classes in the QScopedPointer documentation.
55         typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
56         (void) sizeof(IsIncompleteType);
57 
58         delete [] pointer;
59     }
60 };
61 
62 struct QScopedPointerPodDeleter
63 {
64     static inline void cleanup(void *pointer) { if (pointer) free(pointer); }
65 };
66 
67 #ifndef QT_NO_QOBJECT +/
68 struct QScopedPointerObjectDeleteLater(T) if(is(T : QObject))
69 {
70     pragma(inline, true) static void cleanup(T pointer) { if (pointer) pointer.deleteLater(); }
71 }
72 
73 /+ class QObject; +/
74 alias QScopedPointerDeleteLater = QScopedPointerObjectDeleteLater!(QObject);
75 /+ #endif +/
76 
77 extern(C++, class) struct QScopedPointer(T, Cleanup = QScopedPointerDeleter!T)
78 {
79 private:
80     static if(is(T == class))
81     {
82         alias P = T;
83     }
84     else
85     {
86         alias P = T*;
87     }
88 
89     alias RestrictedBool = P/+ QScopedPointer:: * +/*;
90 public:
91     /+ explicit +/this(P p/+ = null+/)/+ noexcept+/
92     {
93         this.d = p;
94     }
95 
96     pragma(inline, true) ~this()
97     {
98         assert(false);
99         /*P oldD = this.d;
100         Cleanup.cleanup(oldD);*/
101     }
102 
103     pragma(inline, true) ref T opUnary(string op)() const if(op == "*")
104     {
105         import qt.core.global;
106 
107         (mixin(Q_ASSERT(q{d})));
108         return *d;
109     }
110 
111     /+P operator ->() const/+ noexcept+/
112     {
113         return d;
114     }+/
115 
116     /+bool operator !() const/+ noexcept+/
117     {
118         return !d;
119     }+/
120 
121 /+ #if defined(Q_QDOC)
122     inline operator bool() const
123     {
124         return isNull() ? nullptr : &QScopedPointer::d;
125     }
126 #else +/
127     /+auto opCast(T : RestrictedBool)() const/+ noexcept+/
128     {
129         return isNull() ? null : &QScopedPointer.d;
130     }+/
131 /+ #endif +/
132 
133     P data() const/+ noexcept+/
134     {
135         return cast(P)d;
136     }
137     
138     alias data this;
139 
140     P get() const/+ noexcept+/
141     {
142         return cast(P)d;
143     }
144 
145     bool isNull() const/+ noexcept+/
146     {
147         return !d;
148     }
149 
150 /+    void reset(P other = null) /+ noexcept(noexcept(Cleanup::cleanup(std::declval<T *>()))) +/
151     {
152         if (d == other)
153             return;
154         P oldD = d;
155         d = other;
156         Cleanup.cleanup(oldD);
157     }+/
158 
159   /+  P take()/+ noexcept+/
160     {
161         P oldD = d;
162         d = null;
163         return oldD;
164     }+/
165 
166     /+ void swap(QScopedPointer<T, Cleanup> &other) noexcept
167     {
168         qSwap(d, other.d);
169     } +/
170 
171     alias pointer = P;
172 
173 protected:
174     P d = null;
175 
176 private:
177     /+ Q_DISABLE_COPY(QScopedPointer) +/
178 @disable this(this);
179 /+this(ref const(QScopedPointer));+//+ref QScopedPointer operator =(ref const(QScopedPointer));+/}
180 
181 /+pragma(inline, true) bool operator ==(T, Cleanup)(ref const(QScopedPointer!(T, Cleanup)) lhs, ref const(QScopedPointer!(T, Cleanup)) rhs)/+ noexcept+/
182 {
183     return lhs.data() == rhs.data();
184 }+/
185 
186 /+pragma(inline, true) bool operator !=(T, Cleanup)(ref const(QScopedPointer!(T, Cleanup)) lhs, ref const(QScopedPointer!(T, Cleanup)) rhs)/+ noexcept+/
187 {
188     return lhs.data() != rhs.data();
189 }+/
190 
191 /+pragma(inline, true) bool operator ==(T, Cleanup)(ref const(QScopedPointer!(T, Cleanup)) lhs, /+ std:: +/nullptr_t)/+ noexcept+/
192 {
193     return lhs.isNull();
194 }+/
195 
196 /+pragma(inline, true) bool operator ==(T, Cleanup)(/+ std:: +/nullptr_t, ref const(QScopedPointer!(T, Cleanup)) rhs)/+ noexcept+/
197 {
198     return rhs.isNull();
199 }+/
200 
201 /+pragma(inline, true) bool operator !=(T, Cleanup)(ref const(QScopedPointer!(T, Cleanup)) lhs, /+ std:: +/nullptr_t)/+ noexcept+/
202 {
203     return !lhs.isNull();
204 }+/
205 
206 /+pragma(inline, true) bool operator !=(T, Cleanup)(/+ std:: +/nullptr_t, ref const(QScopedPointer!(T, Cleanup)) rhs)/+ noexcept+/
207 {
208     return !rhs.isNull();
209 }+/
210 
211 /+ template <class T, class Cleanup>
212 inline void swap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) noexcept
213 { p1.swap(p2); } +/
214 
215 class QScopedArrayPointer(T, Cleanup ) : QScopedPointer!(T, Cleanup)
216 {
217 private:
218     /+ template <typename Ptr> +/
219     /+ using if_same_type = typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, Ptr>::value, bool>::type; +/
220 public:
221     pragma(inline, true) this()
222     {
223         this.QScopedPointer!(T, Cleanup) = null;
224     }
225 
226     /+ template <typename D, if_same_type<D> = true> +/
227     /+ explicit QScopedArrayPointer(D *p)
228         : QScopedPointer<T, Cleanup>(p)
229     {
230     } +/
231 
232     pragma(inline, true) final ref T opIndex(int i)
233     {
234         return this.d[i];
235     }
236 
237     pragma(inline, true) final ref const(T) opIndex(int i) const
238     {
239         return this.d[i];
240     }
241 
242     /+ void swap(QScopedArrayPointer &other) noexcept // prevent QScopedPointer <->QScopedArrayPointer swaps
243     { QScopedPointer<T, Cleanup>::swap(other); } +/
244 
245 private:
246     /+ explicit +/ pragma(inline, true) this(void* ) {
247         // Enforce the same type.
248 
249         // If you get a compile error here, make sure you declare
250         // QScopedArrayPointer with the same template type as you pass to the
251         // constructor. See also the QScopedPointer documentation.
252 
253         // Storing a scalar array as a pointer to a different type is not
254         // allowed and results in undefined behavior.
255     }
256 
257     /+ Q_DISABLE_COPY(QScopedArrayPointer) +/
258 }
259 
260 /+ template <typename T, typename Cleanup>
261 inline void swap(QScopedArrayPointer<T, Cleanup> &lhs, QScopedArrayPointer<T, Cleanup> &rhs) noexcept
262 { lhs.swap(rhs); } +/
263