LCOV - code coverage report
Current view: top level - xpcom/base - nsCOMPtr.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 426 0.0 %
Date: 2018-08-07 16:35:00 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef nsCOMPtr_h___
       8             : #define nsCOMPtr_h___
       9             : 
      10             : /*
      11             :  * Having problems?
      12             :  *
      13             :  * See the User Manual at:
      14             :  *   http://www.mozilla.org/projects/xpcom/nsCOMPtr.html
      15             :  *
      16             :  *
      17             :  * nsCOMPtr
      18             :  *   better than a raw pointer
      19             :  * for owning objects
      20             :  *                      -- scc
      21             :  */
      22             : 
      23             : #include "mozilla/AlreadyAddRefed.h"
      24             : #include "mozilla/Assertions.h"
      25             : #include "mozilla/Attributes.h"
      26             : #include "mozilla/Move.h"
      27             : #include "mozilla/TypeTraits.h"
      28             : 
      29             : #include "nsDebug.h" // for |NS_ASSERTION|
      30             : #include "nsISupportsUtils.h" // for |nsresult|, |NS_ADDREF|, |NS_GET_TEMPLATE_IID| et al
      31             : #include "mozilla/RefPtr.h"
      32             : 
      33             : #include "nsCycleCollectionNoteChild.h"
      34             : 
      35             : 
      36             : /*
      37             :  * WARNING: This file defines several macros for internal use only. These
      38             :  * macros begin with the prefix |NSCAP_|. Do not use these macros in your own
      39             :  * code. They are for internal use only for cross-platform compatibility, and
      40             :  * are subject to change without notice.
      41             :  */
      42             : 
      43             : 
      44             : #ifdef _MSC_VER
      45             :   // Under VC++, we win by inlining StartAssignment.
      46             :   #define NSCAP_FEATURE_INLINE_STARTASSIGNMENT
      47             : 
      48             :   // Also under VC++, at the highest warning level, we are overwhelmed with
      49             :   // warnings about (unused) inline functions being removed. This is to be
      50             :   // expected with templates, so we disable the warning.
      51             :   #pragma warning( disable: 4514 )
      52             : #endif
      53             : 
      54             : #define NSCAP_FEATURE_USE_BASE
      55             : 
      56             : #ifdef DEBUG
      57             :   #define NSCAP_FEATURE_TEST_DONTQUERY_CASES
      58             :   #undef NSCAP_FEATURE_USE_BASE
      59             : #endif
      60             : 
      61             : #ifdef __GNUC__
      62             :   // Our use of nsCOMPtr_base::mRawPtr violates the C++ standard's aliasing
      63             :   // rules. Mark it with the may_alias attribute so that gcc 3.3 and higher
      64             :   // don't reorder instructions based on aliasing assumptions for
      65             :   // this variable.  Fortunately, gcc versions < 3.3 do not do any
      66             :   // optimizations that break nsCOMPtr.
      67             : 
      68             :   #define NS_MAY_ALIAS_PTR(t)    t*  __attribute__((__may_alias__))
      69             : #else
      70             :   #define NS_MAY_ALIAS_PTR(t)    t*
      71             : #endif
      72             : 
      73             : #if defined(NSCAP_DISABLE_DEBUG_PTR_TYPES)
      74             :   #define NSCAP_FEATURE_USE_BASE
      75             : #endif
      76             : 
      77             : /*
      78             :  * The following three macros (NSCAP_ADDREF, NSCAP_RELEASE, and
      79             :  * NSCAP_LOG_ASSIGNMENT) allow external clients the ability to add logging or
      80             :  * other interesting debug facilities. In fact, if you want |nsCOMPtr| to
      81             :  * participate in the standard logging facility, you provide
      82             :  * (e.g., in "nsISupportsImpl.h") suitable definitions
      83             :  *
      84             :  *   #define NSCAP_ADDREF(this, ptr)         NS_ADDREF(ptr)
      85             :  *   #define NSCAP_RELEASE(this, ptr)        NS_RELEASE(ptr)
      86             :  */
      87             : 
      88             : #ifndef NSCAP_ADDREF
      89             :   #define NSCAP_ADDREF(this, ptr)     (ptr)->AddRef()
      90             : #endif
      91             : 
      92             : #ifndef NSCAP_RELEASE
      93             :   #define NSCAP_RELEASE(this, ptr)    (ptr)->Release()
      94             : #endif
      95             : 
      96             : // Clients can define |NSCAP_LOG_ASSIGNMENT| to perform logging.
      97             : #ifdef NSCAP_LOG_ASSIGNMENT
      98             :   // Remember that |NSCAP_LOG_ASSIGNMENT| was defined by some client so that we
      99             :   // know to instantiate |~nsGetterAddRefs| in turn to note the external
     100             :   // assignment into the |nsCOMPtr|.
     101             :   #define NSCAP_LOG_EXTERNAL_ASSIGNMENT
     102             : #else
     103             :     // ...otherwise, just strip it out of the code
     104             :   #define NSCAP_LOG_ASSIGNMENT(this, ptr)
     105             : #endif
     106             : 
     107             : #ifndef NSCAP_LOG_RELEASE
     108             :   #define NSCAP_LOG_RELEASE(this, ptr)
     109             : #endif
     110             : 
     111             : namespace mozilla {
     112             : template<class T> class OwningNonNull;
     113             : } // namespace mozilla
     114             : 
     115             : template<class T>
     116             : inline already_AddRefed<T>
     117             : dont_AddRef(T* aRawPtr)
     118             : {
     119           0 :   return already_AddRefed<T>(aRawPtr);
     120             : }
     121             : 
     122             : template<class T>
     123             : inline already_AddRefed<T>&&
     124             : dont_AddRef(already_AddRefed<T>&& aAlreadyAddRefedPtr)
     125             : {
     126           0 :   return std::move(aAlreadyAddRefedPtr);
     127             : }
     128             : 
     129             : 
     130             : /*
     131             :  * An nsCOMPtr_helper transforms commonly called getters into typesafe forms
     132             :  * that are more convenient to call, and more efficient to use with |nsCOMPtr|s.
     133             :  * Good candidates for helpers are |QueryInterface()|, |CreateInstance()|, etc.
     134             :  *
     135             :  * Here are the rules for a helper:
     136             :  *   - it implements |operator()| to produce an interface pointer
     137             :  *   - (except for its name) |operator()| is a valid [XP]COM `getter'
     138             :  *   - the interface pointer that it returns is already |AddRef()|ed (as from
     139             :  *     any good getter)
     140             :  *   - it matches the type requested with the supplied |nsIID| argument
     141             :  *   - its constructor provides an optional |nsresult*| that |operator()| can
     142             :  *     fill in with an error when it is executed
     143             :  *
     144             :  * See |class nsGetInterface| for an example.
     145             :  */
     146             : class MOZ_STACK_CLASS nsCOMPtr_helper
     147             : {
     148             : public:
     149             :   virtual nsresult NS_FASTCALL operator()(const nsIID&, void**) const = 0;
     150             : };
     151             : 
     152             : /*
     153             :  * nsQueryInterface could have been implemented as an nsCOMPtr_helper to avoid
     154             :  * adding specialized machinery in nsCOMPtr, but do_QueryInterface is called
     155             :  * often enough that the codesize savings are big enough to warrant the
     156             :  * specialcasing.
     157             :  */
     158             : class MOZ_STACK_CLASS nsQueryInterface final
     159             : {
     160             : public:
     161             :   explicit
     162             :   nsQueryInterface(nsISupports* aRawPtr) : mRawPtr(aRawPtr) {}
     163             : 
     164             :   nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const;
     165             : 
     166             : private:
     167             :   nsISupports* MOZ_OWNING_REF mRawPtr;
     168             : };
     169             : 
     170             : class nsQueryInterfaceWithError final
     171             : {
     172             : public:
     173             :   nsQueryInterfaceWithError(nsISupports* aRawPtr, nsresult* aError)
     174             :     : mRawPtr(aRawPtr)
     175             :     , mErrorPtr(aError)
     176             :   {
     177             :   }
     178             : 
     179             :   nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const;
     180             : 
     181             : private:
     182             :   nsISupports* MOZ_OWNING_REF mRawPtr;
     183             :   nsresult* mErrorPtr;
     184             : };
     185             : 
     186             : inline nsQueryInterface
     187             : do_QueryInterface(nsISupports* aRawPtr)
     188             : {
     189           0 :   return nsQueryInterface(aRawPtr);
     190             : }
     191             : 
     192             : inline nsQueryInterfaceWithError
     193             : do_QueryInterface(nsISupports* aRawPtr, nsresult* aError)
     194             : {
     195           0 :   return nsQueryInterfaceWithError(aRawPtr, aError);
     196             : }
     197             : 
     198             : template<class T>
     199             : inline void
     200             : do_QueryInterface(already_AddRefed<T>&)
     201             : {
     202             :   // This signature exists solely to _stop_ you from doing the bad thing.
     203             :   // Saying |do_QueryInterface()| on a pointer that is not otherwise owned by
     204             :   // someone else is an automatic leak. See bug 8221.
     205             : }
     206             : 
     207             : template<class T>
     208             : inline void
     209             : do_QueryInterface(already_AddRefed<T>&, nsresult*)
     210             : {
     211             :   // This signature exists solely to _stop_ you from doing the bad thing.
     212             :   // Saying |do_QueryInterface()| on a pointer that is not otherwise owned by
     213             :   // someone else is an automatic leak. See bug 8221.
     214             : }
     215             : 
     216             : 
     217             : ////////////////////////////////////////////////////////////////////////////
     218             : // Using servicemanager with COMPtrs
     219             : class nsGetServiceByCID final
     220             : {
     221             : public:
     222             :   explicit nsGetServiceByCID(const nsCID& aCID) : mCID(aCID) {}
     223             : 
     224             :   nsresult NS_FASTCALL operator()(const nsIID&, void**) const;
     225             : 
     226             : private:
     227             :   const nsCID& mCID;
     228             : };
     229             : 
     230             : class nsGetServiceByCIDWithError final
     231             : {
     232             : public:
     233             :   nsGetServiceByCIDWithError(const nsCID& aCID, nsresult* aErrorPtr)
     234             :     : mCID(aCID)
     235             :     , mErrorPtr(aErrorPtr)
     236             :   {
     237             :   }
     238             : 
     239             :   nsresult NS_FASTCALL operator()(const nsIID&, void**) const;
     240             : 
     241             : private:
     242             :   const nsCID& mCID;
     243             :   nsresult* mErrorPtr;
     244             : };
     245             : 
     246             : class nsGetServiceByContractID final
     247             : {
     248             : public:
     249             :   explicit nsGetServiceByContractID(const char* aContractID)
     250             :     : mContractID(aContractID)
     251             :   {
     252             :   }
     253             : 
     254             :   nsresult NS_FASTCALL operator()(const nsIID&, void**) const;
     255             : 
     256             : private:
     257             :   const char* mContractID;
     258             : };
     259             : 
     260             : class nsGetServiceByContractIDWithError final
     261             : {
     262             : public:
     263             :   nsGetServiceByContractIDWithError(const char* aContractID, nsresult* aErrorPtr)
     264             :     : mContractID(aContractID)
     265             :     , mErrorPtr(aErrorPtr)
     266             :   {
     267             :   }
     268             : 
     269             :   nsresult NS_FASTCALL operator()(const nsIID&, void**) const;
     270             : 
     271             : private:
     272             :   const char* mContractID;
     273             :   nsresult* mErrorPtr;
     274             : };
     275             : 
     276             : class nsIWeakReference;
     277             : 
     278             : // Weak references
     279             : class MOZ_STACK_CLASS nsQueryReferent final
     280             : {
     281             : public:
     282             :   nsQueryReferent(nsIWeakReference* aWeakPtr, nsresult* aError)
     283             :     : mWeakPtr(aWeakPtr)
     284             :     , mErrorPtr(aError)
     285             :   {
     286             :   }
     287             : 
     288             :   nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const;
     289             : 
     290             : private:
     291             :   nsIWeakReference* MOZ_NON_OWNING_REF mWeakPtr;
     292             :   nsresult*          mErrorPtr;
     293             : };
     294             : 
     295             : /**
     296             :  * Factors implementation for all template versions of nsCOMPtr.
     297             :  *
     298             :  * Here's the way people normally do things like this:
     299             :  *
     300             :  *   template<class T> class Foo { ... };
     301             :  *   template<> class Foo<void*> { ... };
     302             :  *   template<class T> class Foo<T*> : private Foo<void*> { ... };
     303             :  */
     304             : class nsCOMPtr_base
     305             : {
     306             : public:
     307           0 :   explicit nsCOMPtr_base(nsISupports* aRawPtr = nullptr) : mRawPtr(aRawPtr) {}
     308             : 
     309           0 :   NS_CONSTRUCTOR_FASTCALL ~nsCOMPtr_base()
     310           0 :   {
     311           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
     312           0 :     if (mRawPtr) {
     313           0 :       NSCAP_RELEASE(this, mRawPtr);
     314             :     }
     315           0 :   }
     316             : 
     317             :   void NS_FASTCALL
     318             :   assign_with_AddRef(nsISupports*);
     319             :   void NS_FASTCALL
     320             :   assign_from_qi(const nsQueryInterface, const nsIID&);
     321             :   void NS_FASTCALL
     322             :   assign_from_qi_with_error(const nsQueryInterfaceWithError&, const nsIID&);
     323             :   void NS_FASTCALL
     324             :   assign_from_gs_cid(const nsGetServiceByCID, const nsIID&);
     325             :   void NS_FASTCALL
     326             :   assign_from_gs_cid_with_error(const nsGetServiceByCIDWithError&, const nsIID&);
     327             :   void NS_FASTCALL
     328             :   assign_from_gs_contractid(const nsGetServiceByContractID, const nsIID&);
     329             :   void NS_FASTCALL
     330             :   assign_from_gs_contractid_with_error(const nsGetServiceByContractIDWithError&,
     331             :                                        const nsIID&);
     332             :   void NS_FASTCALL
     333             :   assign_from_query_referent(const nsQueryReferent&, const nsIID&);
     334             :   void NS_FASTCALL
     335             :   assign_from_helper(const nsCOMPtr_helper&, const nsIID&);
     336             :   void** NS_FASTCALL
     337             :   begin_assignment();
     338             : 
     339             : protected:
     340             :   NS_MAY_ALIAS_PTR(nsISupports) MOZ_OWNING_REF mRawPtr;
     341             : 
     342           0 :   void assign_assuming_AddRef(nsISupports* aNewPtr)
     343             :   {
     344             :     // |AddRef()|ing the new value (before entering this function) before
     345             :     // |Release()|ing the old lets us safely ignore the self-assignment case.
     346             :     // We must, however, be careful only to |Release()| _after_ doing the
     347             :     // assignment, in case the |Release()| leads to our _own_ destruction,
     348             :     // which would, in turn, cause an incorrect second |Release()| of our old
     349             :     // pointer. Thank <waterson@netscape.com> for discovering this.
     350           0 :     nsISupports* oldPtr = mRawPtr;
     351           0 :     mRawPtr = aNewPtr;
     352           0 :     NSCAP_LOG_ASSIGNMENT(this, aNewPtr);
     353           0 :     NSCAP_LOG_RELEASE(this, oldPtr);
     354           0 :     if (oldPtr) {
     355           0 :       NSCAP_RELEASE(this, oldPtr);
     356             :     }
     357           0 :   }
     358             : };
     359             : 
     360             : // template<class T> class nsGetterAddRefs;
     361             : 
     362             : // Helper for assert_validity method
     363             : template<class T>
     364             : char (&TestForIID(decltype(&NS_GET_TEMPLATE_IID(T))))[2];
     365             : template<class T>
     366             : char TestForIID(...);
     367             : 
     368             : template<class T>
     369             : class MOZ_IS_REFPTR nsCOMPtr final
     370             : #ifdef NSCAP_FEATURE_USE_BASE
     371             :   : private nsCOMPtr_base
     372             : #endif
     373             : {
     374             : 
     375             : #ifdef NSCAP_FEATURE_USE_BASE
     376             :   #define NSCAP_CTOR_BASE(x) nsCOMPtr_base(x)
     377             : #else
     378             :   #define NSCAP_CTOR_BASE(x) mRawPtr(x)
     379             : 
     380             : private:
     381             :   void assign_with_AddRef(nsISupports*);
     382             :   void assign_from_qi(const nsQueryInterface, const nsIID&);
     383             :   void assign_from_qi_with_error(const nsQueryInterfaceWithError&, const nsIID&);
     384             :   void assign_from_gs_cid(const nsGetServiceByCID, const nsIID&);
     385             :   void assign_from_gs_cid_with_error(const nsGetServiceByCIDWithError&,
     386             :                                      const nsIID&);
     387             :   void assign_from_gs_contractid(const nsGetServiceByContractID, const nsIID&);
     388             :   void assign_from_gs_contractid_with_error(
     389             :     const nsGetServiceByContractIDWithError&, const nsIID&);
     390             :   void assign_from_query_referent(const nsQueryReferent&, const nsIID&);
     391             :   void assign_from_helper(const nsCOMPtr_helper&, const nsIID&);
     392             :   void** begin_assignment();
     393             : 
     394           0 :   void assign_assuming_AddRef(T* aNewPtr)
     395             :   {
     396           0 :     T* oldPtr = mRawPtr;
     397           0 :     mRawPtr = aNewPtr;
     398           0 :     NSCAP_LOG_ASSIGNMENT(this, aNewPtr);
     399           0 :     NSCAP_LOG_RELEASE(this, oldPtr);
     400           0 :     if (oldPtr) {
     401           0 :       NSCAP_RELEASE(this, oldPtr);
     402             :     }
     403           0 :   }
     404             : 
     405             : private:
     406             :   T* MOZ_OWNING_REF mRawPtr;
     407             : #endif
     408             : 
     409             :   void assert_validity()
     410             :   {
     411             :     static_assert(1 < sizeof(TestForIID<T>(nullptr)), "nsCOMPtr only works "
     412             :                   "for types with IIDs.  Either use RefPtr; add an IID to "
     413             :                   "your type with NS_DECLARE_STATIC_IID_ACCESSOR/"
     414             :                   "NS_DEFINE_STATIC_IID_ACCESSOR; or make the nsCOMPtr point "
     415             :                   "to a base class with an IID.");
     416             :   }
     417             : 
     418             : public:
     419             :   typedef T element_type;
     420             : 
     421             : #ifndef NSCAP_FEATURE_USE_BASE
     422           0 :   ~nsCOMPtr()
     423             :   {
     424           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
     425           0 :     if (mRawPtr) {
     426           0 :       NSCAP_RELEASE(this, mRawPtr);
     427             :     }
     428           0 :   }
     429             : #endif
     430             : 
     431             : #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
     432           0 :   void Assert_NoQueryNeeded()
     433             :   {
     434           0 :     if (mRawPtr) {
     435           0 :       nsCOMPtr<T> query_result(do_QueryInterface(mRawPtr));
     436           0 :       NS_ASSERTION(query_result.get() == mRawPtr, "QueryInterface needed");
     437             :     }
     438           0 :   }
     439             : 
     440             :   #define NSCAP_ASSERT_NO_QUERY_NEEDED() Assert_NoQueryNeeded();
     441             : #else
     442             :   #define NSCAP_ASSERT_NO_QUERY_NEEDED()
     443             : #endif
     444             : 
     445             : 
     446             :   // Constructors
     447             : 
     448           0 :   nsCOMPtr()
     449           0 :     : NSCAP_CTOR_BASE(nullptr)
     450             :   {
     451           0 :     assert_validity();
     452             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     453             :   }
     454             : 
     455           0 :   MOZ_IMPLICIT nsCOMPtr(decltype(nullptr))
     456           0 :     : NSCAP_CTOR_BASE(nullptr)
     457             :   {
     458           0 :     assert_validity();
     459             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     460             :   }
     461             : 
     462           0 :   nsCOMPtr(const nsCOMPtr<T>& aSmartPtr)
     463           0 :     : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
     464             :   {
     465           0 :     assert_validity();
     466           0 :     if (mRawPtr) {
     467           0 :       NSCAP_ADDREF(this, mRawPtr);
     468             :     }
     469           0 :     NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
     470           0 :   }
     471             : 
     472           0 :   nsCOMPtr(nsCOMPtr<T>&& aSmartPtr)
     473           0 :     : NSCAP_CTOR_BASE(aSmartPtr.mRawPtr)
     474             :   {
     475           0 :     assert_validity();
     476           0 :     aSmartPtr.mRawPtr = nullptr;
     477           0 :     NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
     478           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     479           0 :   }
     480             : 
     481           0 :   MOZ_IMPLICIT nsCOMPtr(T* aRawPtr)
     482           0 :     : NSCAP_CTOR_BASE(aRawPtr)
     483             :   {
     484           0 :     assert_validity();
     485           0 :     if (mRawPtr) {
     486           0 :       NSCAP_ADDREF(this, mRawPtr);
     487             :     }
     488           0 :     NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
     489           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     490           0 :   }
     491             : 
     492           0 :   MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T>& aSmartPtr)
     493           0 :     : NSCAP_CTOR_BASE(aSmartPtr.take())
     494             :   {
     495           0 :     assert_validity();
     496           0 :     NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
     497           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     498           0 :   }
     499             : 
     500             :   // Construct from |otherComPtr.forget()|.
     501           0 :   MOZ_IMPLICIT nsCOMPtr(already_AddRefed<T>&& aSmartPtr)
     502           0 :     : NSCAP_CTOR_BASE(aSmartPtr.take())
     503             :   {
     504           0 :     assert_validity();
     505           0 :     NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
     506           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     507           0 :   }
     508             : 
     509             :   // Construct from |already_AddRefed|.
     510             :   template<typename U>
     511           0 :   MOZ_IMPLICIT nsCOMPtr(already_AddRefed<U>& aSmartPtr)
     512           0 :     : NSCAP_CTOR_BASE(static_cast<T*>(aSmartPtr.take()))
     513             :   {
     514           0 :     assert_validity();
     515             :     // But make sure that U actually inherits from T.
     516             :     static_assert(mozilla::IsBaseOf<T, U>::value,
     517             :                   "U is not a subclass of T");
     518           0 :     NSCAP_LOG_ASSIGNMENT(this, static_cast<T*>(mRawPtr));
     519           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     520           0 :   }
     521             : 
     522             :   // Construct from |otherComPtr.forget()|.
     523             :   template<typename U>
     524           0 :   MOZ_IMPLICIT nsCOMPtr(already_AddRefed<U>&& aSmartPtr)
     525           0 :     : NSCAP_CTOR_BASE(static_cast<T*>(aSmartPtr.take()))
     526             :   {
     527           0 :     assert_validity();
     528             :     // But make sure that U actually inherits from T.
     529             :     static_assert(mozilla::IsBaseOf<T, U>::value,
     530             :                   "U is not a subclass of T");
     531           0 :     NSCAP_LOG_ASSIGNMENT(this, static_cast<T*>(mRawPtr));
     532           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     533           0 :   }
     534             : 
     535             :   // Construct from |do_QueryInterface(expr)|.
     536           0 :   MOZ_IMPLICIT nsCOMPtr(const nsQueryInterface aQI)
     537           0 :     : NSCAP_CTOR_BASE(nullptr)
     538             :   {
     539           0 :     assert_validity();
     540             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     541           0 :     assign_from_qi(aQI, NS_GET_TEMPLATE_IID(T));
     542           0 :   }
     543             : 
     544             :   // Construct from |do_QueryInterface(expr, &rv)|.
     545           0 :   MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceWithError& aQI)
     546           0 :     : NSCAP_CTOR_BASE(nullptr)
     547             :   {
     548           0 :     assert_validity();
     549             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     550           0 :     assign_from_qi_with_error(aQI, NS_GET_TEMPLATE_IID(T));
     551           0 :   }
     552             : 
     553             :   // Construct from |do_GetService(cid_expr)|.
     554           0 :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCID aGS)
     555           0 :     : NSCAP_CTOR_BASE(nullptr)
     556             :   {
     557           0 :     assert_validity();
     558             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     559           0 :     assign_from_gs_cid(aGS, NS_GET_TEMPLATE_IID(T));
     560           0 :   }
     561             : 
     562             :   // Construct from |do_GetService(cid_expr, &rv)|.
     563           0 :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCIDWithError& aGS)
     564           0 :     : NSCAP_CTOR_BASE(nullptr)
     565             :   {
     566           0 :     assert_validity();
     567             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     568           0 :     assign_from_gs_cid_with_error(aGS, NS_GET_TEMPLATE_IID(T));
     569           0 :   }
     570             : 
     571             :   // Construct from |do_GetService(contractid_expr)|.
     572           0 :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractID aGS)
     573           0 :     : NSCAP_CTOR_BASE(nullptr)
     574             :   {
     575           0 :     assert_validity();
     576             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     577           0 :     assign_from_gs_contractid(aGS, NS_GET_TEMPLATE_IID(T));
     578           0 :   }
     579             : 
     580             :   // Construct from |do_GetService(contractid_expr, &rv)|.
     581           0 :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractIDWithError& aGS)
     582           0 :     : NSCAP_CTOR_BASE(nullptr)
     583             :   {
     584           0 :     assert_validity();
     585             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     586           0 :     assign_from_gs_contractid_with_error(aGS, NS_GET_TEMPLATE_IID(T));
     587           0 :   }
     588             : 
     589             :   // Construct from |do_QueryReferent(ptr)|
     590           0 :   MOZ_IMPLICIT nsCOMPtr(const nsQueryReferent& aQueryReferent)
     591           0 :     : NSCAP_CTOR_BASE(nullptr)
     592             :   {
     593           0 :     assert_validity();
     594             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     595           0 :     assign_from_query_referent(aQueryReferent, NS_GET_TEMPLATE_IID(T));
     596           0 :   }
     597             : 
     598             :   // And finally, anything else we might need to construct from can exploit the
     599             :   // nsCOMPtr_helper facility.
     600           0 :   MOZ_IMPLICIT nsCOMPtr(const nsCOMPtr_helper& aHelper)
     601           0 :     : NSCAP_CTOR_BASE(nullptr)
     602             :   {
     603           0 :     assert_validity();
     604             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     605           0 :     assign_from_helper(aHelper, NS_GET_TEMPLATE_IID(T));
     606           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     607           0 :   }
     608             : 
     609             :   // Defined in OwningNonNull.h
     610             :   template<class U>
     611             :   MOZ_IMPLICIT nsCOMPtr(const mozilla::OwningNonNull<U>& aOther);
     612             : 
     613             : 
     614             :   // Assignment operators
     615             : 
     616           0 :   nsCOMPtr<T>& operator=(const nsCOMPtr<T>& aRhs)
     617             :   {
     618           0 :     assign_with_AddRef(aRhs.mRawPtr);
     619           0 :     return *this;
     620             :   }
     621             : 
     622           0 :   nsCOMPtr<T>& operator=(nsCOMPtr<T>&& aRhs)
     623             :   {
     624           0 :     assign_assuming_AddRef(aRhs.forget().take());
     625           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     626           0 :     return *this;
     627             :   }
     628             : 
     629           0 :   nsCOMPtr<T>& operator=(T* aRhs)
     630             :   {
     631           0 :     assign_with_AddRef(aRhs);
     632           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     633           0 :     return *this;
     634             :   }
     635             : 
     636           0 :   nsCOMPtr<T>& operator=(decltype(nullptr))
     637             :   {
     638           0 :     assign_assuming_AddRef(nullptr);
     639           0 :     return *this;
     640             :   }
     641             : 
     642             :   // Assign from |already_AddRefed|.
     643             :   template<typename U>
     644           0 :   nsCOMPtr<T>& operator=(already_AddRefed<U>& aRhs)
     645             :   {
     646             :     // Make sure that U actually inherits from T
     647             :     static_assert(mozilla::IsBaseOf<T, U>::value,
     648             :                   "U is not a subclass of T");
     649           0 :     assign_assuming_AddRef(static_cast<T*>(aRhs.take()));
     650           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     651           0 :     return *this;
     652             :   }
     653             : 
     654             :   // Assign from |otherComPtr.forget()|.
     655             :   template<typename U>
     656           0 :   nsCOMPtr<T>& operator=(already_AddRefed<U>&& aRhs)
     657             :   {
     658             :     // Make sure that U actually inherits from T
     659             :     static_assert(mozilla::IsBaseOf<T, U>::value,
     660             :                   "U is not a subclass of T");
     661           0 :     assign_assuming_AddRef(static_cast<T*>(aRhs.take()));
     662           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     663           0 :     return *this;
     664             :   }
     665             : 
     666             :   // Assign from |do_QueryInterface(expr)|.
     667           0 :   nsCOMPtr<T>& operator=(const nsQueryInterface aRhs)
     668             :   {
     669           0 :     assign_from_qi(aRhs, NS_GET_TEMPLATE_IID(T));
     670           0 :     return *this;
     671             :   }
     672             : 
     673             :   // Assign from |do_QueryInterface(expr, &rv)|.
     674           0 :   nsCOMPtr<T>& operator=(const nsQueryInterfaceWithError& aRhs)
     675             :   {
     676           0 :     assign_from_qi_with_error(aRhs, NS_GET_TEMPLATE_IID(T));
     677           0 :     return *this;
     678             :   }
     679             : 
     680             :   // Assign from |do_GetService(cid_expr)|.
     681           0 :   nsCOMPtr<T>& operator=(const nsGetServiceByCID aRhs)
     682             :   {
     683           0 :     assign_from_gs_cid(aRhs, NS_GET_TEMPLATE_IID(T));
     684           0 :     return *this;
     685             :   }
     686             : 
     687             :   // Assign from |do_GetService(cid_expr, &rv)|.
     688           0 :   nsCOMPtr<T>& operator=(const nsGetServiceByCIDWithError& aRhs)
     689             :   {
     690           0 :     assign_from_gs_cid_with_error(aRhs, NS_GET_TEMPLATE_IID(T));
     691           0 :     return *this;
     692             :   }
     693             : 
     694             :   // Assign from |do_GetService(contractid_expr)|.
     695           0 :   nsCOMPtr<T>& operator=(const nsGetServiceByContractID aRhs)
     696             :   {
     697           0 :     assign_from_gs_contractid(aRhs, NS_GET_TEMPLATE_IID(T));
     698           0 :     return *this;
     699             :   }
     700             : 
     701             :   // Assign from |do_GetService(contractid_expr, &rv)|.
     702           0 :   nsCOMPtr<T>& operator=(const nsGetServiceByContractIDWithError& aRhs)
     703             :   {
     704           0 :     assign_from_gs_contractid_with_error(aRhs, NS_GET_TEMPLATE_IID(T));
     705           0 :     return *this;
     706             :   }
     707             : 
     708             :   // Assign from |do_QueryReferent(ptr)|.
     709           0 :   nsCOMPtr<T>& operator=(const nsQueryReferent& aRhs)
     710             :   {
     711           0 :     assign_from_query_referent(aRhs, NS_GET_TEMPLATE_IID(T));
     712           0 :     return *this;
     713             :   }
     714             : 
     715             :   // And finally, anything else we might need to assign from can exploit the
     716             :   // nsCOMPtr_helper facility.
     717           0 :   nsCOMPtr<T>& operator=(const nsCOMPtr_helper& aRhs)
     718             :   {
     719           0 :     assign_from_helper(aRhs, NS_GET_TEMPLATE_IID(T));
     720           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     721           0 :     return *this;
     722             :   }
     723             : 
     724             :   // Defined in OwningNonNull.h
     725             :   template<class U>
     726             :   nsCOMPtr<T>& operator=(const mozilla::OwningNonNull<U>& aOther);
     727             : 
     728             :   // Exchange ownership with |aRhs|; can save a pair of refcount operations.
     729           0 :   void swap(nsCOMPtr<T>& aRhs)
     730             :   {
     731             : #ifdef NSCAP_FEATURE_USE_BASE
     732             :     nsISupports* temp = aRhs.mRawPtr;
     733             : #else
     734           0 :     T* temp = aRhs.mRawPtr;
     735             : #endif
     736           0 :     NSCAP_LOG_ASSIGNMENT(&aRhs, mRawPtr);
     737           0 :     NSCAP_LOG_ASSIGNMENT(this, temp);
     738           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
     739           0 :     NSCAP_LOG_RELEASE(&aRhs, temp);
     740           0 :     aRhs.mRawPtr = mRawPtr;
     741           0 :     mRawPtr = temp;
     742             :     // |aRhs| maintains the same invariants, so we don't need to |NSCAP_ASSERT_NO_QUERY_NEEDED|
     743           0 :   }
     744             : 
     745             :   // Exchange ownership with |aRhs|; can save a pair of refcount operations.
     746           0 :   void swap(T*& aRhs)
     747             :   {
     748             : #ifdef NSCAP_FEATURE_USE_BASE
     749             :     nsISupports* temp = aRhs;
     750             : #else
     751           0 :     T* temp = aRhs;
     752             : #endif
     753           0 :     NSCAP_LOG_ASSIGNMENT(this, temp);
     754           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
     755           0 :     aRhs = reinterpret_cast<T*>(mRawPtr);
     756           0 :     mRawPtr = temp;
     757           0 :     NSCAP_ASSERT_NO_QUERY_NEEDED();
     758           0 :   }
     759             : 
     760             : 
     761             :   // Other pointer operators
     762             : 
     763             :   // Return the value of mRawPtr and null out mRawPtr. Useful for
     764             :   // already_AddRefed return values.
     765           0 :   already_AddRefed<T> MOZ_MAY_CALL_AFTER_MUST_RETURN forget()
     766             :   {
     767           0 :     T* temp = nullptr;
     768           0 :     swap(temp);
     769           0 :     return already_AddRefed<T>(temp);
     770             :   }
     771             : 
     772             :   // Set the target of aRhs to the value of mRawPtr and null out mRawPtr.
     773             :   // Useful to avoid unnecessary AddRef/Release pairs with "out" parameters
     774             :   // where aRhs bay be a T** or an I** where I is a base class of T.
     775             :   template<typename I>
     776           0 :   void forget(I** aRhs)
     777             :   {
     778           0 :     NS_ASSERTION(aRhs, "Null pointer passed to forget!");
     779           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
     780           0 :     *aRhs = get();
     781           0 :     mRawPtr = nullptr;
     782           0 :   }
     783             : 
     784             :   // Prefer the implicit conversion provided automatically by
     785             :   // |operator T*() const|. Use |get()| to resolve ambiguity or to get a
     786             :   // castable pointer.
     787           0 :   T* get() const { return reinterpret_cast<T*>(mRawPtr); }
     788             : 
     789             :   // Makes an nsCOMPtr act like its underlying raw pointer type whenever it is
     790             :   // used in a context where a raw pointer is expected. It is this operator
     791             :   // that makes an nsCOMPtr substitutable for a raw pointer.
     792             :   //
     793             :   // Prefer the implicit use of this operator to calling |get()|, except where
     794             :   // necessary to resolve ambiguity.
     795           0 :   operator T*() const & { return get(); }
     796             : 
     797             :   // Don't allow implicit conversion of temporary nsCOMPtr to raw pointer,
     798             :   // because the refcount might be one and the pointer will immediately become
     799             :   // invalid.
     800             :   operator T*() const && = delete;
     801             : 
     802             :   // Needed to avoid the deleted operator above
     803           0 :   explicit operator bool() const { return !!mRawPtr; }
     804             : 
     805           0 :   T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
     806             :   {
     807           0 :     MOZ_ASSERT(mRawPtr != nullptr,
     808             :                "You can't dereference a NULL nsCOMPtr with operator->().");
     809           0 :     return get();
     810             :   }
     811             : 
     812             :   // These are not intended to be used by clients. See |address_of| below.
     813             :   nsCOMPtr<T>* get_address() { return this; }
     814             :   const nsCOMPtr<T>* get_address() const { return this; }
     815             : 
     816             : public:
     817           0 :   T& operator*() const
     818             :   {
     819           0 :     MOZ_ASSERT(mRawPtr != nullptr,
     820             :                "You can't dereference a NULL nsCOMPtr with operator*().");
     821           0 :     return *get();
     822             :   }
     823             : 
     824             :   T** StartAssignment()
     825             :   {
     826             : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
     827           0 :     return reinterpret_cast<T**>(begin_assignment());
     828             : #else
     829             :     assign_assuming_AddRef(nullptr);
     830             :     return reinterpret_cast<T**>(&mRawPtr);
     831             : #endif
     832             :   }
     833             : };
     834             : 
     835             : 
     836             : /*
     837             :  * Specializing nsCOMPtr for nsISupports allows us to use nsCOMPtr<nsISupports>
     838             :  * the same way people use nsISupports* and void*, i.e., as a `catch-all'
     839             :  * pointing to any valid [XP]COM interface. Otherwise, an nsCOMPtr<nsISupports>
     840             :  * would only be able to point to the single [XP]COM-correct nsISupports
     841             :  * instance within an object; extra querying ensues. Clients need to be able to
     842             :  * pass around arbitrary interface pointers, without hassles, through
     843             :  * intermediary code that doesn't know the exact type.
     844             :  */
     845             : template<>
     846           0 : class nsCOMPtr<nsISupports>
     847             :   : private nsCOMPtr_base
     848             : {
     849             : public:
     850             :   typedef nsISupports element_type;
     851             : 
     852             :   // Constructors
     853             : 
     854             :   nsCOMPtr()
     855           0 :     : nsCOMPtr_base(nullptr)
     856             :   {
     857             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     858             :   }
     859             : 
     860             :   MOZ_IMPLICIT nsCOMPtr(decltype(nullptr))
     861           0 :     : nsCOMPtr_base(nullptr)
     862             :   {
     863             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     864             :   }
     865             : 
     866           0 :   nsCOMPtr(const nsCOMPtr<nsISupports>& aSmartPtr)
     867           0 :     : nsCOMPtr_base(aSmartPtr.mRawPtr)
     868             :   {
     869           0 :     if (mRawPtr) {
     870           0 :       NSCAP_ADDREF(this, mRawPtr);
     871             :     }
     872           0 :     NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
     873           0 :   }
     874             : 
     875           0 :   MOZ_IMPLICIT nsCOMPtr(nsISupports* aRawPtr)
     876           0 :     : nsCOMPtr_base(aRawPtr)
     877             :   {
     878           0 :     if (mRawPtr) {
     879           0 :       NSCAP_ADDREF(this, mRawPtr);
     880             :     }
     881           0 :     NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
     882           0 :   }
     883             : 
     884             :   // Construct from |already_AddRefed|.
     885           0 :   MOZ_IMPLICIT nsCOMPtr(already_AddRefed<nsISupports>& aSmartPtr)
     886           0 :     : nsCOMPtr_base(aSmartPtr.take())
     887             :   {
     888           0 :     NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
     889           0 :   }
     890             : 
     891             :   // Construct from |otherComPtr.forget()|.
     892           0 :   MOZ_IMPLICIT nsCOMPtr(already_AddRefed<nsISupports>&& aSmartPtr)
     893           0 :     : nsCOMPtr_base(aSmartPtr.take())
     894             :   {
     895           0 :     NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
     896           0 :   }
     897             : 
     898             :   // Construct from |do_QueryInterface(expr)|.
     899           0 :   MOZ_IMPLICIT nsCOMPtr(const nsQueryInterface aQI)
     900           0 :     : nsCOMPtr_base(nullptr)
     901             :   {
     902             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     903           0 :     assign_from_qi(aQI, NS_GET_IID(nsISupports));
     904           0 :   }
     905             : 
     906             :   // Construct from |do_QueryInterface(expr, &rv)|.
     907           0 :   MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceWithError& aQI)
     908           0 :     : nsCOMPtr_base(nullptr)
     909             :   {
     910             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     911           0 :     assign_from_qi_with_error(aQI, NS_GET_IID(nsISupports));
     912           0 :   }
     913             : 
     914             :   // Construct from |do_GetService(cid_expr)|.
     915             :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCID aGS)
     916             :     : nsCOMPtr_base(nullptr)
     917             :   {
     918             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     919             :     assign_from_gs_cid(aGS, NS_GET_IID(nsISupports));
     920             :   }
     921             : 
     922             :   // Construct from |do_GetService(cid_expr, &rv)|.
     923             :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCIDWithError& aGS)
     924             :     : nsCOMPtr_base(nullptr)
     925             :   {
     926             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     927             :     assign_from_gs_cid_with_error(aGS, NS_GET_IID(nsISupports));
     928             :   }
     929             : 
     930             :   // Construct from |do_GetService(contractid_expr)|.
     931           0 :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractID aGS)
     932           0 :     : nsCOMPtr_base(nullptr)
     933             :   {
     934             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     935           0 :     assign_from_gs_contractid(aGS, NS_GET_IID(nsISupports));
     936           0 :   }
     937             : 
     938             :   // Construct from |do_GetService(contractid_expr, &rv)|.
     939           0 :   MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractIDWithError& aGS)
     940           0 :     : nsCOMPtr_base(nullptr)
     941             :   {
     942             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     943           0 :     assign_from_gs_contractid_with_error(aGS, NS_GET_IID(nsISupports));
     944           0 :   }
     945             : 
     946             :   // Construct from |do_QueryReferent(ptr)|
     947           0 :   MOZ_IMPLICIT nsCOMPtr(const nsQueryReferent& aQueryReferent)
     948           0 :     : nsCOMPtr_base(nullptr)
     949             :   {
     950             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     951           0 :     assign_from_query_referent(aQueryReferent, NS_GET_TEMPLATE_IID(nsISupports));
     952           0 :   }
     953             : 
     954             :   // And finally, anything else we might need to construct from can exploit
     955             :   // the |nsCOMPtr_helper| facility
     956           0 :   MOZ_IMPLICIT nsCOMPtr(const nsCOMPtr_helper& aHelper)
     957           0 :     : nsCOMPtr_base(nullptr)
     958             :   {
     959             :     NSCAP_LOG_ASSIGNMENT(this, nullptr);
     960           0 :     assign_from_helper(aHelper, NS_GET_IID(nsISupports));
     961           0 :   }
     962             : 
     963             : 
     964             :   // Assignment operators
     965             : 
     966           0 :   nsCOMPtr<nsISupports>& operator=(const nsCOMPtr<nsISupports>& aRhs)
     967             :   {
     968           0 :     assign_with_AddRef(aRhs.mRawPtr);
     969           0 :     return *this;
     970             :   }
     971             : 
     972             :   nsCOMPtr<nsISupports>& operator=(nsISupports* aRhs)
     973             :   {
     974           0 :     assign_with_AddRef(aRhs);
     975             :     return *this;
     976             :   }
     977             : 
     978           0 :   nsCOMPtr<nsISupports>& operator=(decltype(nullptr))
     979             :   {
     980           0 :     assign_assuming_AddRef(nullptr);
     981           0 :     return *this;
     982             :   }
     983             : 
     984             :   // Assign from |already_AddRefed|.
     985           0 :   nsCOMPtr<nsISupports>& operator=(already_AddRefed<nsISupports>& aRhs)
     986             :   {
     987           0 :     assign_assuming_AddRef(aRhs.take());
     988           0 :     return *this;
     989             :   }
     990             : 
     991             :   // Assign from |otherComPtr.forget()|.
     992           0 :   nsCOMPtr<nsISupports>& operator=(already_AddRefed<nsISupports>&& aRhs)
     993             :   {
     994           0 :     assign_assuming_AddRef(aRhs.take());
     995           0 :     return *this;
     996             :   }
     997             : 
     998             :   // Assign from |do_QueryInterface(expr)|.
     999           0 :   nsCOMPtr<nsISupports>& operator=(const nsQueryInterface aRhs)
    1000             :   {
    1001           0 :     assign_from_qi(aRhs, NS_GET_IID(nsISupports));
    1002           0 :     return *this;
    1003             :   }
    1004             : 
    1005             :   // Assign from |do_QueryInterface(expr, &rv)|.
    1006             :   nsCOMPtr<nsISupports>& operator=(const nsQueryInterfaceWithError& aRhs)
    1007             :   {
    1008             :     assign_from_qi_with_error(aRhs, NS_GET_IID(nsISupports));
    1009             :     return *this;
    1010             :   }
    1011             : 
    1012             :   // Assign from |do_GetService(cid_expr)|.
    1013             :   nsCOMPtr<nsISupports>& operator=(const nsGetServiceByCID aRhs)
    1014             :   {
    1015             :     assign_from_gs_cid(aRhs, NS_GET_IID(nsISupports));
    1016             :     return *this;
    1017             :   }
    1018             : 
    1019             :   // Assign from |do_GetService(cid_expr, &rv)|.
    1020             :   nsCOMPtr<nsISupports>& operator=(const nsGetServiceByCIDWithError& aRhs)
    1021             :   {
    1022             :     assign_from_gs_cid_with_error(aRhs, NS_GET_IID(nsISupports));
    1023             :     return *this;
    1024             :   }
    1025             : 
    1026             :   // Assign from |do_GetService(contractid_expr)|.
    1027             :   nsCOMPtr<nsISupports>& operator=(const nsGetServiceByContractID aRhs)
    1028             :   {
    1029             :     assign_from_gs_contractid(aRhs, NS_GET_IID(nsISupports));
    1030             :     return *this;
    1031             :   }
    1032             : 
    1033             :   // Assign from |do_GetService(contractid_expr, &rv)|.
    1034           0 :   nsCOMPtr<nsISupports>& operator=(const nsGetServiceByContractIDWithError& aRhs)
    1035             :   {
    1036           0 :     assign_from_gs_contractid_with_error(aRhs, NS_GET_IID(nsISupports));
    1037           0 :     return *this;
    1038             :   }
    1039             : 
    1040             :   // Assign from |do_QueryReferent(ptr)|.
    1041           0 :   nsCOMPtr<nsISupports>& operator=(const nsQueryReferent& aRhs)
    1042             :   {
    1043           0 :     assign_from_query_referent(aRhs, NS_GET_TEMPLATE_IID(nsISupports));
    1044           0 :     return *this;
    1045             :   }
    1046             : 
    1047             :   // And finally, anything else we might need to assign from can exploit the
    1048             :   // nsCOMPtr_helper facility
    1049           0 :   nsCOMPtr<nsISupports>& operator=(const nsCOMPtr_helper& aRhs)
    1050             :   {
    1051           0 :     assign_from_helper(aRhs, NS_GET_IID(nsISupports));
    1052           0 :     return *this;
    1053             :   }
    1054             : 
    1055             :   // Exchange ownership with |aRhs|; can save a pair of refcount operations.
    1056           0 :   void swap(nsCOMPtr<nsISupports>& aRhs)
    1057             :   {
    1058           0 :     nsISupports* temp = aRhs.mRawPtr;
    1059           0 :     NSCAP_LOG_ASSIGNMENT(&aRhs, mRawPtr);
    1060           0 :     NSCAP_LOG_ASSIGNMENT(this, temp);
    1061           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
    1062           0 :     NSCAP_LOG_RELEASE(&aRhs, temp);
    1063           0 :     aRhs.mRawPtr = mRawPtr;
    1064           0 :     mRawPtr = temp;
    1065           0 :   }
    1066             : 
    1067             :   // Exchange ownership with |aRhs|; can save a pair of refcount operations.
    1068           0 :   void swap(nsISupports*& aRhs)
    1069             :   {
    1070           0 :     nsISupports* temp = aRhs;
    1071           0 :     NSCAP_LOG_ASSIGNMENT(this, temp);
    1072           0 :     NSCAP_LOG_RELEASE(this, mRawPtr);
    1073           0 :     aRhs = mRawPtr;
    1074           0 :     mRawPtr = temp;
    1075           0 :   }
    1076             : 
    1077             :   // Return the value of mRawPtr and null out mRawPtr. Useful for
    1078             :   // already_AddRefed return values.
    1079           0 :   already_AddRefed<nsISupports> forget()
    1080             :   {
    1081           0 :     nsISupports* temp = nullptr;
    1082           0 :     swap(temp);
    1083           0 :     return already_AddRefed<nsISupports>(temp);
    1084             :   }
    1085             : 
    1086             :   // Set the target of aRhs to the value of mRawPtr and null out mRawPtr.
    1087             :   // Useful to avoid unnecessary AddRef/Release pairs with "out"
    1088             :   // parameters.
    1089           0 :   void forget(nsISupports** aRhs)
    1090             :   {
    1091           0 :     NS_ASSERTION(aRhs, "Null pointer passed to forget!");
    1092           0 :     *aRhs = nullptr;
    1093           0 :     swap(*aRhs);
    1094           0 :   }
    1095             : 
    1096             :   // Other pointer operators
    1097             : 
    1098             :   // Prefer the implicit conversion provided automatically by
    1099             :   // |operator nsISupports*() const|. Use |get()| to resolve ambiguity or to
    1100             :   // get a castable pointer.
    1101           0 :   nsISupports* get() const { return reinterpret_cast<nsISupports*>(mRawPtr); }
    1102             : 
    1103             :   // Makes an nsCOMPtr act like its underlying raw pointer type whenever it is
    1104             :   // used in a context where a raw pointer is expected. It is this operator
    1105             :   // that makes an nsCOMPtr substitutable for a raw pointer.
    1106             :   //
    1107             :   // Prefer the implicit use of this operator to calling |get()|, except where
    1108             :   // necessary to resolve ambiguity/
    1109           0 :   operator nsISupports* () const { return get(); }
    1110             : 
    1111           0 :   nsISupports* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
    1112             :   {
    1113           0 :     MOZ_ASSERT(mRawPtr != nullptr,
    1114             :                "You can't dereference a NULL nsCOMPtr with operator->().");
    1115           0 :     return get();
    1116             :   }
    1117             : 
    1118             :   // These are not intended to be used by clients. See |address_of| below.
    1119             :   nsCOMPtr<nsISupports>* get_address() { return this; }
    1120             :   const nsCOMPtr<nsISupports>* get_address() const { return this; }
    1121             : 
    1122             : public:
    1123             : 
    1124             :   nsISupports& operator*() const
    1125             :   {
    1126             :     MOZ_ASSERT(mRawPtr != nullptr,
    1127             :                "You can't dereference a NULL nsCOMPtr with operator*().");
    1128             :     return *get();
    1129             :   }
    1130             : 
    1131             :   nsISupports** StartAssignment()
    1132             :   {
    1133             : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
    1134           0 :     return reinterpret_cast<nsISupports**>(begin_assignment());
    1135             : #else
    1136             :     assign_assuming_AddRef(nullptr);
    1137             :     return reinterpret_cast<nsISupports**>(&mRawPtr);
    1138             : #endif
    1139             :   }
    1140             : };
    1141             : 
    1142             : template<typename T>
    1143             : inline void
    1144             : ImplCycleCollectionUnlink(nsCOMPtr<T>& aField)
    1145             : {
    1146           0 :   aField = nullptr;
    1147             : }
    1148             : 
    1149             : template<typename T>
    1150             : inline void
    1151           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
    1152             :                             nsCOMPtr<T>& aField,
    1153             :                             const char* aName,
    1154             :                             uint32_t aFlags = 0)
    1155             : {
    1156           0 :   CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
    1157           0 : }
    1158             : 
    1159             : #ifndef NSCAP_FEATURE_USE_BASE
    1160             : template<class T>
    1161             : void
    1162           0 : nsCOMPtr<T>::assign_with_AddRef(nsISupports* aRawPtr)
    1163             : {
    1164           0 :   if (aRawPtr) {
    1165           0 :     NSCAP_ADDREF(this, aRawPtr);
    1166             :   }
    1167           0 :   assign_assuming_AddRef(reinterpret_cast<T*>(aRawPtr));
    1168           0 : }
    1169             : 
    1170             : template<class T>
    1171             : void
    1172           0 : nsCOMPtr<T>::assign_from_qi(const nsQueryInterface aQI, const nsIID& aIID)
    1173             : {
    1174             :   void* newRawPtr;
    1175           0 :   if (NS_FAILED(aQI(aIID, &newRawPtr))) {
    1176           0 :     newRawPtr = nullptr;
    1177             :   }
    1178           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1179           0 : }
    1180             : 
    1181             : template<class T>
    1182             : void
    1183           0 : nsCOMPtr<T>::assign_from_qi_with_error(const nsQueryInterfaceWithError& aQI,
    1184             :                                        const nsIID& aIID)
    1185             : {
    1186             :   void* newRawPtr;
    1187           0 :   if (NS_FAILED(aQI(aIID, &newRawPtr))) {
    1188           0 :     newRawPtr = nullptr;
    1189             :   }
    1190           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1191           0 : }
    1192             : 
    1193             : template<class T>
    1194             : void
    1195           0 : nsCOMPtr<T>::assign_from_gs_cid(const nsGetServiceByCID aGS, const nsIID& aIID)
    1196             : {
    1197             :   void* newRawPtr;
    1198           0 :   if (NS_FAILED(aGS(aIID, &newRawPtr))) {
    1199           0 :     newRawPtr = nullptr;
    1200             :   }
    1201           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1202           0 : }
    1203             : 
    1204             : template<class T>
    1205             : void
    1206           0 : nsCOMPtr<T>::assign_from_gs_cid_with_error(const nsGetServiceByCIDWithError& aGS,
    1207             :                                            const nsIID& aIID)
    1208             : {
    1209             :   void* newRawPtr;
    1210           0 :   if (NS_FAILED(aGS(aIID, &newRawPtr))) {
    1211           0 :     newRawPtr = nullptr;
    1212             :   }
    1213           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1214           0 : }
    1215             : 
    1216             : template<class T>
    1217             : void
    1218           0 : nsCOMPtr<T>::assign_from_gs_contractid(const nsGetServiceByContractID aGS,
    1219             :                                        const nsIID& aIID)
    1220             : {
    1221             :   void* newRawPtr;
    1222           0 :   if (NS_FAILED(aGS(aIID, &newRawPtr))) {
    1223           0 :     newRawPtr = nullptr;
    1224             :   }
    1225           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1226           0 : }
    1227             : 
    1228             : template<class T>
    1229             : void
    1230           0 : nsCOMPtr<T>::assign_from_gs_contractid_with_error(
    1231             :     const nsGetServiceByContractIDWithError& aGS, const nsIID& aIID)
    1232             : {
    1233             :   void* newRawPtr;
    1234           0 :   if (NS_FAILED(aGS(aIID, &newRawPtr))) {
    1235           0 :     newRawPtr = nullptr;
    1236             :   }
    1237           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1238           0 : }
    1239             : 
    1240             : template<class T>
    1241             : void
    1242           0 : nsCOMPtr<T>::assign_from_query_referent(
    1243             :     const nsQueryReferent& aQueryReferent, const nsIID& aIID)
    1244             : {
    1245             :   void* newRawPtr;
    1246           0 :   if (NS_FAILED(aQueryReferent(aIID, &newRawPtr))) {
    1247           0 :     newRawPtr = nullptr;
    1248             :   }
    1249           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1250           0 : }
    1251             : 
    1252             : template<class T>
    1253             : void
    1254           0 : nsCOMPtr<T>::assign_from_helper(const nsCOMPtr_helper& helper, const nsIID& aIID)
    1255             : {
    1256             :   void* newRawPtr;
    1257           0 :   if (NS_FAILED(helper(aIID, &newRawPtr))) {
    1258           0 :     newRawPtr = nullptr;
    1259             :   }
    1260           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1261           0 : }
    1262             : 
    1263             : template<class T>
    1264             : void**
    1265             : nsCOMPtr<T>::begin_assignment()
    1266             : {
    1267           0 :   assign_assuming_AddRef(nullptr);
    1268             :   union
    1269             :   {
    1270             :     T** mT;
    1271             :     void** mVoid;
    1272             :   } result;
    1273           0 :   result.mT = &mRawPtr;
    1274             :   return result.mVoid;
    1275             : }
    1276             : #endif
    1277             : 
    1278             : template<class T>
    1279             : inline nsCOMPtr<T>*
    1280             : address_of(nsCOMPtr<T>& aPtr)
    1281             : {
    1282           0 :   return aPtr.get_address();
    1283             : }
    1284             : 
    1285             : template<class T>
    1286             : inline const nsCOMPtr<T>*
    1287             : address_of(const nsCOMPtr<T>& aPtr)
    1288             : {
    1289             :   return aPtr.get_address();
    1290             : }
    1291             : 
    1292             : /**
    1293             :  * This class is designed to be used for anonymous temporary objects in the
    1294             :  * argument list of calls that return COM interface pointers, e.g.,
    1295             :  *
    1296             :  *   nsCOMPtr<IFoo> fooP;
    1297             :  *   ...->QueryInterface(iid, getter_AddRefs(fooP))
    1298             :  *
    1299             :  * DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
    1300             :  *
    1301             :  * When initialized with a |nsCOMPtr|, as in the example above, it returns
    1302             :  * a |void**|, a |T**|, or an |nsISupports**| as needed, that the outer call
    1303             :  * (|QueryInterface| in this case) can fill in.
    1304             :  *
    1305             :  * This type should be a nested class inside |nsCOMPtr<T>|.
    1306             :  */
    1307             : template<class T>
    1308             : class nsGetterAddRefs
    1309             : {
    1310             : public:
    1311             :   explicit nsGetterAddRefs(nsCOMPtr<T>& aSmartPtr)
    1312           0 :     : mTargetSmartPtr(aSmartPtr)
    1313             :   {
    1314             :   }
    1315             : 
    1316             : #if defined(NSCAP_FEATURE_TEST_DONTQUERY_CASES) || defined(NSCAP_LOG_EXTERNAL_ASSIGNMENT)
    1317           0 :   ~nsGetterAddRefs()
    1318             :   {
    1319             : #ifdef NSCAP_LOG_EXTERNAL_ASSIGNMENT
    1320           0 :     NSCAP_LOG_ASSIGNMENT(reinterpret_cast<void*>(address_of(mTargetSmartPtr)),
    1321             :                          mTargetSmartPtr.get());
    1322             : #endif
    1323             : 
    1324             : #ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
    1325           0 :     mTargetSmartPtr.Assert_NoQueryNeeded();
    1326             : #endif
    1327           0 :   }
    1328             : #endif
    1329             : 
    1330           0 :   operator void**()
    1331             :   {
    1332           0 :     return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
    1333             :   }
    1334             : 
    1335           0 :   operator T**() { return mTargetSmartPtr.StartAssignment(); }
    1336           0 :   T*& operator*() { return *(mTargetSmartPtr.StartAssignment()); }
    1337             : 
    1338             : private:
    1339             :   nsCOMPtr<T>& mTargetSmartPtr;
    1340             : };
    1341             : 
    1342             : 
    1343             : template<>
    1344             : class nsGetterAddRefs<nsISupports>
    1345             : {
    1346             : public:
    1347             :   explicit nsGetterAddRefs(nsCOMPtr<nsISupports>& aSmartPtr)
    1348           0 :     : mTargetSmartPtr(aSmartPtr)
    1349             :   {
    1350             :   }
    1351             : 
    1352             : #ifdef NSCAP_LOG_EXTERNAL_ASSIGNMENT
    1353           0 :   ~nsGetterAddRefs()
    1354           0 :   {
    1355           0 :     NSCAP_LOG_ASSIGNMENT(reinterpret_cast<void*>(address_of(mTargetSmartPtr)),
    1356           0 :                          mTargetSmartPtr.get());
    1357           0 :   }
    1358             : #endif
    1359             : 
    1360           0 :   operator void**()
    1361             :   {
    1362           0 :     return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
    1363             :   }
    1364             : 
    1365           0 :   operator nsISupports**() { return mTargetSmartPtr.StartAssignment(); }
    1366             :   nsISupports*& operator*() { return *(mTargetSmartPtr.StartAssignment()); }
    1367             : 
    1368             : private:
    1369             :   nsCOMPtr<nsISupports>& mTargetSmartPtr;
    1370             : };
    1371             : 
    1372             : template<class T>
    1373             : inline nsGetterAddRefs<T>
    1374             : getter_AddRefs(nsCOMPtr<T>& aSmartPtr)
    1375             : {
    1376           0 :   return nsGetterAddRefs<T>(aSmartPtr);
    1377             : }
    1378             : 
    1379             : template<class T, class DestinationType>
    1380             : inline nsresult
    1381           0 : CallQueryInterface(T* aSource, nsGetterAddRefs<DestinationType> aDestination)
    1382             : {
    1383           0 :   return CallQueryInterface(aSource,
    1384           0 :                             static_cast<DestinationType**>(aDestination));
    1385             : }
    1386             : 
    1387             : 
    1388             : // Comparing two |nsCOMPtr|s
    1389             : 
    1390             : template<class T, class U>
    1391             : inline bool
    1392             : operator==(const nsCOMPtr<T>& aLhs, const nsCOMPtr<U>& aRhs)
    1393             : {
    1394           0 :   return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs.get());
    1395             : }
    1396             : 
    1397             : 
    1398             : template<class T, class U>
    1399             : inline bool
    1400             : operator!=(const nsCOMPtr<T>& aLhs, const nsCOMPtr<U>& aRhs)
    1401             : {
    1402           0 :   return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs.get());
    1403             : }
    1404             : 
    1405             : 
    1406             : // Comparing an |nsCOMPtr| to a raw pointer
    1407             : 
    1408             : template<class T, class U>
    1409             : inline bool
    1410             : operator==(const nsCOMPtr<T>& aLhs, const U* aRhs)
    1411             : {
    1412           0 :   return static_cast<const T*>(aLhs.get()) == aRhs;
    1413             : }
    1414             : 
    1415             : template<class T, class U>
    1416             : inline bool
    1417             : operator==(const U* aLhs, const nsCOMPtr<T>& aRhs)
    1418             : {
    1419           0 :   return aLhs == static_cast<const T*>(aRhs.get());
    1420             : }
    1421             : 
    1422             : template<class T, class U>
    1423             : inline bool
    1424             : operator!=(const nsCOMPtr<T>& aLhs, const U* aRhs)
    1425             : {
    1426             :   return static_cast<const T*>(aLhs.get()) != aRhs;
    1427             : }
    1428             : 
    1429             : template<class T, class U>
    1430             : inline bool
    1431             : operator!=(const U* aLhs, const nsCOMPtr<T>& aRhs)
    1432             : {
    1433             :   return aLhs != static_cast<const T*>(aRhs.get());
    1434             : }
    1435             : 
    1436             : template<class T, class U>
    1437             : inline bool
    1438             : operator==(const nsCOMPtr<T>& aLhs, U* aRhs)
    1439             : {
    1440           0 :   return static_cast<const T*>(aLhs.get()) == const_cast<const U*>(aRhs);
    1441             : }
    1442             : 
    1443             : template<class T, class U>
    1444             : inline bool
    1445             : operator==(U* aLhs, const nsCOMPtr<T>& aRhs)
    1446             : {
    1447           0 :   return const_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
    1448             : }
    1449             : 
    1450             : template<class T, class U>
    1451             : inline bool
    1452             : operator!=(const nsCOMPtr<T>& aLhs, U* aRhs)
    1453             : {
    1454           0 :   return static_cast<const T*>(aLhs.get()) != const_cast<const U*>(aRhs);
    1455             : }
    1456             : 
    1457             : template<class T, class U>
    1458             : inline bool
    1459             : operator!=(U* aLhs, const nsCOMPtr<T>& aRhs)
    1460             : {
    1461           0 :   return const_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
    1462             : }
    1463             : 
    1464             : 
    1465             : 
    1466             : // Comparing an |nsCOMPtr| to |nullptr|
    1467             : 
    1468             : template<class T>
    1469             : inline bool
    1470             : operator==(const nsCOMPtr<T>& aLhs, decltype(nullptr))
    1471             : {
    1472           0 :   return aLhs.get() == nullptr;
    1473             : }
    1474             : 
    1475             : template<class T>
    1476             : inline bool
    1477             : operator==(decltype(nullptr), const nsCOMPtr<T>& aRhs)
    1478             : {
    1479           0 :   return nullptr == aRhs.get();
    1480             : }
    1481             : 
    1482             : template<class T>
    1483             : inline bool
    1484             : operator!=(const nsCOMPtr<T>& aLhs, decltype(nullptr))
    1485             : {
    1486           0 :   return aLhs.get() != nullptr;
    1487             : }
    1488             : 
    1489             : template<class T>
    1490             : inline bool
    1491             : operator!=(decltype(nullptr), const nsCOMPtr<T>& aRhs)
    1492             : {
    1493           0 :   return nullptr != aRhs.get();
    1494             : }
    1495             : 
    1496             : 
    1497             : // Comparing any two [XP]COM objects for identity
    1498             : 
    1499             : inline bool
    1500           0 : SameCOMIdentity(nsISupports* aLhs, nsISupports* aRhs)
    1501             : {
    1502           0 :   return nsCOMPtr<nsISupports>(do_QueryInterface(aLhs)) ==
    1503           0 :     nsCOMPtr<nsISupports>(do_QueryInterface(aRhs));
    1504             : }
    1505             : 
    1506             : 
    1507             : 
    1508             : template<class SourceType, class DestinationType>
    1509             : inline nsresult
    1510           0 : CallQueryInterface(nsCOMPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr)
    1511             : {
    1512           0 :   return CallQueryInterface(aSourcePtr.get(), aDestPtr);
    1513             : }
    1514             : 
    1515             : template <class T>
    1516           0 : RefPtr<T>::RefPtr(const nsQueryReferent& aQueryReferent)
    1517             : {
    1518             :   void* newRawPtr;
    1519           0 :   if (NS_FAILED(aQueryReferent(NS_GET_TEMPLATE_IID(T), &newRawPtr))) {
    1520           0 :     newRawPtr = nullptr;
    1521             :   }
    1522           0 :   mRawPtr = static_cast<T*>(newRawPtr);
    1523           0 : }
    1524             : 
    1525             : template <class T>
    1526           0 : RefPtr<T>::RefPtr(const nsCOMPtr_helper& aHelper)
    1527             : {
    1528             :   void* newRawPtr;
    1529           0 :   if (NS_FAILED(aHelper(NS_GET_TEMPLATE_IID(T), &newRawPtr))) {
    1530           0 :     newRawPtr = nullptr;
    1531             :   }
    1532           0 :   mRawPtr = static_cast<T*>(newRawPtr);
    1533           0 : }
    1534             : 
    1535             : template <class T>
    1536             : RefPtr<T>&
    1537             : RefPtr<T>::operator=(const nsQueryReferent& aQueryReferent)
    1538             : {
    1539             :   void* newRawPtr;
    1540             :   if (NS_FAILED(aQueryReferent(NS_GET_TEMPLATE_IID(T), &newRawPtr))) {
    1541             :     newRawPtr = nullptr;
    1542             :   }
    1543             :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1544             :   return *this;
    1545             : }
    1546             : 
    1547             : template <class T>
    1548             : RefPtr<T>&
    1549           0 : RefPtr<T>::operator=(const nsCOMPtr_helper& aHelper)
    1550             : {
    1551             :   void* newRawPtr;
    1552           0 :   if (NS_FAILED(aHelper(NS_GET_TEMPLATE_IID(T), &newRawPtr))) {
    1553           0 :     newRawPtr = nullptr;
    1554             :   }
    1555           0 :   assign_assuming_AddRef(static_cast<T*>(newRawPtr));
    1556           0 :   return *this;
    1557             : }
    1558             : 
    1559             : template <class T>
    1560             : inline already_AddRefed<T>
    1561           0 : do_AddRef(const nsCOMPtr<T>& aObj)
    1562             : {
    1563           0 :   nsCOMPtr<T> ref(aObj);
    1564           0 :   return ref.forget();
    1565             : }
    1566             : 
    1567             : #endif // !defined(nsCOMPtr_h___)

Generated by: LCOV version 1.13-14-ga5dd952