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