]> git.saurik.com Git - wxWidgets.git/blame - include/wx/mac/corefoundation/cfref.h
fixed memory leak in wxXmlResource introduced when fixing wxVector<> usage (patch...
[wxWidgets.git] / include / wx / mac / corefoundation / cfref.h
CommitLineData
b4e0eabd
DE
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/mac/corefoundation/cfref.h
3// Purpose: wxCFRef template class
4// Author: David Elliott <dfe@cox.net>
fd9cd37f 5// Modified by: Stefan Csomor
b4e0eabd
DE
6// Created: 2007/05/10
7// RCS-ID: $Id$
fd9cd37f 8// Copyright: (c) 2007 David Elliott <dfe@cox.net>, Stefan Csomor
b4e0eabd
DE
9// Licence: wxWindows licence
10// Notes: See http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/index.html
11/////////////////////////////////////////////////////////////////////////////
12/*! @header wx/mac/corefoundation/cfref.h
13 @abstract wxCFRef template class
14 @discussion FIXME: Convert doc tags to something less buggy with C++
15*/
16
17#ifndef _WX_MAC_COREFOUNDATION_CFREF_H__
18#define _WX_MAC_COREFOUNDATION_CFREF_H__
19
9ed8b5a7
DE
20// #include <CoreFoundation/CFBase.h>
21/* Don't include CFBase.h such that this header can be included from public
22 * headers with minimal namespace pollution.
23 * Note that Darwin CF uses extern for CF_EXPORT. If we need this on Win32
24 * or non-Darwin Mac OS we'll need to define the appropriate __declspec.
25 */
9ed8b5a7 26typedef const void *CFTypeRef;
15041ff9 27extern "C" {
9ed8b5a7
DE
28extern /* CF_EXPORT */
29CFTypeRef CFRetain(CFTypeRef cf);
30extern /* CF_EXPORT */
31void CFRelease(CFTypeRef cf);
32} // extern "C"
33
b4e0eabd 34
fd9cd37f
DE
35/*! @function wxCFRelease
36 @abstract A CFRelease variant that checks for NULL before releasing.
69726164
DE
37 @discussion The parameter is template not for type safety but to ensure the argument
38 is a raw pointer and not a ref holder of any type.
fd9cd37f 39*/
69726164
DE
40template <class Type>
41inline void wxCFRelease(Type *r)
fd9cd37f
DE
42{
43 if ( r != NULL )
69726164 44 ::CFRelease((CFTypeRef)r);
fd9cd37f
DE
45}
46
47/*! @function wxCFRetain
48 @abstract A typesafe CFRetain variant that checks for NULL.
49*/
50template <class Type>
51inline Type* wxCFRetain(Type *r)
52{
53 // NOTE(DE): Setting r to the result of CFRetain improves efficiency on both x86 and PPC
54 // Casting r to CFTypeRef ensures we are calling the real C version defined in CFBase.h
55 // and not any possibly templated/overloaded CFRetain.
56 if ( r != NULL )
57 r = (Type*)::CFRetain((CFTypeRef)r);
58 return r;
59}
60
64dfdfa2
DE
61template <class refType>
62class wxCFRef;
63
64/*! @class wxCFWeakRef
65 @templatefield refType The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
66 It should already be a pointer. This is different from
67 shared_ptr where the template parameter is the pointee type.
68 @discussion Wraps a raw pointer without any retain or release.
69 Provides a way to get what amounts to a raw pointer from a wxCFRef without
70 using a raw pointer. Unlike a raw pointer, constructing a wxCFRef from this
71 class will cause it to be retained because it is assumed that a wxCFWeakRef
72 does not own its pointer.
73*/
74template <class refType>
75class wxCFWeakRef
76{
77 template <class refTypeA, class otherRefType>
78 friend wxCFWeakRef<refTypeA> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);
79public:
80 /*! @method wxCFWeakRef
81 @abstract Creates a NULL reference
82 */
83 wxCFWeakRef()
84 : m_ptr(NULL)
85 {}
86
87 // Default copy constructor is fine.
88 // Default destructor is fine but we'll set NULL to avoid bugs
89 ~wxCFWeakRef()
90 { m_ptr = NULL; }
91
92 // Do not implement a raw-pointer constructor.
93
94 /*! @method wxCFWeakRef
95 @abstract Copies another ref holder where its type can be converted to ours
96 @templatefield otherRefType Any type held by another wxCFWeakRef.
97 @param otherRef The other weak ref holder to copy.
98 @discussion This is merely a copy or implicit cast.
99 */
100 template <class otherRefType>
101 wxCFWeakRef(const wxCFWeakRef<otherRefType>& otherRef)
102 : m_ptr(otherRef.get()) // Implicit conversion from otherRefType to refType should occur
103 {}
104
105 /*! @method wxCFWeakRef
106 @abstract Copies a strong ref holder where its type can be converted to ours
107 @templatefield otherRefType Any type held by a wxCFRef.
108 @param otherRef The strong ref holder to copy.
109 @discussion This ref is merely a pointer copy, the strong ref still holds the pointer.
110 */
111 template <class otherRefType>
112 wxCFWeakRef(const wxCFRef<otherRefType>& otherRef)
113 : m_ptr(otherRef.get()) // Implicit conversion from otherRefType to refType should occur
114 {}
115
116 /*! @method get
117 @abstract Explicit conversion to the underlying pointer type
118 @discussion Allows the caller to explicitly get the underlying pointer.
119 */
120 refType get() const
121 { return m_ptr; }
122
123 /*! @method operator refType
124 @abstract Implicit conversion to the underlying pointer type
125 @discussion Allows the ref to be used in CF function calls.
126 */
127 operator refType() const
128 { return m_ptr; }
129
130protected:
131 /*! @method wxCFWeakRef
132 @abstract Constructs a weak reference to the raw pointer
133 @templatefield otherType Any type.
134 @param p The raw pointer to assume ownership of. May be NULL.
135 @discussion This method is private so that the friend static_cfref_cast can use it
136 */
137 template <class otherType>
138 explicit wxCFWeakRef(otherType *p)
139 : m_ptr(p) // Implicit conversion from otherType* to refType should occur.
140 {}
141
142 /*! @var m_ptr The raw pointer.
143 */
144 refType m_ptr;
145};
146
b4e0eabd
DE
147/*! @class wxCFRef
148 @templatefield refType The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
149 It should already be a pointer. This is different from
150 shared_ptr where the template parameter is the pointee type.
151 @discussion Properly retains/releases reference to CoreFoundation objects
152*/
153template <class refType>
154class wxCFRef
155{
b4e0eabd
DE
156public:
157 /*! @method wxCFRef
158 @abstract Creates a NULL reference
159 */
160 wxCFRef()
161 : m_ptr(NULL)
162 {}
163
164 /*! @method wxCFRef
165 @abstract Assumes ownership of p and creates a reference to it.
166 @templatefield otherType Any type.
167 @param p The raw pointer to assume ownership of. May be NULL.
168 @discussion Like shared_ptr, it is assumed that the caller has a strong reference to p and intends
169 to transfer ownership of that reference to this ref holder. If the object comes from
170 a Create or Copy method then this is the correct behavior. If the object comes from
171 a Get method then you must CFRetain it yourself before passing it to this constructor.
172 A handy way to do this is to use the non-member wxCFRefFromGet factory funcion.
173 This method is templated and takes an otherType *p. This prevents implicit conversion
174 using an operator refType() in a different ref-holding class type.
175 */
176 template <class otherType>
177 explicit wxCFRef(otherType *p)
178 : m_ptr(p) // Implicit conversion from otherType* to refType should occur.
179 {}
180
181 /*! @method wxCFRef
182 @abstract Copies a ref holder of the same type
183 @param otherRef The other ref holder to copy.
184 @discussion Ownership will be shared by the original ref and the newly created ref. That is,
185 the object will be explicitly retained by this new ref.
186 */
187 wxCFRef(const wxCFRef& otherRef)
fd9cd37f
DE
188 : m_ptr(wxCFRetain(otherRef.m_ptr))
189 {}
b4e0eabd
DE
190
191 /*! @method wxCFRef
192 @abstract Copies a ref holder where its type can be converted to ours
193 @templatefield otherRefType Any type held by another wxCFRef.
194 @param otherRef The other ref holder to copy.
195 @discussion Ownership will be shared by the original ref and the newly created ref. That is,
196 the object will be explicitly retained by this new ref.
197 */
198 template <class otherRefType>
199 wxCFRef(const wxCFRef<otherRefType>& otherRef)
fd9cd37f
DE
200 : m_ptr(wxCFRetain(otherRef.get())) // Implicit conversion from otherRefType to refType should occur
201 {}
b4e0eabd 202
64dfdfa2
DE
203 /*! @method wxCFRef
204 @abstract Copies a weak ref holder where its type can be converted to ours
205 @templatefield otherRefType Any type held by a wxCFWeakRef.
206 @param otherRef The weak ref holder to copy.
207 @discussion Ownership will be taken by this newly created ref. That is,
208 the object will be explicitly retained by this new ref.
209 Ownership is most likely shared with some other ref as well.
210 */
211 template <class otherRefType>
212 wxCFRef(const wxCFWeakRef<otherRefType>& otherRef)
213 : m_ptr(wxCFRetain(otherRef.get())) // Implicit conversion from otherRefType to refType should occur
214 {}
215
b4e0eabd
DE
216 /*! @method ~wxCFRef
217 @abstract Releases (potentially shared) ownership of the ref.
218 @discussion A ref holder instance is always assumed to have ownership so ownership is always
219 released (CFRelease called) upon destruction.
220 */
221 ~wxCFRef()
222 { reset(); }
223
224 /*! @method operator=
225 @abstract Assigns the other ref's pointer to us when the otherRef is the same type.
226 @param otherRef The other ref holder to copy.
227 @discussion The incoming pointer is retained, the original pointer is released, and this object
228 is made to point to the new pointer.
229 */
230 wxCFRef& operator=(const wxCFRef& otherRef)
231 {
fd9cd37f
DE
232 wxCFRetain(otherRef.m_ptr);
233 wxCFRelease(m_ptr);
b4e0eabd
DE
234 m_ptr = otherRef.m_ptr;
235 return *this;
236 }
237
238 /*! @method operator=
239 @abstract Assigns the other ref's pointer to us when the other ref can be converted to our type.
240 @templatefield otherRefType Any type held by another wxCFRef
241 @param otherRef The other ref holder to copy.
242 @discussion The incoming pointer is retained, the original pointer is released, and this object
243 is made to point to the new pointer.
244 */
245 template <class otherRefType>
246 wxCFRef& operator=(const wxCFRef<otherRefType>& otherRef)
247 {
fd9cd37f
DE
248 wxCFRetain(otherRef.get());
249 wxCFRelease(m_ptr);
250 m_ptr = otherRef.get(); // Implicit conversion from otherRefType to refType should occur
b4e0eabd
DE
251 return *this;
252 }
253
254 /*! @method get
255 @abstract Explicit conversion to the underlying pointer type
256 @discussion Allows the caller to explicitly get the underlying pointer.
257 */
258 refType get() const
259 { return m_ptr; }
260
261 /*! @method operator refType
262 @abstract Implicit conversion to the underlying pointer type
263 @discussion Allows the ref to be used in CF function calls.
264 */
265 operator refType() const
266 { return m_ptr; }
267
268#if 0
269 < // HeaderDoc is retarded and thinks the GT from operator-> is part of a template param.
270 // So give it that < outside of a comment to fake it out. (if 0 is not a comment to HeaderDoc)
271#endif
272
273 /*! @method operator-&gt;
274 @abstract Implicit conversion to the underlying pointer type
275 @discussion This is nearly useless for CF types which are nearly always opaque
276 */
277 refType operator-> () const
278 { return m_ptr; }
279
280 /*! @method reset
281 @abstract Nullifies the reference
282 @discussion Releases ownership (calls CFRelease) before nullifying the pointer.
283 */
284 void reset()
285 {
fd9cd37f 286 wxCFRelease(m_ptr);
b4e0eabd
DE
287 m_ptr = NULL;
288 }
289
290 /*! @method reset
291 @abstract Sets this to a new reference
292 @templatefield otherType Any type.
293 @param p The raw pointer to assume ownership of
294 @discussion The existing reference is released (like destruction). It is assumed that the caller
295 has a strong reference to the new p and intends to transfer ownership of that reference
296 to this ref holder. Take care to call CFRetain if you received the object from a Get method.
297 This method is templated and takes an otherType *p. This prevents implicit conversion
298 using an operator refType() in a different ref-holding class type.
299 */
300 template <class otherType>
301 void reset(otherType* p)
302 {
fd9cd37f 303 wxCFRelease(m_ptr);
b4e0eabd
DE
304 m_ptr = p; // Automatic conversion should occur
305 }
306protected:
307 /*! @var m_ptr The raw pointer.
308 */
309 refType m_ptr;
310};
311
312/*! @function wxCFRefFromGet
313 @abstract Factory function to create wxCFRef from a raw pointer obtained from a Get-rule function
314 @param p The pointer to retain and create a wxCFRef from. May be NULL.
315 @discussion Unlike the wxCFRef raw pointer constructor, this function explicitly retains its
316 argument. This can be used for functions such as CFDictionaryGetValue() or
317 CFAttributedStringGetString() which return a temporary reference (Get-rule functions).
318 FIXME: Anybody got a better name?
319*/
320template <typename Type>
321inline wxCFRef<Type*> wxCFRefFromGet(Type *p)
322{
fd9cd37f 323 return wxCFRef<Type*>(wxCFRetain(p));
b4e0eabd
DE
324}
325
326/*! @function static_cfref_cast
64dfdfa2 327 @abstract Works like static_cast but with a wxCFRef as the argument.
b4e0eabd
DE
328 @param refType Template parameter. The destination raw pointer type
329 @param otherRef Normal parameter. The source wxCFRef<> object.
64dfdfa2
DE
330 @discussion This is intended to be a clever way to make static_cast work while allowing
331 the return value to be converted to either a strong ref or a raw pointer
332 while ensuring that the retain count is updated appropriately.
333
334 This is modeled after shared_ptr's static_pointer_cast. Just as wxCFRef is
b4e0eabd
DE
335 parameterized on a pointer to an opaque type so is this class. Note that
336 this differs from shared_ptr which is parameterized on the pointee type.
64dfdfa2 337
b4e0eabd
DE
338 FIXME: Anybody got a better name?
339*/
340template <class refType, class otherRefType>
64dfdfa2 341inline wxCFWeakRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);
b4e0eabd
DE
342
343template <class refType, class otherRefType>
64dfdfa2 344inline wxCFWeakRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef)
b4e0eabd 345{
64dfdfa2 346 return wxCFWeakRef<refType>(static_cast<refType>(otherRef.get()));
b4e0eabd
DE
347}
348
349/*! @function CFRelease
350 @abstract Overloads CFRelease so that the user is warned of bad behavior.
351 @discussion It is rarely appropriate to retain or release a wxCFRef. If one absolutely
352 must do it he can explicitly get() the raw pointer
353 Normally, this function is unimplemented resulting in a linker error if used.
354*/
355template <class T>
356inline void CFRelease(const wxCFRef<T*> & cfref) DEPRECATED_ATTRIBUTE;
357
358/*! @function CFRetain
359 @abstract Overloads CFRetain so that the user is warned of bad behavior.
360 @discussion It is rarely appropriate to retain or release a wxCFRef. If one absolutely
361 must do it he can explicitly get() the raw pointer
362 Normally, this function is unimplemented resulting in a linker error if used.
363*/
364template <class T>
365inline void CFRetain(const wxCFRef<T*>& cfref) DEPRECATED_ATTRIBUTE;
366
367// Change the 0 to a 1 if you want the functions to work (no link errors)
368// Neither function will cause retain/release side-effects if implemented.
369#if 0
370template <class T>
371void CFRelease(const wxCFRef<T*> & cfref)
372{
373 CFRelease(cfref.get());
374}
375
376template <class T>
377void CFRetain(const wxCFRef<T*> & cfref)
378{
379 CFRetain(cfref.get());
380}
381#endif
382
383#endif //ndef _WX_MAC_COREFOUNDATION_CFREF_H__
384