415 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			415 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /////////////////////////////////////////////////////////////////////////////
 | |
| // 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.
 | |
|      @param p        The raw core foundation reference 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 function.
 | |
|      */
 | |
|     wxCFRef(refType p) : m_ptr(p)
 | |
|     {
 | |
|         
 | |
|     }
 | |
|     /*! @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 function.
 | |
|                     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->
 | |
|         @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__
 | |
| 
 |