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