-/////////////////////////////////////////////////////////////////////////////
-// Name: wx/mac/corefoundation/cfref.h
-// Purpose: wxCFRef template class
-// Author: David Elliott <dfe@cox.net>
-// Modified by: Stefan Csomor
-// Created: 2007/05/10
-// RCS-ID: $Id$
-// 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/mac/corefoundation/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 behavior. 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)
- {
- 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
- }
-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 behavior.
- @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 behavior.
- @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__
-