new feature lets you `see past' |nsISupports| in |nsCOMPtr|s. Now in the debugger (in debug versions only) you will see the actual type of the object. This is enabled by defining the preprocessor symbol |NSCAP_FEATURE_DEBUG_PTR_TYPES|. It cannot be turned on in non-debug builds. It is currently on in debug builds by default. It may become a feature that has to be enabled with a build command line switch.

This commit is contained in:
scc%netscape.com 1999-07-15 03:59:09 +00:00
Родитель aab306a649
Коммит a9bb3d6a16
2 изменённых файлов: 212 добавлений и 156 удалений

Просмотреть файл

@ -69,7 +69,6 @@
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
@ -114,12 +113,19 @@
// under VC++, we win by inlining StartAssignment
#endif
#define NSCAP_FEATURE_ALLOW_RAW_POINTERS
#define NSCAP_FEATURE_ALLOW_COMPARISONS
#define NSCAP_FEATURE_FACTOR_DESTRUCTOR
#ifdef NS_DEBUG
#define NSCAP_FEATURE_TEST_DONTQUERY_CASES
#define NSCAP_FEATURE_DEBUG_PTR_TYPES
#endif
#ifndef NS_DEBUG
#undef NSCAP_FEATURE_DEBUG_PTR_TYPES
#endif
#ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES
#undef NSCAP_FEATURE_FACTOR_DESTRUCTOR
#endif
@ -189,7 +195,8 @@ class nsDerivedSafe : public T
void operator delete( void*, size_t ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
// nsDerivedSafe<T>& operator=( const T& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
@ -219,6 +226,8 @@ struct nsDontQueryInterface
...
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |dont_QueryInterface()| instead.
This type should be a nested class inside |nsCOMPtr<T>|.
*/
{
explicit
@ -268,26 +277,7 @@ do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
return nsQueryInterface(aRawPtr, error);
}
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
#define null_nsCOMPtr() (0)
#else
inline
const nsQueryInterface
null_nsCOMPtr()
/*
You can use this to assign |NULL| into an |nsCOMPtr|, e.g.,
myPtr = null_nsCOMPtr();
*/
{
typedef nsISupports* nsISupports_Ptr;
return nsQueryInterface(nsISupports_Ptr(0));
}
#endif
#define null_nsCOMPtr() (0)
@ -303,6 +293,8 @@ struct nsDontAddRef
|dont_AddRef()| instead.
See also |getter_AddRefs()|, |dont_AddRef()|, and |class nsGetterAddRefs|.
This type should be a nested class inside |nsCOMPtr<T>|.
*/
{
explicit
@ -354,14 +346,6 @@ class nsCOMPtr_base
NS_EXPORT ~nsCOMPtr_base();
#endif
#if 0
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
#endif
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
@ -373,19 +357,28 @@ class nsCOMPtr_base
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
class nsCOMPtr
#ifndef NSCAP_FEATURE_DEBUG_PTR_TYPES
: private nsCOMPtr_base
#endif
{
#ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES
private:
void assign_with_AddRef( nsISupports* );
void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
void** begin_assignment();
private:
T* mRawPtr;
#define NSCAP_CTOR_BASE(x) mRawPtr(x)
#else
#define NSCAP_CTOR_BASE(x) nsCOMPtr_base(x)
#endif
public:
typedef T element_type;
#if 0
typedef nsDerivedSafe<T>* safe_ptr_t;
typedef T* safe_ptr_t;
#endif
#ifndef NSCAP_FEATURE_FACTOR_DESTRUCTOR
~nsCOMPtr()
{
@ -395,13 +388,13 @@ class nsCOMPtr : private nsCOMPtr_base
#endif
nsCOMPtr()
// : nsCOMPtr_base(0)
: NSCAP_CTOR_BASE(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
: NSCAP_CTOR_BASE(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, nsCOMTypeInfo<T>::GetIID(), aSmartPtr.mErrorPtr);
}
@ -410,62 +403,59 @@ class nsCOMPtr : private nsCOMPtr_base
void
Assert_NoQueryNeeded()
{
if ( !mRawPtr )
return;
T* query_result = 0;
nsresult status = CallQueryInterface(mRawPtr, &query_result);
NS_ASSERTION(query_result == mRawPtr, "QueryInterface needed");
if ( NS_SUCCEEDED(status) )
NSCAP_RELEASE(query_result);
if ( mRawPtr )
{
T* query_result = 0;
nsresult status = CallQueryInterface(mRawPtr, &query_result);
NS_ASSERTION(query_result == mRawPtr, "QueryInterface needed");
if ( NS_SUCCEEDED(status) )
NSCAP_RELEASE(query_result);
}
}
#define NSCAP_ASSERT_NO_QUERY_NEEDED(); Assert_NoQueryNeeded();
#else
#define NSCAP_ASSERT_NO_QUERY_NEEDED();
#endif
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
nsCOMPtr( T* aRawPtr )
: nsCOMPtr_base(aRawPtr)
: NSCAP_CTOR_BASE(aRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
nsCOMPtr<T>&
operator=( T* rhs )
{
assign_with_AddRef(rhs);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
return *this;
}
#endif
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
@ -480,9 +470,8 @@ class nsCOMPtr : private nsCOMPtr_base
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
return *this;
}
@ -490,9 +479,7 @@ class nsCOMPtr : private nsCOMPtr_base
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
return *this;
}
@ -560,6 +547,49 @@ class nsCOMPtr : private nsCOMPtr_base
}
};
#ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES
template <class T>
void
nsCOMPtr<T>::assign_with_AddRef( nsISupports* rawPtr )
{
if ( rawPtr )
NSCAP_ADDREF(rawPtr);
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = NS_REINTERPRET_CAST(T*, rawPtr);
}
template <class T>
void
nsCOMPtr<T>::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
{
nsresult status = NS_ERROR_NULL_POINTER;
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
rawPtr = 0;
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = NS_REINTERPRET_CAST(T*, rawPtr);
if ( result )
*result = status;
}
template <class T>
void**
nsCOMPtr<T>::begin_assignment()
{
if ( mRawPtr )
{
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
}
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
}
#endif
template <class T>
class nsGetterAddRefs
@ -577,6 +607,8 @@ class nsGetterAddRefs
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in.
This type should be a nested class inside |nsCOMPtr<T>|.
*/
{
public:
@ -620,8 +652,6 @@ getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
}
#ifdef NSCAP_FEATURE_ALLOW_COMPARISONS
class NSCAP_Zero;
template <class T, class U>
@ -715,8 +745,6 @@ SameCOMIdentity( nsISupports* lhs, nsISupports* rhs )
return nsCOMPtr<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
}
#endif // defined(NSCAP_FEATURE_ALLOW_COMPARISONS)
template <class DestinationType>
inline

Просмотреть файл

@ -69,7 +69,6 @@
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
@ -114,12 +113,19 @@
// under VC++, we win by inlining StartAssignment
#endif
#define NSCAP_FEATURE_ALLOW_RAW_POINTERS
#define NSCAP_FEATURE_ALLOW_COMPARISONS
#define NSCAP_FEATURE_FACTOR_DESTRUCTOR
#ifdef NS_DEBUG
#define NSCAP_FEATURE_TEST_DONTQUERY_CASES
#define NSCAP_FEATURE_DEBUG_PTR_TYPES
#endif
#ifndef NS_DEBUG
#undef NSCAP_FEATURE_DEBUG_PTR_TYPES
#endif
#ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES
#undef NSCAP_FEATURE_FACTOR_DESTRUCTOR
#endif
@ -189,7 +195,8 @@ class nsDerivedSafe : public T
void operator delete( void*, size_t ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
nsDerivedSafe<T>& operator=( const nsDerivedSafe<T>& ); // NOT TO BE IMPLEMENTED
// nsDerivedSafe<T>& operator=( const T& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
@ -219,6 +226,8 @@ struct nsDontQueryInterface
...
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |dont_QueryInterface()| instead.
This type should be a nested class inside |nsCOMPtr<T>|.
*/
{
explicit
@ -268,26 +277,7 @@ do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
return nsQueryInterface(aRawPtr, error);
}
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
#define null_nsCOMPtr() (0)
#else
inline
const nsQueryInterface
null_nsCOMPtr()
/*
You can use this to assign |NULL| into an |nsCOMPtr|, e.g.,
myPtr = null_nsCOMPtr();
*/
{
typedef nsISupports* nsISupports_Ptr;
return nsQueryInterface(nsISupports_Ptr(0));
}
#endif
#define null_nsCOMPtr() (0)
@ -303,6 +293,8 @@ struct nsDontAddRef
|dont_AddRef()| instead.
See also |getter_AddRefs()|, |dont_AddRef()|, and |class nsGetterAddRefs|.
This type should be a nested class inside |nsCOMPtr<T>|.
*/
{
explicit
@ -354,14 +346,6 @@ class nsCOMPtr_base
NS_EXPORT ~nsCOMPtr_base();
#endif
#if 0
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
#endif
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
@ -373,19 +357,28 @@ class nsCOMPtr_base
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
class nsCOMPtr
#ifndef NSCAP_FEATURE_DEBUG_PTR_TYPES
: private nsCOMPtr_base
#endif
{
#ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES
private:
void assign_with_AddRef( nsISupports* );
void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
void** begin_assignment();
private:
T* mRawPtr;
#define NSCAP_CTOR_BASE(x) mRawPtr(x)
#else
#define NSCAP_CTOR_BASE(x) nsCOMPtr_base(x)
#endif
public:
typedef T element_type;
#if 0
typedef nsDerivedSafe<T>* safe_ptr_t;
typedef T* safe_ptr_t;
#endif
#ifndef NSCAP_FEATURE_FACTOR_DESTRUCTOR
~nsCOMPtr()
{
@ -395,13 +388,13 @@ class nsCOMPtr : private nsCOMPtr_base
#endif
nsCOMPtr()
// : nsCOMPtr_base(0)
: NSCAP_CTOR_BASE(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
: NSCAP_CTOR_BASE(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, nsCOMTypeInfo<T>::GetIID(), aSmartPtr.mErrorPtr);
}
@ -410,62 +403,59 @@ class nsCOMPtr : private nsCOMPtr_base
void
Assert_NoQueryNeeded()
{
if ( !mRawPtr )
return;
T* query_result = 0;
nsresult status = CallQueryInterface(mRawPtr, &query_result);
NS_ASSERTION(query_result == mRawPtr, "QueryInterface needed");
if ( NS_SUCCEEDED(status) )
NSCAP_RELEASE(query_result);
if ( mRawPtr )
{
T* query_result = 0;
nsresult status = CallQueryInterface(mRawPtr, &query_result);
NS_ASSERTION(query_result == mRawPtr, "QueryInterface needed");
if ( NS_SUCCEEDED(status) )
NSCAP_RELEASE(query_result);
}
}
#define NSCAP_ASSERT_NO_QUERY_NEEDED(); Assert_NoQueryNeeded();
#else
#define NSCAP_ASSERT_NO_QUERY_NEEDED();
#endif
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
: NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
#ifdef NSCAP_FEATURE_ALLOW_RAW_POINTERS
nsCOMPtr( T* aRawPtr )
: nsCOMPtr_base(aRawPtr)
: NSCAP_CTOR_BASE(aRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
}
nsCOMPtr<T>&
operator=( T* rhs )
{
assign_with_AddRef(rhs);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
return *this;
}
#endif
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
@ -480,9 +470,8 @@ class nsCOMPtr : private nsCOMPtr_base
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
return *this;
}
@ -490,9 +479,7 @@ class nsCOMPtr : private nsCOMPtr_base
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
Assert_NoQueryNeeded();
#endif
NSCAP_ASSERT_NO_QUERY_NEEDED();
return *this;
}
@ -560,6 +547,49 @@ class nsCOMPtr : private nsCOMPtr_base
}
};
#ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES
template <class T>
void
nsCOMPtr<T>::assign_with_AddRef( nsISupports* rawPtr )
{
if ( rawPtr )
NSCAP_ADDREF(rawPtr);
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = NS_REINTERPRET_CAST(T*, rawPtr);
}
template <class T>
void
nsCOMPtr<T>::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
{
nsresult status = NS_ERROR_NULL_POINTER;
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
rawPtr = 0;
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = NS_REINTERPRET_CAST(T*, rawPtr);
if ( result )
*result = status;
}
template <class T>
void**
nsCOMPtr<T>::begin_assignment()
{
if ( mRawPtr )
{
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
}
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
}
#endif
template <class T>
class nsGetterAddRefs
@ -577,6 +607,8 @@ class nsGetterAddRefs
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in.
This type should be a nested class inside |nsCOMPtr<T>|.
*/
{
public:
@ -620,8 +652,6 @@ getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
}
#ifdef NSCAP_FEATURE_ALLOW_COMPARISONS
class NSCAP_Zero;
template <class T, class U>
@ -715,8 +745,6 @@ SameCOMIdentity( nsISupports* lhs, nsISupports* rhs )
return nsCOMPtr<nsISupports>( do_QueryInterface(lhs) ) == nsCOMPtr<nsISupports>( do_QueryInterface(rhs) );
}
#endif // defined(NSCAP_FEATURE_ALLOW_COMPARISONS)
template <class DestinationType>
inline