]> git.saurik.com Git - wxWidgets.git/blob - include/wx/mac/corefoundation/cfref.h
Add factory functions for use with future unit tests.
[wxWidgets.git] / include / wx / mac / corefoundation / cfref.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/mac/corefoundation/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 // RCS-ID: $Id$
8 // Copyright: (c) 2007 David Elliott <dfe@cox.net>, Stefan Csomor
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
20 #include <CoreFoundation/CFBase.h>
21
22 /*! @function wxCFRelease
23 @abstract A CFRelease variant that checks for NULL before releasing.
24 @discussion The parameter is template not for type safety but to ensure the argument
25 is a raw pointer and not a ref holder of any type.
26 */
27 template <class Type>
28 inline void wxCFRelease(Type *r)
29 {
30 if ( r != NULL )
31 ::CFRelease((CFTypeRef)r);
32 }
33
34 /*! @function wxCFRetain
35 @abstract A typesafe CFRetain variant that checks for NULL.
36 */
37 template <class Type>
38 inline Type* wxCFRetain(Type *r)
39 {
40 // NOTE(DE): Setting r to the result of CFRetain improves efficiency on both x86 and PPC
41 // Casting r to CFTypeRef ensures we are calling the real C version defined in CFBase.h
42 // and not any possibly templated/overloaded CFRetain.
43 if ( r != NULL )
44 r = (Type*)::CFRetain((CFTypeRef)r);
45 return r;
46 }
47
48 /*! @class wxCFRef
49 @templatefield refType The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
50 It should already be a pointer. This is different from
51 shared_ptr where the template parameter is the pointee type.
52 @discussion Properly retains/releases reference to CoreFoundation objects
53 */
54 template <class refType>
55 class wxCFRef
56 {
57 public:
58 /*! @method wxCFRef
59 @abstract Creates a NULL reference
60 */
61 wxCFRef()
62 : m_ptr(NULL)
63 {}
64
65 /*! @method wxCFRef
66 @abstract Assumes ownership of p and creates a reference to it.
67 @templatefield otherType Any type.
68 @param p The raw pointer to assume ownership of. May be NULL.
69 @discussion Like shared_ptr, it is assumed that the caller has a strong reference to p and intends
70 to transfer ownership of that reference to this ref holder. If the object comes from
71 a Create or Copy method then this is the correct behavior. If the object comes from
72 a Get method then you must CFRetain it yourself before passing it to this constructor.
73 A handy way to do this is to use the non-member wxCFRefFromGet factory funcion.
74 This method is templated and takes an otherType *p. This prevents implicit conversion
75 using an operator refType() in a different ref-holding class type.
76 */
77 template <class otherType>
78 explicit wxCFRef(otherType *p)
79 : m_ptr(p) // Implicit conversion from otherType* to refType should occur.
80 {}
81
82 /*! @method wxCFRef
83 @abstract Copies a ref holder of the same type
84 @param otherRef The other ref holder to copy.
85 @discussion Ownership will be shared by the original ref and the newly created ref. That is,
86 the object will be explicitly retained by this new ref.
87 */
88 wxCFRef(const wxCFRef& otherRef)
89 : m_ptr(wxCFRetain(otherRef.m_ptr))
90 {}
91
92 /*! @method wxCFRef
93 @abstract Copies a ref holder where its type can be converted to ours
94 @templatefield otherRefType Any type held by another wxCFRef.
95 @param otherRef The other ref holder to copy.
96 @discussion Ownership will be shared by the original ref and the newly created ref. That is,
97 the object will be explicitly retained by this new ref.
98 */
99 template <class otherRefType>
100 wxCFRef(const wxCFRef<otherRefType>& otherRef)
101 : m_ptr(wxCFRetain(otherRef.get())) // Implicit conversion from otherRefType to refType should occur
102 {}
103
104 /*! @method ~wxCFRef
105 @abstract Releases (potentially shared) ownership of the ref.
106 @discussion A ref holder instance is always assumed to have ownership so ownership is always
107 released (CFRelease called) upon destruction.
108 */
109 ~wxCFRef()
110 { reset(); }
111
112 /*! @method operator=
113 @abstract Assigns the other ref's pointer to us when the otherRef is the same type.
114 @param otherRef The other ref holder to copy.
115 @discussion The incoming pointer is retained, the original pointer is released, and this object
116 is made to point to the new pointer.
117 */
118 wxCFRef& operator=(const wxCFRef& otherRef)
119 {
120 wxCFRetain(otherRef.m_ptr);
121 wxCFRelease(m_ptr);
122 m_ptr = otherRef.m_ptr;
123 return *this;
124 }
125
126 /*! @method operator=
127 @abstract Assigns the other ref's pointer to us when the other ref can be converted to our type.
128 @templatefield otherRefType Any type held by another wxCFRef
129 @param otherRef The other ref holder to copy.
130 @discussion The incoming pointer is retained, the original pointer is released, and this object
131 is made to point to the new pointer.
132 */
133 template <class otherRefType>
134 wxCFRef& operator=(const wxCFRef<otherRefType>& otherRef)
135 {
136 wxCFRetain(otherRef.get());
137 wxCFRelease(m_ptr);
138 m_ptr = otherRef.get(); // Implicit conversion from otherRefType to refType should occur
139 return *this;
140 }
141
142 /*! @method get
143 @abstract Explicit conversion to the underlying pointer type
144 @discussion Allows the caller to explicitly get the underlying pointer.
145 */
146 refType get() const
147 { return m_ptr; }
148
149 /*! @method operator refType
150 @abstract Implicit conversion to the underlying pointer type
151 @discussion Allows the ref to be used in CF function calls.
152 */
153 operator refType() const
154 { return m_ptr; }
155
156 #if 0
157 < // HeaderDoc is retarded and thinks the GT from operator-> is part of a template param.
158 // So give it that < outside of a comment to fake it out. (if 0 is not a comment to HeaderDoc)
159 #endif
160
161 /*! @method operator-&gt;
162 @abstract Implicit conversion to the underlying pointer type
163 @discussion This is nearly useless for CF types which are nearly always opaque
164 */
165 refType operator-> () const
166 { return m_ptr; }
167
168 /*! @method reset
169 @abstract Nullifies the reference
170 @discussion Releases ownership (calls CFRelease) before nullifying the pointer.
171 */
172 void reset()
173 {
174 wxCFRelease(m_ptr);
175 m_ptr = NULL;
176 }
177
178 /*! @method reset
179 @abstract Sets this to a new reference
180 @templatefield otherType Any type.
181 @param p The raw pointer to assume ownership of
182 @discussion The existing reference is released (like destruction). It is assumed that the caller
183 has a strong reference to the new p and intends to transfer ownership of that reference
184 to this ref holder. Take care to call CFRetain if you received the object from a Get method.
185 This method is templated and takes an otherType *p. This prevents implicit conversion
186 using an operator refType() in a different ref-holding class type.
187 */
188 template <class otherType>
189 void reset(otherType* p)
190 {
191 wxCFRelease(m_ptr);
192 m_ptr = p; // Automatic conversion should occur
193 }
194 protected:
195 /*! @var m_ptr The raw pointer.
196 */
197 refType m_ptr;
198 };
199
200 /*! @function wxCFRefFromGet
201 @abstract Factory function to create wxCFRef from a raw pointer obtained from a Get-rule function
202 @param p The pointer to retain and create a wxCFRef from. May be NULL.
203 @discussion Unlike the wxCFRef raw pointer constructor, this function explicitly retains its
204 argument. This can be used for functions such as CFDictionaryGetValue() or
205 CFAttributedStringGetString() which return a temporary reference (Get-rule functions).
206 FIXME: Anybody got a better name?
207 */
208 template <typename Type>
209 inline wxCFRef<Type*> wxCFRefFromGet(Type *p)
210 {
211 return wxCFRef<Type*>(wxCFRetain(p));
212 }
213
214 /*! @function static_cfref_cast
215 @abstract Works like static_cast but from one wxCFRef to another
216 @param refType Template parameter. The destination raw pointer type
217 @param otherRef Normal parameter. The source wxCFRef<> object.
218 @discussion This is modeled after shared_ptr's static_pointer_cast. Just as wxCFRef is
219 parameterized on a pointer to an opaque type so is this class. Note that
220 this differs from shared_ptr which is parameterized on the pointee type.
221 FIXME: Anybody got a better name?
222 */
223 template <class refType, class otherRefType>
224 inline wxCFRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);
225
226 template <class refType, class otherRefType>
227 inline wxCFRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef)
228 {
229 return wxCFRef<refType>(static_cast<refType>(wxCFRetain(otherRef.get())));
230 }
231
232 /*! @function CFRelease
233 @abstract Overloads CFRelease so that the user is warned of bad behavior.
234 @discussion It is rarely appropriate to retain or release a wxCFRef. If one absolutely
235 must do it he can explicitly get() the raw pointer
236 Normally, this function is unimplemented resulting in a linker error if used.
237 */
238 template <class T>
239 inline void CFRelease(const wxCFRef<T*> & cfref) DEPRECATED_ATTRIBUTE;
240
241 /*! @function CFRetain
242 @abstract Overloads CFRetain so that the user is warned of bad behavior.
243 @discussion It is rarely appropriate to retain or release a wxCFRef. If one absolutely
244 must do it he can explicitly get() the raw pointer
245 Normally, this function is unimplemented resulting in a linker error if used.
246 */
247 template <class T>
248 inline void CFRetain(const wxCFRef<T*>& cfref) DEPRECATED_ATTRIBUTE;
249
250 // Change the 0 to a 1 if you want the functions to work (no link errors)
251 // Neither function will cause retain/release side-effects if implemented.
252 #if 0
253 template <class T>
254 void CFRelease(const wxCFRef<T*> & cfref)
255 {
256 CFRelease(cfref.get());
257 }
258
259 template <class T>
260 void CFRetain(const wxCFRef<T*> & cfref)
261 {
262 CFRetain(cfref.get());
263 }
264 #endif
265
266 #endif //ndef _WX_MAC_COREFOUNDATION_CFREF_H__
267