⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nscomptr.h

📁 gaca源码
💻 H
📖 第 1 页 / 共 3 页
字号:
    : private nsCOMPtr_base
#endif
  {

#ifdef NSCAP_FEATURE_USE_BASE
  #define NSCAP_CTOR_BASE(x) nsCOMPtr_base(x)
#else
  #define NSCAP_CTOR_BASE(x) mRawPtr(x)

    private:
      void    assign_with_AddRef( nsISupports* );
      void    assign_from_helper( const nsCOMPtr_helper&, const nsIID& );
      void**  begin_assignment();

      void
      assign_assuming_AddRef( T* newPtr )
        {
          T* oldPtr = mRawPtr;
          mRawPtr = newPtr;
          NSCAP_LOG_ASSIGNMENT(this, newPtr);
          NSCAP_LOG_RELEASE(this, oldPtr);
          if ( oldPtr )
            NSCAP_RELEASE(this, oldPtr);
        }

    private:
      T* mRawPtr;
#endif

    public:
      typedef T element_type;
      
#ifndef NSCAP_FEATURE_USE_BASE
     ~nsCOMPtr()
        {
          NSCAP_LOG_RELEASE(this, mRawPtr);
          if ( mRawPtr )
            NSCAP_RELEASE(this, mRawPtr);
        }
#endif

#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
      void
      Assert_NoQueryNeeded()
        {
          if ( mRawPtr )
            {
              nsCOMPtr<T> query_result( do_QueryInterface(mRawPtr) );
              NS_ASSERTION(query_result.get() == mRawPtr, "QueryInterface needed");
            }
        }

  #define NSCAP_ASSERT_NO_QUERY_NEEDED() Assert_NoQueryNeeded();
#else
  #define NSCAP_ASSERT_NO_QUERY_NEEDED()
#endif


        // Constructors

      nsCOMPtr()
            : NSCAP_CTOR_BASE(0)
          // default constructor
        {
          NSCAP_LOG_ASSIGNMENT(this, 0);
        }

      nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
            : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
          // copy-constructor
        {
          if ( mRawPtr )
            NSCAP_ADDREF(this, mRawPtr);
          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
        }

      nsCOMPtr( T* aRawPtr )
            : NSCAP_CTOR_BASE(aRawPtr)
          // construct from a raw pointer (of the right type)
        {
          if ( mRawPtr )
            NSCAP_ADDREF(this, mRawPtr);
          NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
          NSCAP_ASSERT_NO_QUERY_NEEDED();
        }

      nsCOMPtr( const already_AddRefed<T>& aSmartPtr )
            : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
          // construct from |dont_AddRef(expr)|
        {
          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
          NSCAP_ASSERT_NO_QUERY_NEEDED();
        }

      nsCOMPtr( const nsCOMPtr_helper& helper )
            : NSCAP_CTOR_BASE(0)
          // ...and finally, anything else we might need to construct from
          //  can exploit the |nsCOMPtr_helper| facility
        {
          NSCAP_LOG_ASSIGNMENT(this, 0);
          assign_from_helper(helper, NS_GET_IID(T));
          NSCAP_ASSERT_NO_QUERY_NEEDED();
        }

#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
        // For debug only --- this particular helper doesn't need to do the
        //  |NSCAP_ASSERT_NO_QUERY_NEEDED()| test.  In fact, with the logging
        //  changes, skipping the query test prevents infinite recursion.
      nsCOMPtr( const nsQueryInterface& helper )
            : NSCAP_CTOR_BASE(0)
        {
          NSCAP_LOG_ASSIGNMENT(this, 0);
          assign_from_helper(helper, NS_GET_IID(T));
        }
#endif


        // Assignment operators

      nsCOMPtr<T>&
      operator=( const nsCOMPtr<T>& rhs )
          // copy assignment operator
        {
          assign_with_AddRef(rhs.mRawPtr);
          return *this;
        }

      nsCOMPtr<T>&
      operator=( T* rhs )
          // assign from a raw pointer (of the right type)
        {
          assign_with_AddRef(rhs);
          NSCAP_ASSERT_NO_QUERY_NEEDED();
          return *this;
        }

      nsCOMPtr<T>&
      operator=( const already_AddRefed<T>& rhs )
          // assign from |dont_AddRef(expr)|
        {
          assign_assuming_AddRef(rhs.mRawPtr);
          NSCAP_ASSERT_NO_QUERY_NEEDED();
          return *this;
        }

      nsCOMPtr<T>&
      operator=( const nsCOMPtr_helper& rhs )
          // ...and finally, anything else we might need to assign from
          //  can exploit the |nsCOMPtr_helper| facility.
        {
          assign_from_helper(rhs, NS_GET_IID(T));
          NSCAP_ASSERT_NO_QUERY_NEEDED();
          return *this;
        }

#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
        // For debug only --- this particular helper doesn't need to do the
        //  |NSCAP_ASSERT_NO_QUERY_NEEDED()| test.  In fact, with the logging
        //  changes, skipping the query test prevents infinite recursion.
      nsCOMPtr<T>&
      operator=( const nsQueryInterface& rhs )
        {
          assign_from_helper(rhs, NS_GET_IID(T));
          return *this;
        }
#endif

      void
      swap( nsCOMPtr<T>& rhs )
          // ...exchange ownership with |rhs|; can save a pair of refcount operations
        {
#ifdef NSCAP_FEATURE_USE_BASE
          nsISupports* temp = rhs.mRawPtr;
#else
          T* temp = rhs.mRawPtr;
#endif
          NSCAP_LOG_ASSIGNMENT(&rhs, mRawPtr);
          NSCAP_LOG_ASSIGNMENT(this, temp);
          NSCAP_LOG_RELEASE(this, mRawPtr);
          NSCAP_LOG_RELEASE(&rhs, temp);
          rhs.mRawPtr = mRawPtr;
          mRawPtr = temp;
          // |rhs| maintains the same invariants, so we don't need to |NSCAP_ASSERT_NO_QUERY_NEEDED|
        }

      void
      swap( T*& rhs )
          // ...exchange ownership with |rhs|; can save a pair of refcount operations
        {
#ifdef NSCAP_FEATURE_USE_BASE
          nsISupports* temp = rhs;
#else
          T* temp = rhs;
#endif
          NSCAP_LOG_ASSIGNMENT(this, temp);
          NSCAP_LOG_RELEASE(this, mRawPtr);
          rhs = NS_REINTERPRET_CAST(T*, mRawPtr);
          mRawPtr = temp;
          NSCAP_ASSERT_NO_QUERY_NEEDED();
        }


        // Other pointer operators

      nsDerivedSafe<T>*
      get() const
          /*
            Prefer the implicit conversion provided automatically by |operator nsDerivedSafe<T>*() const|.
             Use |get()| _only_ to resolve ambiguity.

            Returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|.
          */
        {
          return NS_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
        }

      operator nsDerivedSafe<T>*() const
          /*
            ...makes an |nsCOMPtr| act like its underlying raw pointer type (except against |AddRef()|, |Release()|,
              and |delete|) whenever it is used in a context where a raw pointer is expected.  It is this operator
              that makes an |nsCOMPtr| substitutable for a raw pointer.

            Prefer the implicit use of this operator to calling |get()|, except where necessary to resolve ambiguity.
          */
        {
          return get();
        }

      nsDerivedSafe<T>*
      operator->() const
        {
          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
          return get();
        }

#ifdef CANT_RESOLVE_CPP_CONST_AMBIGUITY
  // broken version for IRIX

      nsCOMPtr<T>*
      get_address() const
          // This is not intended to be used by clients.  See |address_of|
          // below.
        {
          return NS_CONST_CAST(nsCOMPtr<T>*, this);
        }

#else // CANT_RESOLVE_CPP_CONST_AMBIGUITY

      nsCOMPtr<T>*
      get_address()
          // This is not intended to be used by clients.  See |address_of|
          // below.
        {
          return this;
        }

      const nsCOMPtr<T>*
      get_address() const
          // This is not intended to be used by clients.  See |address_of|
          // below.
        {
          return this;
        }

#endif // CANT_RESOLVE_CPP_CONST_AMBIGUITY

    public:
      nsDerivedSafe<T>&
      operator*() const
        {
          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
          return *get();
        }

#if 0
    private:
      friend class nsGetterAddRefs<T>;
#endif

      T**
      StartAssignment()
        {
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
          return NS_REINTERPRET_CAST(T**, begin_assignment());
#else
          assign_assuming_AddRef(0);
          return NS_REINTERPRET_CAST(T**, &mRawPtr);
#endif
        }
  };



  /*
    Specializing |nsCOMPtr| for |nsISupports| allows us to use |nsCOMPtr<nsISupports>| the
    same way people use |nsISupports*| and |void*|, i.e., as a `catch-all' pointer pointing
    to any valid [XP]COM interface.  Otherwise, an |nsCOMPtr<nsISupports>| would only be able
    to point to the single [XP]COM-correct |nsISupports| instance within an object; extra
    querying ensues.  Clients need to be able to pass around arbitrary interface pointers,
    without hassles, through intermediary code that doesn't know the exact type.
  */

NS_SPECIALIZE_TEMPLATE
class nsCOMPtr<nsISupports>
    : private nsCOMPtr_base
  {
    public:
      typedef nsISupports element_type;

        // Constructors

      nsCOMPtr()
            : nsCOMPtr_base(0)
          // default constructor
        {
          NSCAP_LOG_ASSIGNMENT(this, 0);
        }

      nsCOMPtr( const nsCOMPtr<nsISupports>& aSmartPtr )
            : nsCOMPtr_base(aSmartPtr.mRawPtr)
          // copy constructor
        {
          if ( mRawPtr )
            NSCAP_ADDREF(this, mRawPtr);
          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
        }

      nsCOMPtr( nsISupports* aRawPtr )
            : nsCOMPtr_base(aRawPtr)
          // construct from a raw pointer (of the right type)
        {
          if ( mRawPtr )
            NSCAP_ADDREF(this, mRawPtr);
          NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
        }

      nsCOMPtr( const already_AddRefed<nsISupports>& aSmartPtr )
            : nsCOMPtr_base(aSmartPtr.mRawPtr)
          // construct from |dont_AddRef(expr)|
        {
          NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
        }

      nsCOMPtr( const nsCOMPtr_helper& helper )
            : nsCOMPtr_base(0)
          // ...and finally, anything else we might need to construct from
          //  can exploit the |nsCOMPtr_helper| facility
        {
          NSCAP_LOG_ASSIGNMENT(this, 0);
          assign_from_helper(helper, NS_GET_IID(nsISupports));
        }


        // Assignment operators

      nsCOMPtr<nsISupports>&
      operator=( const nsCOMPtr<nsISupports>& rhs )
          // copy assignment operator
        {
          assign_with_AddRef(rhs.mRawPtr);
          return *this;
        }

      nsCOMPtr<nsISupports>&
      operator=( nsISupports* rhs )
          // assign from a raw pointer (of the right type)
        {
          assign_with_AddRef(rhs);
          return *this;
        }

      nsCOMPtr<nsISupports>&
      operator=( const already_AddRefed<nsISupports>& rhs )
          // assign from |dont_AddRef(expr)|
        {
          assign_assuming_AddRef(rhs.mRawPtr);
          return *this;
        }

      nsCOMPtr<nsISupports>&
      operator=( const nsCOMPtr_helper& rhs )
          // ...and finally, anything else we might need to assign from
          //  can exploit the |nsCOMPtr_helper| facility.
        {
          assign_from_helper(rhs, NS_GET_IID(nsISupports));
          return *this;
        }

      void
      swap( nsCOMPtr<nsISupports>& rhs )
          // ...exchange ownership with |rhs|; can save a pair of refcount operations
        {
          nsISupports* temp = rhs.mRawPtr;
          NSCAP_LOG_ASSIGNMENT(&rhs, mRawPtr);
          NSCAP_LOG_ASSIGNMENT(this, temp);
          NSCAP_LOG_RELEASE(this, mRawPtr);
          NSCAP_LOG_RELEASE(&rhs, temp);
          rhs.mRawPtr = mRawPtr;
          mRawPtr = temp;
        }

      void
      swap( nsISupports*& rhs )
          // ...exchange ownership with |rhs|; can save a pair of refcount operations
        {
          nsISupports* temp = rhs;
          NSCAP_LOG_ASSIGNMENT(this, temp);
          NSCAP_LOG_RELEASE(this, mRawPtr);
          rhs = mRawPtr;
          mRawPtr = temp;
        }


        // Other pointer operators

      nsDerivedSafe<nsISupports>*
      get() const
          /*
            Prefer the implicit conversion provided automatically by |operator nsDerivedSafe<nsISupports>*() const|.
             Use |get()| _only_ to resolve ambiguity.

            Returns a |nsDerivedSafe<nsISupports>*| to deny clients the use of |AddRef| and |Release|.
          */
        {
          return NS_REINTERPRET_CAST(nsDerivedSafe<nsISupports>*, mRawPtr);
        }

      operator nsDerivedSafe<nsISupports>*() const
          /*
            ...makes an |nsCOMPtr| act like its underlying raw pointer type (except against |AddRef()|, |Release()|,
              and |delete|) whenever it is used in a context where a raw pointer is expected.  It is this operator
              that makes an |nsCOMPtr| substitutable for a raw pointer.

            Prefer the implicit use of this operator to calling |get()|, except where necessary to resolve ambiguity.
          */
        {
          return get();
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -