]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/mac/corefoundation/cfref.h
wxChar -> char
[wxWidgets.git] / include / wx / mac / corefoundation / cfref.h
index 29485f4325e76388d47a8382facd2c6135e237ca..fb84f0fc5c96183f39ed7c8c38ec056802e2fc11 100644 (file)
@@ -2,10 +2,10 @@
 // Name:        wx/mac/corefoundation/cfref.h
 // Purpose:     wxCFRef template class
 // Author:      David Elliott <dfe@cox.net>
 // Name:        wx/mac/corefoundation/cfref.h
 // Purpose:     wxCFRef template class
 // Author:      David Elliott <dfe@cox.net>
-// Modified by: 
+// Modified by: Stefan Csomor
 // Created:     2007/05/10
 // RCS-ID:      $Id$
 // Created:     2007/05/10
 // RCS-ID:      $Id$
-// Copyright:   (c) 2007 David Elliott <dfe@cox.net>
+// 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
 /////////////////////////////////////////////////////////////////////////////
 // Licence:     wxWindows licence
 // Notes:       See http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/index.html
 /////////////////////////////////////////////////////////////////////////////
 #ifndef _WX_MAC_COREFOUNDATION_CFREF_H__
 #define _WX_MAC_COREFOUNDATION_CFREF_H__
 
 #ifndef _WX_MAC_COREFOUNDATION_CFREF_H__
 #define _WX_MAC_COREFOUNDATION_CFREF_H__
 
-#include <CoreFoundation/CFBase.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.
+ */
+extern "C" {
+typedef const void *CFTypeRef;
+extern /* CF_EXPORT */
+CFTypeRef CFRetain(CFTypeRef cf);
+extern /* CF_EXPORT */
+void CFRelease(CFTypeRef cf);
+} // extern "C"
 
 
-/*! @class wxCFRef
+
+/*! @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.
     @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
+    @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>
 */
 template <class refType>
-class wxCFRef
+class wxCFWeakRef
 {
 {
-    // Declare wxCFRef<otherRefType> as a friend so that the conversion constructor can access m_ptr directly
+    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>
     template <class otherRefType>
-    friend class wxCFRef;
+    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
 public:
     /*! @method     wxCFRef
         @abstract   Creates a NULL reference
@@ -65,11 +185,8 @@ public:
                     the object will be explicitly retained by this new ref.
     */
     wxCFRef(const wxCFRef& otherRef)
                     the object will be explicitly retained by this new ref.
     */
     wxCFRef(const wxCFRef& otherRef)
-    :   m_ptr(otherRef.m_ptr)
-    {
-        if(m_ptr != NULL)
-            CFRetain(m_ptr);
-    }
+    :   m_ptr(wxCFRetain(otherRef.m_ptr))
+    {}
 
     /*! @method     wxCFRef
         @abstract   Copies a ref holder where its type can be converted to ours
 
     /*! @method     wxCFRef
         @abstract   Copies a ref holder where its type can be converted to ours
@@ -80,11 +197,21 @@ public:
     */
     template <class otherRefType>
     wxCFRef(const wxCFRef<otherRefType>& otherRef)
     */
     template <class otherRefType>
     wxCFRef(const wxCFRef<otherRefType>& otherRef)
-    :   m_ptr(otherRef.m_ptr) // Implicit conversion from otherRefType to refType should occur
-    {
-        if(m_ptr != NULL)
-            CFRetain(m_ptr);
-    }
+    :   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.
 
     /*! @method     ~wxCFRef
         @abstract   Releases (potentially shared) ownership of the ref.
@@ -102,10 +229,8 @@ public:
     */
     wxCFRef& operator=(const wxCFRef& otherRef)
     {
     */
     wxCFRef& operator=(const wxCFRef& otherRef)
     {
-        if(otherRef.m_ptr != NULL)
-            CFRetain(otherRef.m_ptr);
-        if(m_ptr != NULL)
-            CFRelease(m_ptr);
+        wxCFRetain(otherRef.m_ptr);
+        wxCFRelease(m_ptr);
         m_ptr = otherRef.m_ptr;
         return *this;
     }
         m_ptr = otherRef.m_ptr;
         return *this;
     }
@@ -120,11 +245,9 @@ public:
     template <class otherRefType>
     wxCFRef& operator=(const wxCFRef<otherRefType>& otherRef)
     {
     template <class otherRefType>
     wxCFRef& operator=(const wxCFRef<otherRefType>& otherRef)
     {
-        if(otherRef.m_ptr != NULL)
-            CFRetain(otherRef.m_ptr);
-        if(m_ptr != NULL)
-            CFRelease(m_ptr);
-        m_ptr = otherRef.m_ptr; // Implicit conversion from otherRefType to refType should occur
+        wxCFRetain(otherRef.get());
+        wxCFRelease(m_ptr);
+        m_ptr = otherRef.get(); // Implicit conversion from otherRefType to refType should occur
         return *this;
     }
 
         return *this;
     }
 
@@ -160,8 +283,7 @@ public:
     */
     void reset()
     {
     */
     void reset()
     {
-        if(m_ptr != NULL)
-            CFRelease(m_ptr);
+        wxCFRelease(m_ptr);
         m_ptr = NULL;
     }
 
         m_ptr = NULL;
     }
 
@@ -178,8 +300,7 @@ public:
     template <class otherType>
     void reset(otherType* p)
     {
     template <class otherType>
     void reset(otherType* p)
     {
-        if(m_ptr != NULL)
-            CFRelease(m_ptr);
+        wxCFRelease(m_ptr);
         m_ptr = p; // Automatic conversion should occur
     }
 protected:
         m_ptr = p; // Automatic conversion should occur
     }
 protected:
@@ -199,25 +320,30 @@ protected:
 template <typename Type>
 inline wxCFRef<Type*> wxCFRefFromGet(Type *p)
 {
 template <typename Type>
 inline wxCFRef<Type*> wxCFRefFromGet(Type *p)
 {
-    return wxCFRef<Type*>( (p!=NULL) ? (Type*)CFRetain(p) : p );
+    return wxCFRef<Type*>(wxCFRetain(p));
 }
 
 /*! @function   static_cfref_cast
 }
 
 /*! @function   static_cfref_cast
-    @abstract   Works like static_cast but from one wxCFRef to another
+    @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.
     @param  refType     Template parameter.  The destination raw pointer type
     @param  otherRef    Normal parameter.  The source wxCFRef<> object.
-    @discussion This is modeled after shared_ptr's static_pointer_cast.  Just as wxCFRef is
+    @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.
                 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>
                 FIXME: Anybody got a better name?
 */
 template <class refType, class otherRefType>
-inline wxCFRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);
+inline wxCFWeakRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef);
 
 template <class refType, class otherRefType>
 
 template <class refType, class otherRefType>
-inline wxCFRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef)
+inline wxCFWeakRef<refType> static_cfref_cast(const wxCFRef<otherRefType> &otherRef)
 {
 {
-    return wxCFRef<refType>(static_cast<refType>(CFRetain(otherRef.get())));
+    return wxCFWeakRef<refType>(static_cast<refType>(otherRef.get()));
 }
 
 /*! @function   CFRelease
 }
 
 /*! @function   CFRelease