зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1056356 - Add support for nsRefPtr<const T>. r=froydnj
--HG-- extra : rebase_source : 7b86c6e7bc47c7b3ebc19075559cf0f7d24ededf
This commit is contained in:
Родитель
82a19a631c
Коммит
1ad5e05028
|
@ -29,7 +29,7 @@ private:
|
|||
assign_with_AddRef(T* aRawPtr)
|
||||
{
|
||||
if (aRawPtr) {
|
||||
aRawPtr->AddRef();
|
||||
AddRefTraits<T>::AddRef(aRawPtr);
|
||||
}
|
||||
assign_assuming_AddRef(aRawPtr);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ private:
|
|||
T* oldPtr = mRawPtr;
|
||||
mRawPtr = aNewPtr;
|
||||
if (oldPtr) {
|
||||
oldPtr->Release();
|
||||
AddRefTraits<T>::Release(oldPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public:
|
|||
~nsRefPtr()
|
||||
{
|
||||
if (mRawPtr) {
|
||||
mRawPtr->Release();
|
||||
AddRefTraits<T>::Release(mRawPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public:
|
|||
// copy-constructor
|
||||
{
|
||||
if (mRawPtr) {
|
||||
mRawPtr->AddRef();
|
||||
AddRefTraits<T>::AddRef(mRawPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public:
|
|||
: mRawPtr(aRawPtr)
|
||||
{
|
||||
if (mRawPtr) {
|
||||
mRawPtr->AddRef();
|
||||
AddRefTraits<T>::AddRef(mRawPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,16 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
MOZ_IMPLICIT nsRefPtr(const nsRefPtr<I>& aSmartPtr)
|
||||
: mRawPtr(aSmartPtr.get())
|
||||
// copy-construct from a smart pointer with a related pointer type
|
||||
{
|
||||
if (mRawPtr) {
|
||||
AddRefTraits<T>::AddRef(mRawPtr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
MOZ_IMPLICIT nsRefPtr(nsRefPtr<I>&& aSmartPtr)
|
||||
: mRawPtr(aSmartPtr.forget().take())
|
||||
|
@ -134,6 +144,15 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
nsRefPtr<T>&
|
||||
operator=(const nsRefPtr<I>& aRhs)
|
||||
// assign from an nsRefPtr of a related pointer type
|
||||
{
|
||||
assign_with_AddRef(aRhs.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsRefPtr<T>&
|
||||
operator=(T* aRhs)
|
||||
// assign from a raw pointer (of the right type)
|
||||
|
@ -307,6 +326,35 @@ public:
|
|||
assign_assuming_AddRef(0);
|
||||
return reinterpret_cast<T**>(&mRawPtr);
|
||||
}
|
||||
private:
|
||||
// This helper class makes |nsRefPtr<const T>| possible by casting away
|
||||
// the constness from the pointer when calling AddRef() and Release().
|
||||
// This is necessary because AddRef() and Release() implementations can't
|
||||
// generally expected to be const themselves (without heavy use of |mutable|
|
||||
// and |const_cast| in their own implementations).
|
||||
// This should be sound because while |nsRefPtr<const T>| provides a const
|
||||
// view of an object, the object itself should be const (it would have to be
|
||||
// allocated as |new const T| or similar to itself be const).
|
||||
template<class U>
|
||||
struct AddRefTraits
|
||||
{
|
||||
static void AddRef(U* aPtr) {
|
||||
aPtr->AddRef();
|
||||
}
|
||||
static void Release(U* aPtr) {
|
||||
aPtr->Release();
|
||||
}
|
||||
};
|
||||
template<class U>
|
||||
struct AddRefTraits<const U>
|
||||
{
|
||||
static void AddRef(const U* aPtr) {
|
||||
const_cast<U*>(aPtr)->AddRef();
|
||||
}
|
||||
static void Release(const U* aPtr) {
|
||||
const_cast<U*>(aPtr)->Release();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
|
|
|
@ -32,6 +32,9 @@ class Foo : public nsISupports
|
|||
virtual void VirtualConstMemberFunction( int, int*, int& ) const;
|
||||
static void print_totals();
|
||||
|
||||
void NonconstMethod() {}
|
||||
void ConstMethod() const {}
|
||||
|
||||
private:
|
||||
unsigned int refcount_;
|
||||
|
||||
|
@ -613,8 +616,25 @@ main()
|
|||
AVoidPtrPtrContext( getter_AddRefs(fooP) );
|
||||
}
|
||||
|
||||
{
|
||||
printf("\n### setup for Test 25\n");
|
||||
nsRefPtr<Foo> fooP(new Foo);
|
||||
|
||||
printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
|
||||
printf("### Test 25: can you construct an |nsRefPtr<const T>| from an |nsRefPtr<T>|?\n");
|
||||
nsRefPtr<const Foo> constFooP = fooP;
|
||||
|
||||
printf("### Test 25: can you call a non-const method on an |nsRefPtr<const T>|?\n");
|
||||
constFooP->ConstMethod();
|
||||
|
||||
// [Shouldn't compile] Is it a compile time error to call a non-const method on an |nsRefPtr<const T>|?
|
||||
//constFooP->NonconstMethod();
|
||||
|
||||
// [Shouldn't compile] Is it a compile time error to construct an |nsRefPtr<T> from an |nsRefPtr<const T>|?
|
||||
//nsRefPtr<Foo> otherFooP(constFooP);
|
||||
}
|
||||
|
||||
|
||||
printf("\n### Test 26: will a static |nsCOMPtr| |Release| before program termination?\n");
|
||||
gFoop = do_QueryObject(new Foo);
|
||||
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче