Improve static_cfref_cast so that it can be used without causing an unnecessary retain/release in the case when one is only using the cast to convert to a more-derived raw CF ref type.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47384 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
aa25b7f983
commit
64dfdfa28b
@ -58,6 +58,92 @@ inline Type* wxCFRetain(Type *r)
|
|||||||
return 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
|
/*! @class wxCFRef
|
||||||
@templatefield refType The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
|
@templatefield refType The CF reference type (e.g. CFStringRef, CFRunLoopRef, etc.)
|
||||||
It should already be a pointer. This is different from
|
It should already be a pointer. This is different from
|
||||||
@ -114,6 +200,19 @@ public:
|
|||||||
: m_ptr(wxCFRetain(otherRef.get())) // Implicit conversion from otherRefType to refType should occur
|
: 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
|
/*! @method ~wxCFRef
|
||||||
@abstract Releases (potentially shared) ownership of the ref.
|
@abstract Releases (potentially shared) ownership of the ref.
|
||||||
@discussion A ref holder instance is always assumed to have ownership so ownership is always
|
@discussion A ref holder instance is always assumed to have ownership so ownership is always
|
||||||
@ -225,21 +324,26 @@ inline wxCFRef<Type*> wxCFRefFromGet(Type *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 refType Template parameter. The destination raw pointer type
|
||||||
@param otherRef Normal parameter. The source wxCFRef<> object.
|
@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
|
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.
|
this differs from shared_ptr which is parameterized on the pointee type.
|
||||||
|
|
||||||
FIXME: Anybody got a better name?
|
FIXME: Anybody got a better name?
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
||||||
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>(wxCFRetain(otherRef.get())));
|
return wxCFWeakRef<refType>(static_cast<refType>(otherRef.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @function CFRelease
|
/*! @function CFRelease
|
||||||
|
Loading…
Reference in New Issue
Block a user