diff --git a/xpcom/base/nsCOMPtr.cpp b/xpcom/base/nsCOMPtr.cpp index ad26d0bc404..1d9598a7dc2 100644 --- a/xpcom/base/nsCOMPtr.cpp +++ b/xpcom/base/nsCOMPtr.cpp @@ -62,43 +62,6 @@ nsCOMPtr_base::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& i mRawPtr = newRawPtr; } - -#if 0 -void -nsCOMPtr_base::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 = rawPtr; - - if ( result ) - *result = status; - } - -void -nsCOMPtr_base::assign_with_QueryReferent( nsIWeakReference* weakPtr, const nsIID& iid, nsresult* result ) - { - nsresult status = NS_ERROR_NULL_POINTER; - - nsISupports* rawPtr; - if ( !weakPtr || !NS_SUCCEEDED( status = weakPtr->QueryReferent(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) ) - rawPtr = 0; - - if ( mRawPtr ) - NSCAP_RELEASE(mRawPtr); - - mRawPtr = rawPtr; - - if ( result ) - *result = status; - } -#endif - void** nsCOMPtr_base::begin_assignment() { diff --git a/xpcom/base/nsCOMPtr.h b/xpcom/base/nsCOMPtr.h index 2d0e7bd2871..a2b6efeb9c6 100644 --- a/xpcom/base/nsCOMPtr.h +++ b/xpcom/base/nsCOMPtr.h @@ -140,8 +140,6 @@ #define NSCAP_FEATURE_INLINE_STARTASSIGNMENT // under VC++, we win by inlining StartAssignment - // but we need to diable the tons of bogus warnings - #pragma warning( disable: 4514 ) #endif #define NSCAP_FEATURE_FACTOR_DESTRUCTOR @@ -310,7 +308,7 @@ class nsCOMPtr_helper - (except for its name) operator() is a valid [XP]COM `getter' - that interface pointer it returns is already |AddRef()|ed (as from any good getter) - it matches the type requested with the supplied |nsIID| argument - - it's constructor provides an optional |nsresult*| that |operator()| can fill + - its constructor provides an optional |nsresult*| that |operator()| can fill in with an error when it is executed See |class nsQueryInterface| for an example. @@ -447,8 +445,6 @@ class nsCOMPtr private: void assign_with_AddRef( nsISupports* ); void assign_from_helper( const nsCOMPtr_helper&, const nsIID& ); -// void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); -// void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); void** begin_assignment(); private: @@ -467,6 +463,7 @@ class nsCOMPtr { if ( mRawPtr ) NSCAP_RELEASE(mRawPtr); + mRawPtr = 0; } #endif @@ -476,12 +473,6 @@ class nsCOMPtr // nothing else to do here } - nsCOMPtr( const nsCOMPtr_helper& helper ) - : NSCAP_CTOR_BASE(0) - { - assign_from_helper(helper, NS_GET_IID(T)); - } - #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES void Assert_NoQueryNeeded() @@ -501,6 +492,13 @@ class nsCOMPtr #define NSCAP_ASSERT_NO_QUERY_NEEDED(); #endif + nsCOMPtr( const nsCOMPtr_helper& helper ) + : NSCAP_CTOR_BASE(0) + { + assign_from_helper(helper, NS_GET_IID(T)); + NSCAP_ASSERT_NO_QUERY_NEEDED(); + } + nsCOMPtr( const nsDontAddRef& aSmartPtr ) : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr) { @@ -544,6 +542,7 @@ class nsCOMPtr operator=( const nsCOMPtr_helper& rhs ) { assign_from_helper(rhs, NS_GET_IID(T)); + NSCAP_ASSERT_NO_QUERY_NEEDED(); return *this; } @@ -620,6 +619,121 @@ class nsCOMPtr } }; +// template <> +class nsCOMPtr + : private nsCOMPtr_base + { + public: + typedef nsISupports element_type; + +#ifndef NSCAP_FEATURE_FACTOR_DESTRUCTOR + ~nsCOMPtr() + { + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = 0; + } +#endif + + nsCOMPtr() + : nsCOMPtr_base(0) + { + // nothing else to do here + } + + nsCOMPtr( const nsCOMPtr_helper& helper ) + : nsCOMPtr_base(0) + { + assign_from_helper(helper, NS_GET_IID(T)); + } + + nsCOMPtr( const nsDontQueryInterface& aSmartPtr ) + : nsCOMPtr_base(aSmartPtr.mRawPtr) + { + // nothing else to do here + } + + nsCOMPtr( const nsCOMPtr& aSmartPtr ) + : nsCOMPtr_base(aSmartPtr.mRawPtr) + { + if ( mRawPtr ) + NSCAP_ADDREF(mRawPtr); + } + + nsCOMPtr( nsISupports* aRawPtr ) + : nsCOMPtr_base(aRawPtr) + { + if ( mRawPtr ) + NSCAP_ADDREF(mRawPtr); + } + + nsCOMPtr& + operator=( nsISupports* rhs ) + { + assign_with_AddRef(rhs); + return *this; + } + + nsCOMPtr& + operator=( const nsCOMPtr_helper& rhs ) + { + assign_from_helper(rhs, NS_GET_IID(T)); + return *this; + } + + nsCOMPtr& + operator=( const nsDontQueryInterface& rhs ) + { + assign_with_AddRef(rhs.mRawPtr); + return *this; + } + + nsCOMPtr& + operator=( const nsCOMPtr& rhs ) + { + assign_with_AddRef(rhs.mRawPtr); + return *this; + } + + nsDerivedSafe* + get() const + { + return NSCAP_REINTERPRET_CAST(nsDerivedSafe*, mRawPtr); + } + + nsDerivedSafe* + operator->() const + { + NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->()."); + return get(); + } + + nsDerivedSafe& + operator*() const + { + NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*()."); + return *get(); + } + + operator nsDerivedSafe*() const + { + return get(); + } + + nsISupports** + StartAssignment() + { +#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT + return NSCAP_REINTERPRET_CAST(nsISupports**, begin_assignment()); +#else + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = 0; + return NSCAP_REINTERPRET_CAST(nsISupports**, &mRawPtr); +#endif + } + }; + #ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES template void @@ -687,11 +801,13 @@ class nsGetterAddRefs // nothing else to do } +#if 0 #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES ~nsGetterAddRefs() { - // mTargetSmartPtr.Assert_NoQueryNeeded(); + mTargetSmartPtr.Assert_NoQueryNeeded(); } +#endif #endif operator void**() @@ -710,10 +826,48 @@ class nsGetterAddRefs return mTargetSmartPtr.StartAssignment(); } + operator nsISupports**() + { + return NSCAP_REINTERPRET_CAST(nsISupports**, mTargetSmartPtr.StartAssignment()); + } + private: nsCOMPtr& mTargetSmartPtr; }; + +// template <> +class nsGetterAddRefs + { + public: + explicit + nsGetterAddRefs( nsCOMPtr& aSmartPtr ) + : mTargetSmartPtr(aSmartPtr) + { + // nothing else to do + } + + operator void**() + { + return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment()); + } + + nsISupports*& + operator*() + { + return *(mTargetSmartPtr.StartAssignment()); + } + + operator nsISupports**() + { + return mTargetSmartPtr.StartAssignment(); + } + + private: + nsCOMPtr& mTargetSmartPtr; + }; + + template inline nsGetterAddRefs diff --git a/xpcom/glue/nsCOMPtr.cpp b/xpcom/glue/nsCOMPtr.cpp index ad26d0bc404..1d9598a7dc2 100644 --- a/xpcom/glue/nsCOMPtr.cpp +++ b/xpcom/glue/nsCOMPtr.cpp @@ -62,43 +62,6 @@ nsCOMPtr_base::assign_from_helper( const nsCOMPtr_helper& helper, const nsIID& i mRawPtr = newRawPtr; } - -#if 0 -void -nsCOMPtr_base::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 = rawPtr; - - if ( result ) - *result = status; - } - -void -nsCOMPtr_base::assign_with_QueryReferent( nsIWeakReference* weakPtr, const nsIID& iid, nsresult* result ) - { - nsresult status = NS_ERROR_NULL_POINTER; - - nsISupports* rawPtr; - if ( !weakPtr || !NS_SUCCEEDED( status = weakPtr->QueryReferent(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) ) - rawPtr = 0; - - if ( mRawPtr ) - NSCAP_RELEASE(mRawPtr); - - mRawPtr = rawPtr; - - if ( result ) - *result = status; - } -#endif - void** nsCOMPtr_base::begin_assignment() { diff --git a/xpcom/glue/nsCOMPtr.h b/xpcom/glue/nsCOMPtr.h index 2d0e7bd2871..a2b6efeb9c6 100644 --- a/xpcom/glue/nsCOMPtr.h +++ b/xpcom/glue/nsCOMPtr.h @@ -140,8 +140,6 @@ #define NSCAP_FEATURE_INLINE_STARTASSIGNMENT // under VC++, we win by inlining StartAssignment - // but we need to diable the tons of bogus warnings - #pragma warning( disable: 4514 ) #endif #define NSCAP_FEATURE_FACTOR_DESTRUCTOR @@ -310,7 +308,7 @@ class nsCOMPtr_helper - (except for its name) operator() is a valid [XP]COM `getter' - that interface pointer it returns is already |AddRef()|ed (as from any good getter) - it matches the type requested with the supplied |nsIID| argument - - it's constructor provides an optional |nsresult*| that |operator()| can fill + - its constructor provides an optional |nsresult*| that |operator()| can fill in with an error when it is executed See |class nsQueryInterface| for an example. @@ -447,8 +445,6 @@ class nsCOMPtr private: void assign_with_AddRef( nsISupports* ); void assign_from_helper( const nsCOMPtr_helper&, const nsIID& ); -// void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* ); -// void assign_with_QueryReferent( nsIWeakReference*, const nsIID&, nsresult* ); void** begin_assignment(); private: @@ -467,6 +463,7 @@ class nsCOMPtr { if ( mRawPtr ) NSCAP_RELEASE(mRawPtr); + mRawPtr = 0; } #endif @@ -476,12 +473,6 @@ class nsCOMPtr // nothing else to do here } - nsCOMPtr( const nsCOMPtr_helper& helper ) - : NSCAP_CTOR_BASE(0) - { - assign_from_helper(helper, NS_GET_IID(T)); - } - #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES void Assert_NoQueryNeeded() @@ -501,6 +492,13 @@ class nsCOMPtr #define NSCAP_ASSERT_NO_QUERY_NEEDED(); #endif + nsCOMPtr( const nsCOMPtr_helper& helper ) + : NSCAP_CTOR_BASE(0) + { + assign_from_helper(helper, NS_GET_IID(T)); + NSCAP_ASSERT_NO_QUERY_NEEDED(); + } + nsCOMPtr( const nsDontAddRef& aSmartPtr ) : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr) { @@ -544,6 +542,7 @@ class nsCOMPtr operator=( const nsCOMPtr_helper& rhs ) { assign_from_helper(rhs, NS_GET_IID(T)); + NSCAP_ASSERT_NO_QUERY_NEEDED(); return *this; } @@ -620,6 +619,121 @@ class nsCOMPtr } }; +// template <> +class nsCOMPtr + : private nsCOMPtr_base + { + public: + typedef nsISupports element_type; + +#ifndef NSCAP_FEATURE_FACTOR_DESTRUCTOR + ~nsCOMPtr() + { + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = 0; + } +#endif + + nsCOMPtr() + : nsCOMPtr_base(0) + { + // nothing else to do here + } + + nsCOMPtr( const nsCOMPtr_helper& helper ) + : nsCOMPtr_base(0) + { + assign_from_helper(helper, NS_GET_IID(T)); + } + + nsCOMPtr( const nsDontQueryInterface& aSmartPtr ) + : nsCOMPtr_base(aSmartPtr.mRawPtr) + { + // nothing else to do here + } + + nsCOMPtr( const nsCOMPtr& aSmartPtr ) + : nsCOMPtr_base(aSmartPtr.mRawPtr) + { + if ( mRawPtr ) + NSCAP_ADDREF(mRawPtr); + } + + nsCOMPtr( nsISupports* aRawPtr ) + : nsCOMPtr_base(aRawPtr) + { + if ( mRawPtr ) + NSCAP_ADDREF(mRawPtr); + } + + nsCOMPtr& + operator=( nsISupports* rhs ) + { + assign_with_AddRef(rhs); + return *this; + } + + nsCOMPtr& + operator=( const nsCOMPtr_helper& rhs ) + { + assign_from_helper(rhs, NS_GET_IID(T)); + return *this; + } + + nsCOMPtr& + operator=( const nsDontQueryInterface& rhs ) + { + assign_with_AddRef(rhs.mRawPtr); + return *this; + } + + nsCOMPtr& + operator=( const nsCOMPtr& rhs ) + { + assign_with_AddRef(rhs.mRawPtr); + return *this; + } + + nsDerivedSafe* + get() const + { + return NSCAP_REINTERPRET_CAST(nsDerivedSafe*, mRawPtr); + } + + nsDerivedSafe* + operator->() const + { + NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->()."); + return get(); + } + + nsDerivedSafe& + operator*() const + { + NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*()."); + return *get(); + } + + operator nsDerivedSafe*() const + { + return get(); + } + + nsISupports** + StartAssignment() + { +#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT + return NSCAP_REINTERPRET_CAST(nsISupports**, begin_assignment()); +#else + if ( mRawPtr ) + NSCAP_RELEASE(mRawPtr); + mRawPtr = 0; + return NSCAP_REINTERPRET_CAST(nsISupports**, &mRawPtr); +#endif + } + }; + #ifdef NSCAP_FEATURE_DEBUG_PTR_TYPES template void @@ -687,11 +801,13 @@ class nsGetterAddRefs // nothing else to do } +#if 0 #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES ~nsGetterAddRefs() { - // mTargetSmartPtr.Assert_NoQueryNeeded(); + mTargetSmartPtr.Assert_NoQueryNeeded(); } +#endif #endif operator void**() @@ -710,10 +826,48 @@ class nsGetterAddRefs return mTargetSmartPtr.StartAssignment(); } + operator nsISupports**() + { + return NSCAP_REINTERPRET_CAST(nsISupports**, mTargetSmartPtr.StartAssignment()); + } + private: nsCOMPtr& mTargetSmartPtr; }; + +// template <> +class nsGetterAddRefs + { + public: + explicit + nsGetterAddRefs( nsCOMPtr& aSmartPtr ) + : mTargetSmartPtr(aSmartPtr) + { + // nothing else to do + } + + operator void**() + { + return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment()); + } + + nsISupports*& + operator*() + { + return *(mTargetSmartPtr.StartAssignment()); + } + + operator nsISupports**() + { + return mTargetSmartPtr.StartAssignment(); + } + + private: + nsCOMPtr& mTargetSmartPtr; + }; + + template inline nsGetterAddRefs