File: cfref.h

package info (click to toggle)
wxpython3.0 3.0.2.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 482,760 kB
  • ctags: 518,293
  • sloc: cpp: 2,127,226; python: 294,045; makefile: 51,942; ansic: 19,033; sh: 3,013; xml: 1,629; perl: 17
file content (400 lines) | stat: -rw-r--r-- 16,068 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/////////////////////////////////////////////////////////////////////////////
// Name:        wx/osx/core/cfref.h
// Purpose:     wxCFRef template class
// Author:      David Elliott <dfe@cox.net>
// Modified by: Stefan Csomor
// Created:     2007/05/10
// Copyright:   (c) 2007 David Elliott <dfe@cox.net>, Stefan Csomor
// Licence:     wxWindows licence
// Notes:       See http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/index.html
/////////////////////////////////////////////////////////////////////////////
/*! @header     wx/osx/core/cfref.h
    @abstract   wxCFRef template class
    @discussion FIXME: Convert doc tags to something less buggy with C++
*/

#ifndef _WX_MAC_COREFOUNDATION_CFREF_H__
#define _WX_MAC_COREFOUNDATION_CFREF_H__

// Include unistd to ensure that NULL is defined
#include <unistd.h>
// Include AvailabilityMacros for DEPRECATED_ATTRIBUTE
#include <AvailabilityMacros.h>

// #include <CoreFoundation/CFBase.h>
/* Don't include CFBase.h such that this header can be included from public
 * headers with minimal namespace pollution.
 * Note that Darwin CF uses extern for CF_EXPORT.  If we need this on Win32
 * or non-Darwin Mac OS we'll need to define the appropriate __declspec.
 */
typedef const void *CFTypeRef;
extern "C" {
extern /* CF_EXPORT */
CFTypeRef CFRetain(CFTypeRef cf);
extern /* CF_EXPORT */
void CFRelease(CFTypeRef cf);
} // extern "C"


/*! @function   wxCFRelease
    @abstract   A CFRelease variant that checks for NULL before releasing.
    @discussion The parameter is template not for type safety but to ensure the argument
                is a raw pointer and not a ref holder of any type.
*/
template <class Type>
inline void wxCFRelease(Type *r)
{
    if ( r != NULL )
        ::CFRelease((CFTypeRef)r);
}

/*! @function   wxCFRetain
    @abstract   A typesafe CFRetain variant that checks for NULL.
*/
template <class Type>
inline Type* wxCFRetain(Type *r)
{
    // NOTE(DE): Setting r to the result of CFRetain improves efficiency on both x86 and PPC
    // Casting r to CFTypeRef ensures we are calling the real C version defined in CFBase.h
    // and not any possibly templated/overloaded CFRetain.
    if ( r != NULL )
        r = (Type*)::CFRetain((CFTypeRef)r);
    return r;
}

template <class refType>
class wxCFRef;

/*! @class wxCFWeakRef
    @templatefield  refType     The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
                                It should already be a pointer.  This is different from
                                shared_ptr where the template parameter is the pointee type.
    @discussion Wraps a raw pointer without any retain or release.
                Provides a way to get what amounts to a raw pointer from a wxCFRef without
                using a raw pointer.  Unlike a raw pointer, constructing a wxCFRef from this
                class will cause it to be retained because it is assumed that a wxCFWeakRef
                does not own its pointer.
*/
template <class refType>
class wxCFWeakRef
{
    template <class refTypeA, class otherRefType>
    friend wxCFWeakRef<refTypeA> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);
public:
    /*! @method     wxCFWeakRef
        @abstract   Creates a NULL reference
    */
    wxCFWeakRef()
    :   m_ptr(NULL)
    {}

    // Default copy constructor is fine.
    // Default destructor is fine but we'll set NULL to avoid bugs
    ~wxCFWeakRef()
    {   m_ptr = NULL; }

    // Do not implement a raw-pointer constructor.

    /*! @method     wxCFWeakRef
        @abstract   Copies another ref holder where its type can be converted to ours
        @templatefield otherRefType     Any type held by another wxCFWeakRef.
        @param otherRef The other weak ref holder to copy.
        @discussion This is merely a copy or implicit cast.
    */
    template <class otherRefType>
    wxCFWeakRef(const wxCFWeakRef<otherRefType>& otherRef)
    :   m_ptr(otherRef.get()) // Implicit conversion from otherRefType to refType should occur
    {}

    /*! @method     wxCFWeakRef
        @abstract   Copies a strong ref holder where its type can be converted to ours
        @templatefield otherRefType     Any type held by a wxCFRef.
        @param otherRef The strong ref holder to copy.
        @discussion This ref is merely a pointer copy, the strong ref still holds the pointer.
    */
    template <class otherRefType>
    wxCFWeakRef(const wxCFRef<otherRefType>& otherRef)
    :   m_ptr(otherRef.get()) // Implicit conversion from otherRefType to refType should occur
    {}

    /*! @method     get
        @abstract   Explicit conversion to the underlying pointer type
        @discussion Allows the caller to explicitly get the underlying pointer.
    */
    refType get() const
    {   return m_ptr; }

    /*! @method     operator refType
        @abstract   Implicit conversion to the underlying pointer type
        @discussion Allows the ref to be used in CF function calls.
    */
    operator refType() const
    {   return m_ptr; }

protected:
    /*! @method     wxCFWeakRef
        @abstract   Constructs a weak reference to the raw pointer
        @templatefield otherType    Any type.
        @param p        The raw pointer to assume ownership of.  May be NULL.
        @discussion This method is private so that the friend static_cfref_cast can use it
    */
    template <class otherType>
    explicit wxCFWeakRef(otherType *p)
    :   m_ptr(p) // Implicit conversion from otherType* to refType should occur.
    {}

    /*! @var m_ptr      The raw pointer.
    */
    refType m_ptr;
};

/*! @class wxCFRef
    @templatefield  refType     The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
                                It should already be a pointer.  This is different from
                                shared_ptr where the template parameter is the pointee type.
    @discussion Properly retains/releases reference to CoreFoundation objects
*/
template <class refType>
class wxCFRef
{
public:
    /*! @method     wxCFRef
        @abstract   Creates a NULL reference
    */
    wxCFRef()
    :   m_ptr(NULL)
    {}

    /*! @method     wxCFRef
        @abstract   Assumes ownership of p and creates a reference to it.
        @templatefield otherType    Any type.
        @param p        The raw pointer to assume ownership of.  May be NULL.
        @discussion Like shared_ptr, it is assumed that the caller has a strong reference to p and intends
                    to transfer ownership of that reference to this ref holder.  If the object comes from
                    a Create or Copy method then this is the correct behaviour.  If the object comes from
                    a Get method then you must CFRetain it yourself before passing it to this constructor.
                    A handy way to do this is to use the non-member wxCFRefFromGet factory funcion.
                    This method is templated and takes an otherType *p.  This prevents implicit conversion
                    using an operator refType() in a different ref-holding class type.
    */
    template <class otherType>
    explicit wxCFRef(otherType *p)
    :   m_ptr(p) // Implicit conversion from otherType* to refType should occur.
    {}

    /*! @method     wxCFRef
        @abstract   Copies a ref holder of the same type
        @param otherRef The other ref holder to copy.
        @discussion Ownership will be shared by the original ref and the newly created ref. That is,
                    the object will be explicitly retained by this new ref.
    */
    wxCFRef(const wxCFRef& otherRef)
    :   m_ptr(wxCFRetain(otherRef.m_ptr))
    {}

    /*! @method     wxCFRef
        @abstract   Copies a ref holder where its type can be converted to ours
        @templatefield otherRefType     Any type held by another wxCFRef.
        @param otherRef The other ref holder to copy.
        @discussion Ownership will be shared by the original ref and the newly created ref. That is,
                    the object will be explicitly retained by this new ref.
    */
    template <class otherRefType>
    wxCFRef(const wxCFRef<otherRefType>& otherRef)
    :   m_ptr(wxCFRetain(otherRef.get())) // Implicit conversion from otherRefType to refType should occur
    {}

    /*! @method     wxCFRef
        @abstract   Copies a weak ref holder where its type can be converted to ours
        @templatefield otherRefType     Any type held by a wxCFWeakRef.
        @param otherRef The weak ref holder to copy.
        @discussion Ownership will be taken by this newly created ref. That is,
                    the object will be explicitly retained by this new ref.
                    Ownership is most likely shared with some other ref as well.
    */
    template <class otherRefType>
    wxCFRef(const wxCFWeakRef<otherRefType>& otherRef)
    :   m_ptr(wxCFRetain(otherRef.get())) // Implicit conversion from otherRefType to refType should occur
    {}

    /*! @method     ~wxCFRef
        @abstract   Releases (potentially shared) ownership of the ref.
        @discussion A ref holder instance is always assumed to have ownership so ownership is always
                    released (CFRelease called) upon destruction.
    */
    ~wxCFRef()
    {   reset(); }

    /*! @method     operator=
        @abstract   Assigns the other ref's pointer to us when the otherRef is the same type.
        @param otherRef The other ref holder to copy.
        @discussion The incoming pointer is retained, the original pointer is released, and this object
                    is made to point to the new pointer.
    */
    wxCFRef& operator=(const wxCFRef& otherRef)
    {
        if (this != &otherRef)
        {
            wxCFRetain(otherRef.m_ptr);
            wxCFRelease(m_ptr);
            m_ptr = otherRef.m_ptr;
        }
        return *this;
    }

    /*! @method     operator=
        @abstract   Assigns the other ref's pointer to us when the other ref can be converted to our type.
        @templatefield otherRefType     Any type held by another wxCFRef
        @param otherRef The other ref holder to copy.
        @discussion The incoming pointer is retained, the original pointer is released, and this object
                    is made to point to the new pointer.
    */
    template <class otherRefType>
    wxCFRef& operator=(const wxCFRef<otherRefType>& otherRef)
    {
        wxCFRetain(otherRef.get());
        wxCFRelease(m_ptr);
        m_ptr = otherRef.get(); // Implicit conversion from otherRefType to refType should occur
        return *this;
    }

    /*! @method     get
        @abstract   Explicit conversion to the underlying pointer type
        @discussion Allows the caller to explicitly get the underlying pointer.
    */
    refType get() const
    {   return m_ptr; }

    /*! @method     operator refType
        @abstract   Implicit conversion to the underlying pointer type
        @discussion Allows the ref to be used in CF function calls.
    */
    operator refType() const
    {   return m_ptr; }

#if 0
    <   // HeaderDoc is retarded and thinks the GT from operator-> is part of a template param.
        // So give it that < outside of a comment to fake it out. (if 0 is not a comment to HeaderDoc)
#endif

    /*! @method     operator-&gt;
        @abstract   Implicit conversion to the underlying pointer type
        @discussion This is nearly useless for CF types which are nearly always opaque
    */
    refType operator-> () const
    {   return m_ptr; }

    /*! @method     reset
        @abstract   Nullifies the reference
        @discussion Releases ownership (calls CFRelease) before nullifying the pointer.
    */
    void reset()
    {
        wxCFRelease(m_ptr);
        m_ptr = NULL;
    }

    /*! @method     reset
        @abstract   Sets this to a new reference
        @templatefield otherType    Any type.
        @param p        The raw pointer to assume ownership of
        @discussion The existing reference is released (like destruction).  It is assumed that the caller
                    has a strong reference to the new p and intends to transfer ownership of that reference
                    to this ref holder.  Take care to call CFRetain if you received the object from a Get method.
                    This method is templated and takes an otherType *p.  This prevents implicit conversion
                    using an operator refType() in a different ref-holding class type.
    */
    template <class otherType>
    void reset(otherType* p)
    {
        wxCFRelease(m_ptr);
        m_ptr = p; // Automatic conversion should occur
    }

    // Release the pointer, i.e. give up its ownership.
    refType release()
    {
        refType p = m_ptr;
        m_ptr = NULL;
        return p;
    }

protected:
    /*! @var m_ptr      The raw pointer.
    */
    refType m_ptr;
};

/*! @function   wxCFRefFromGet
    @abstract   Factory function to create wxCFRef from a raw pointer obtained from a Get-rule function
    @param  p           The pointer to retain and create a wxCFRef from.  May be NULL.
    @discussion Unlike the wxCFRef raw pointer constructor, this function explicitly retains its
                argument.  This can be used for functions such as CFDictionaryGetValue() or
                CFAttributedStringGetString() which return a temporary reference (Get-rule functions).
                FIXME: Anybody got a better name?
*/
template <typename Type>
inline wxCFRef<Type*> wxCFRefFromGet(Type *p)
{
    return wxCFRef<Type*>(wxCFRetain(p));
}

/*! @function   static_cfref_cast
    @abstract   Works like static_cast but with a wxCFRef as the argument.
    @param  refType     Template parameter.  The destination raw pointer type
    @param  otherRef    Normal parameter.  The source wxCFRef<> object.
    @discussion This is intended to be a clever way to make static_cast work while allowing
                the return value to be converted to either a strong ref or a raw pointer
                while ensuring that the retain count is updated appropriately.

                This is modeled after shared_ptr's static_pointer_cast.  Just as wxCFRef is
                parameterized on a pointer to an opaque type so is this class.  Note that
                this differs from shared_ptr which is parameterized on the pointee type.

                FIXME: Anybody got a better name?
*/
template <class refType, class otherRefType>
inline wxCFWeakRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);

template <class refType, class otherRefType>
inline wxCFWeakRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef)
{
    return wxCFWeakRef<refType>(static_cast<refType>(otherRef.get()));
}

/*! @function   CFRelease
    @abstract   Overloads CFRelease so that the user is warned of bad behaviour.
    @discussion It is rarely appropriate to retain or release a wxCFRef.  If one absolutely
                must do it he can explicitly get() the raw pointer
                Normally, this function is unimplemented resulting in a linker error if used.
*/
template <class T>
inline void CFRelease(const wxCFRef<T*> & cfref) DEPRECATED_ATTRIBUTE;

/*! @function   CFRetain
    @abstract   Overloads CFRetain so that the user is warned of bad behaviour.
    @discussion It is rarely appropriate to retain or release a wxCFRef.  If one absolutely
                must do it he can explicitly get() the raw pointer
                Normally, this function is unimplemented resulting in a linker error if used.
*/
template <class T>
inline void CFRetain(const wxCFRef<T*>& cfref) DEPRECATED_ATTRIBUTE;

// Change the 0 to a 1 if you want the functions to work (no link errors)
// Neither function will cause retain/release side-effects if implemented.
#if 0
template <class T>
void CFRelease(const wxCFRef<T*> & cfref)
{
    CFRelease(cfref.get());
}

template <class T>
void CFRetain(const wxCFRef<T*> & cfref)
{
    CFRetain(cfref.get());
}
#endif

#endif //ndef _WX_MAC_COREFOUNDATION_CFREF_H__