LCOV - code coverage report
Current view: top level - mfbt - RefPtr.h (source / functions) Hit Total Coverage
Test: output.info Lines: 173 188 92.0 %
Date: 2017-07-14 16:53:18 Functions: 12755 62707 20.3 %
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 mozilla_RefPtr_h
       8             : #define mozilla_RefPtr_h
       9             : 
      10             : #include "mozilla/AlreadyAddRefed.h"
      11             : #include "mozilla/Assertions.h"
      12             : #include "mozilla/Attributes.h"
      13             : 
      14             : /*****************************************************************************/
      15             : 
      16             : // template <class T> class RefPtrGetterAddRefs;
      17             : 
      18             : class nsCOMPtr_helper;
      19             : 
      20             : namespace mozilla {
      21             : template<class T> class OwningNonNull;
      22             : template<class T> class StaticRefPtr;
      23             : 
      24             : // Traditionally, RefPtr supports automatic refcounting of any pointer type
      25             : // with AddRef() and Release() methods that follow the traditional semantics.
      26             : //
      27             : // This traits class can be specialized to operate on other pointer types. For
      28             : // example, we specialize this trait for opaque FFI types that represent
      29             : // refcounted objects in Rust.
      30             : //
      31             : // Given the use of ConstRemovingRefPtrTraits below, U should not be a const-
      32             : // qualified type.
      33             : template<class U>
      34             : struct RefPtrTraits
      35             : {
      36      297736 :   static void AddRef(U* aPtr) {
      37      297736 :     aPtr->AddRef();
      38      297737 :   }
      39      260968 :   static void Release(U* aPtr) {
      40      260968 :     aPtr->Release();
      41      260968 :   }
      42             : };
      43             : 
      44             : } // namespace mozilla
      45             : 
      46             : template <class T>
      47             : class RefPtr
      48             : {
      49             : private:
      50             :   void
      51      135724 :   assign_with_AddRef(T* aRawPtr)
      52             :   {
      53      135724 :     if (aRawPtr) {
      54      121409 :       ConstRemovingRefPtrTraits<T>::AddRef(aRawPtr);
      55             :     }
      56      135724 :     assign_assuming_AddRef(aRawPtr);
      57      135724 :   }
      58             : 
      59             :   void
      60      250165 :   assign_assuming_AddRef(T* aNewPtr)
      61             :   {
      62      250165 :     T* oldPtr = mRawPtr;
      63      250165 :     mRawPtr = aNewPtr;
      64      250165 :     if (oldPtr) {
      65       16685 :       ConstRemovingRefPtrTraits<T>::Release(oldPtr);
      66             :     }
      67      250165 :   }
      68             : 
      69             : private:
      70             :   T* MOZ_OWNING_REF mRawPtr;
      71             : 
      72             : public:
      73             :   typedef T element_type;
      74             : 
      75      534297 :   ~RefPtr()
      76             :   {
      77      534297 :     if (mRawPtr) {
      78      244274 :       ConstRemovingRefPtrTraits<T>::Release(mRawPtr);
      79             :     }
      80      534297 :   }
      81             : 
      82             :   // Constructors
      83             : 
      84      289289 :   RefPtr()
      85      289289 :     : mRawPtr(nullptr)
      86             :     // default constructor
      87             :   {
      88      289289 :   }
      89             : 
      90       19180 :   RefPtr(const RefPtr<T>& aSmartPtr)
      91       19180 :     : mRawPtr(aSmartPtr.mRawPtr)
      92             :     // copy-constructor
      93             :   {
      94       19180 :     if (mRawPtr) {
      95       13233 :       ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
      96             :     }
      97       19180 :   }
      98             : 
      99        3032 :   RefPtr(RefPtr<T>&& aRefPtr)
     100        3032 :     : mRawPtr(aRefPtr.mRawPtr)
     101             :   {
     102        3032 :     aRefPtr.mRawPtr = nullptr;
     103        3032 :   }
     104             : 
     105             :   // construct from a raw pointer (of the right type)
     106             : 
     107      186420 :   MOZ_IMPLICIT RefPtr(T* aRawPtr)
     108      186420 :     : mRawPtr(aRawPtr)
     109             :   {
     110      186420 :     if (mRawPtr) {
     111      162479 :       ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
     112             :     }
     113      186420 :   }
     114             : 
     115       12748 :   MOZ_IMPLICIT RefPtr(decltype(nullptr))
     116       12748 :     : mRawPtr(nullptr)
     117             :   {
     118       12748 :   }
     119             : 
     120             :   template <typename I>
     121       11887 :   MOZ_IMPLICIT RefPtr(already_AddRefed<I>& aSmartPtr)
     122       11887 :     : mRawPtr(aSmartPtr.take())
     123             :     // construct from |already_AddRefed|
     124             :   {
     125       11887 :   }
     126             : 
     127             :   template <typename I>
     128       54162 :   MOZ_IMPLICIT RefPtr(already_AddRefed<I>&& aSmartPtr)
     129       54162 :     : mRawPtr(aSmartPtr.take())
     130             :     // construct from |otherRefPtr.forget()|
     131             :   {
     132       54162 :   }
     133             : 
     134             :   template <typename I>
     135         603 :   MOZ_IMPLICIT RefPtr(const RefPtr<I>& aSmartPtr)
     136         603 :     : mRawPtr(aSmartPtr.get())
     137             :     // copy-construct from a smart pointer with a related pointer type
     138             :   {
     139         603 :     if (mRawPtr) {
     140         603 :       ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
     141             :     }
     142         603 :   }
     143             : 
     144             :   template <typename I>
     145           2 :   MOZ_IMPLICIT RefPtr(RefPtr<I>&& aSmartPtr)
     146           2 :     : mRawPtr(aSmartPtr.forget().take())
     147             :     // construct from |Move(RefPtr<SomeSubclassOfT>)|.
     148             :   {
     149           2 :   }
     150             : 
     151             :   MOZ_IMPLICIT RefPtr(const nsCOMPtr_helper& aHelper);
     152             : 
     153             :   // Defined in OwningNonNull.h
     154             :   template<class U>
     155             :   MOZ_IMPLICIT RefPtr(const mozilla::OwningNonNull<U>& aOther);
     156             : 
     157             :   // Defined in StaticPtr.h
     158             :   template<class U>
     159             :   MOZ_IMPLICIT RefPtr(const mozilla::StaticRefPtr<U>& aOther);
     160             : 
     161             :   // Assignment operators
     162             : 
     163             :   RefPtr<T>&
     164       49067 :   operator=(decltype(nullptr))
     165             :   {
     166       49067 :     assign_assuming_AddRef(nullptr);
     167       49067 :     return *this;
     168             :   }
     169             : 
     170             :   RefPtr<T>&
     171        7094 :   operator=(const RefPtr<T>& aRhs)
     172             :   // copy assignment operator
     173             :   {
     174        7094 :     assign_with_AddRef(aRhs.mRawPtr);
     175        7094 :     return *this;
     176             :   }
     177             : 
     178             :   template <typename I>
     179             :   RefPtr<T>&
     180        1514 :   operator=(const RefPtr<I>& aRhs)
     181             :   // assign from an RefPtr of a related pointer type
     182             :   {
     183        1514 :     assign_with_AddRef(aRhs.get());
     184        1514 :     return *this;
     185             :   }
     186             : 
     187             :   RefPtr<T>&
     188      127117 :   operator=(T* aRhs)
     189             :   // assign from a raw pointer (of the right type)
     190             :   {
     191      127117 :     assign_with_AddRef(aRhs);
     192      127117 :     return *this;
     193             :   }
     194             : 
     195             :   template <typename I>
     196             :   RefPtr<T>&
     197        2861 :   operator=(already_AddRefed<I>& aRhs)
     198             :   // assign from |already_AddRefed|
     199             :   {
     200        2861 :     assign_assuming_AddRef(aRhs.take());
     201        2861 :     return *this;
     202             :   }
     203             : 
     204             :   template <typename I>
     205             :   RefPtr<T>&
     206       32093 :   operator=(already_AddRefed<I> && aRhs)
     207             :   // assign from |otherRefPtr.forget()|
     208             :   {
     209       32093 :     assign_assuming_AddRef(aRhs.take());
     210       32093 :     return *this;
     211             :   }
     212             : 
     213             :   RefPtr<T>& operator=(const nsCOMPtr_helper& aHelper);
     214             : 
     215             :   RefPtr<T>&
     216         117 :   operator=(RefPtr<T> && aRefPtr)
     217             :   {
     218         117 :     assign_assuming_AddRef(aRefPtr.mRawPtr);
     219         117 :     aRefPtr.mRawPtr = nullptr;
     220         117 :     return *this;
     221             :   }
     222             : 
     223             :   // Defined in OwningNonNull.h
     224             :   template<class U>
     225             :   RefPtr<T>&
     226             :   operator=(const mozilla::OwningNonNull<U>& aOther);
     227             : 
     228             :   // Defined in StaticPtr.h
     229             :   template<class U>
     230             :   RefPtr<T>&
     231             :   operator=(const mozilla::StaticRefPtr<U>& aOther);
     232             : 
     233             :   // Other pointer operators
     234             : 
     235             :   void
     236         298 :   swap(RefPtr<T>& aRhs)
     237             :   // ...exchange ownership with |aRhs|; can save a pair of refcount operations
     238             :   {
     239         298 :     T* temp = aRhs.mRawPtr;
     240         298 :     aRhs.mRawPtr = mRawPtr;
     241         298 :     mRawPtr = temp;
     242         298 :   }
     243             : 
     244             :   void
     245      107147 :   swap(T*& aRhs)
     246             :   // ...exchange ownership with |aRhs|; can save a pair of refcount operations
     247             :   {
     248      107147 :     T* temp = aRhs;
     249      107147 :     aRhs = mRawPtr;
     250      107147 :     mRawPtr = temp;
     251      107147 :   }
     252             : 
     253             :   already_AddRefed<T>
     254             :   MOZ_MAY_CALL_AFTER_MUST_RETURN
     255      106625 :   forget()
     256             :   // return the value of mRawPtr and null out mRawPtr. Useful for
     257             :   // already_AddRefed return values.
     258             :   {
     259      106625 :     T* temp = nullptr;
     260      106625 :     swap(temp);
     261      106625 :     return already_AddRefed<T>(temp);
     262             :   }
     263             : 
     264             :   template <typename I>
     265             :   void
     266       35207 :   forget(I** aRhs)
     267             :   // Set the target of aRhs to the value of mRawPtr and null out mRawPtr.
     268             :   // Useful to avoid unnecessary AddRef/Release pairs with "out"
     269             :   // parameters where aRhs bay be a T** or an I** where I is a base class
     270             :   // of T.
     271             :   {
     272       35207 :     MOZ_ASSERT(aRhs, "Null pointer passed to forget!");
     273       35207 :     *aRhs = mRawPtr;
     274       35207 :     mRawPtr = nullptr;
     275       35207 :   }
     276             : 
     277             :   T*
     278     2272618 :   get() const
     279             :   /*
     280             :     Prefer the implicit conversion provided automatically by |operator T*() const|.
     281             :     Use |get()| to resolve ambiguity or to get a castable pointer.
     282             :   */
     283             :   {
     284     2272618 :     return const_cast<T*>(mRawPtr);
     285             :   }
     286             : 
     287     1006518 :   operator T*() const &
     288             :   /*
     289             :     ...makes an |RefPtr| act like its underlying raw pointer type whenever it
     290             :     is used in a context where a raw pointer is expected.  It is this operator
     291             :     that makes an |RefPtr| substitutable for a raw pointer.
     292             : 
     293             :     Prefer the implicit use of this operator to calling |get()|, except where
     294             :     necessary to resolve ambiguity.
     295             :   */
     296             :   {
     297     1006518 :     return get();
     298             :   }
     299             : 
     300             :   // Don't allow implicit conversion of temporary RefPtr to raw pointer,
     301             :   // because the refcount might be one and the pointer will immediately become
     302             :   // invalid.
     303             :   operator T*() const && = delete;
     304             : 
     305             :   // These are needed to avoid the deleted operator above.  XXX Why is operator!
     306             :   // needed separately?  Shouldn't the compiler prefer using the non-deleted
     307             :   // operator bool instead of the deleted operator T*?
     308      228520 :   explicit operator bool() const { return !!mRawPtr; }
     309      699073 :   bool operator!() const { return !mRawPtr; }
     310             : 
     311             :   T*
     312      981679 :   operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
     313             :   {
     314      981679 :     MOZ_ASSERT(mRawPtr != nullptr,
     315             :                "You can't dereference a NULL RefPtr with operator->().");
     316      981679 :     return get();
     317             :   }
     318             : 
     319             :   template <typename R, typename... Args>
     320             :   class Proxy
     321             :   {
     322             :     typedef R (T::*member_function)(Args...);
     323             :     T* mRawPtr;
     324             :     member_function mFunction;
     325             :   public:
     326          16 :     Proxy(T* aRawPtr, member_function aFunction)
     327             :       : mRawPtr(aRawPtr),
     328          16 :         mFunction(aFunction)
     329             :     {
     330          16 :     }
     331             :     template<typename... ActualArgs>
     332          16 :     R operator()(ActualArgs&&... aArgs)
     333             :     {
     334          16 :       return ((*mRawPtr).*mFunction)(mozilla::Forward<ActualArgs>(aArgs)...);
     335             :     }
     336             :   };
     337             : 
     338             :   template <typename R, typename... Args>
     339          16 :   Proxy<R, Args...> operator->*(R (T::*aFptr)(Args...)) const
     340             :   {
     341          16 :     MOZ_ASSERT(mRawPtr != nullptr,
     342             :                "You can't dereference a NULL RefPtr with operator->*().");
     343          16 :     return Proxy<R, Args...>(get(), aFptr);
     344             :   }
     345             : 
     346             :   RefPtr<T>*
     347           0 :   get_address()
     348             :   // This is not intended to be used by clients.  See |address_of|
     349             :   // below.
     350             :   {
     351           0 :     return this;
     352             :   }
     353             : 
     354             :   const RefPtr<T>*
     355             :   get_address() const
     356             :   // This is not intended to be used by clients.  See |address_of|
     357             :   // below.
     358             :   {
     359             :     return this;
     360             :   }
     361             : 
     362             : public:
     363             :   T&
     364        3348 :   operator*() const
     365             :   {
     366        3348 :     MOZ_ASSERT(mRawPtr != nullptr,
     367             :                "You can't dereference a NULL RefPtr with operator*().");
     368        3348 :     return *get();
     369             :   }
     370             : 
     371             :   T**
     372       30284 :   StartAssignment()
     373             :   {
     374       30284 :     assign_assuming_AddRef(nullptr);
     375       30284 :     return reinterpret_cast<T**>(&mRawPtr);
     376             :   }
     377             : private:
     378             :   // This helper class makes |RefPtr<const T>| possible by casting away
     379             :   // the constness from the pointer when calling AddRef() and Release().
     380             :   //
     381             :   // This is necessary because AddRef() and Release() implementations can't
     382             :   // generally expected to be const themselves (without heavy use of |mutable|
     383             :   // and |const_cast| in their own implementations).
     384             :   //
     385             :   // This should be sound because while |RefPtr<const T>| provides a
     386             :   // const view of an object, the object itself should not be const (it
     387             :   // would have to be allocated as |new const T| or similar to be const).
     388             :   template<class U>
     389             :   struct ConstRemovingRefPtrTraits
     390             :   {
     391      297736 :     static void AddRef(U* aPtr) {
     392      297736 :       mozilla::RefPtrTraits<U>::AddRef(aPtr);
     393      297737 :     }
     394      260968 :     static void Release(U* aPtr) {
     395      260968 :       mozilla::RefPtrTraits<U>::Release(aPtr);
     396      260968 :     }
     397             :   };
     398             :   template<class U>
     399             :   struct ConstRemovingRefPtrTraits<const U>
     400             :   {
     401           0 :     static void AddRef(const U* aPtr) {
     402           0 :       mozilla::RefPtrTraits<U>::AddRef(const_cast<U*>(aPtr));
     403           0 :     }
     404           0 :     static void Release(const U* aPtr) {
     405           0 :       mozilla::RefPtrTraits<U>::Release(const_cast<U*>(aPtr));
     406           0 :     }
     407             :   };
     408             : };
     409             : 
     410             : class nsCycleCollectionTraversalCallback;
     411             : template <typename T>
     412             : void
     413             : CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback,
     414             :                          T* aChild, const char* aName, uint32_t aFlags);
     415             : 
     416             : template <typename T>
     417             : inline void
     418           2 : ImplCycleCollectionUnlink(RefPtr<T>& aField)
     419             : {
     420           2 :   aField = nullptr;
     421           2 : }
     422             : 
     423             : template <typename T>
     424             : inline void
     425         919 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
     426             :                             RefPtr<T>& aField,
     427             :                             const char* aName,
     428             :                             uint32_t aFlags = 0)
     429             : {
     430         919 :   CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
     431         919 : }
     432             : 
     433             : template <class T>
     434             : inline RefPtr<T>*
     435           0 : address_of(RefPtr<T>& aPtr)
     436             : {
     437           0 :   return aPtr.get_address();
     438             : }
     439             : 
     440             : template <class T>
     441             : inline const RefPtr<T>*
     442             : address_of(const RefPtr<T>& aPtr)
     443             : {
     444             :   return aPtr.get_address();
     445             : }
     446             : 
     447             : template <class T>
     448             : class RefPtrGetterAddRefs
     449             : /*
     450             :   ...
     451             : 
     452             :   This class is designed to be used for anonymous temporary objects in the
     453             :   argument list of calls that return COM interface pointers, e.g.,
     454             : 
     455             :     RefPtr<IFoo> fooP;
     456             :     ...->GetAddRefedPointer(getter_AddRefs(fooP))
     457             : 
     458             :   DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
     459             : 
     460             :   When initialized with a |RefPtr|, as in the example above, it returns
     461             :   a |void**|, a |T**|, or an |nsISupports**| as needed, that the
     462             :   outer call (|GetAddRefedPointer| in this case) can fill in.
     463             : 
     464             :   This type should be a nested class inside |RefPtr<T>|.
     465             : */
     466             : {
     467             : public:
     468             :   explicit
     469       30284 :   RefPtrGetterAddRefs(RefPtr<T>& aSmartPtr)
     470       30284 :     : mTargetSmartPtr(aSmartPtr)
     471             :   {
     472             :     // nothing else to do
     473       30284 :   }
     474             : 
     475        9697 :   operator void**()
     476             :   {
     477        9697 :     return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
     478             :   }
     479             : 
     480       20589 :   operator T**()
     481             :   {
     482       20589 :     return mTargetSmartPtr.StartAssignment();
     483             :   }
     484             : 
     485             :   T*&
     486             :   operator*()
     487             :   {
     488             :     return *(mTargetSmartPtr.StartAssignment());
     489             :   }
     490             : 
     491             : private:
     492             :   RefPtr<T>& mTargetSmartPtr;
     493             : };
     494             : 
     495             : template <class T>
     496             : inline RefPtrGetterAddRefs<T>
     497       30286 : getter_AddRefs(RefPtr<T>& aSmartPtr)
     498             : /*
     499             :   Used around a |RefPtr| when
     500             :   ...makes the class |RefPtrGetterAddRefs<T>| invisible.
     501             : */
     502             : {
     503       30286 :   return RefPtrGetterAddRefs<T>(aSmartPtr);
     504             : }
     505             : 
     506             : 
     507             : // Comparing two |RefPtr|s
     508             : 
     509             : template <class T, class U>
     510             : inline bool
     511        4790 : operator==(const RefPtr<T>& aLhs, const RefPtr<U>& aRhs)
     512             : {
     513        4790 :   return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs.get());
     514             : }
     515             : 
     516             : 
     517             : template <class T, class U>
     518             : inline bool
     519        3956 : operator!=(const RefPtr<T>& aLhs, const RefPtr<U>& aRhs)
     520             : {
     521        3956 :   return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs.get());
     522             : }
     523             : 
     524             : 
     525             : // Comparing an |RefPtr| to a raw pointer
     526             : 
     527             : template <class T, class U>
     528             : inline bool
     529          61 : operator==(const RefPtr<T>& aLhs, const U* aRhs)
     530             : {
     531          61 :   return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs);
     532             : }
     533             : 
     534             : template <class T, class U>
     535             : inline bool
     536         571 : operator==(const U* aLhs, const RefPtr<T>& aRhs)
     537             : {
     538         571 :   return static_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
     539             : }
     540             : 
     541             : template <class T, class U>
     542             : inline bool
     543             : operator!=(const RefPtr<T>& aLhs, const U* aRhs)
     544             : {
     545             :   return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs);
     546             : }
     547             : 
     548             : template <class T, class U>
     549             : inline bool
     550           0 : operator!=(const U* aLhs, const RefPtr<T>& aRhs)
     551             : {
     552           0 :   return static_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
     553             : }
     554             : 
     555             : template <class T, class U>
     556             : inline bool
     557        8387 : operator==(const RefPtr<T>& aLhs, U* aRhs)
     558             : {
     559        8387 :   return static_cast<const T*>(aLhs.get()) == const_cast<const U*>(aRhs);
     560             : }
     561             : 
     562             : template <class T, class U>
     563             : inline bool
     564        3571 : operator==(U* aLhs, const RefPtr<T>& aRhs)
     565             : {
     566        3571 :   return const_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
     567             : }
     568             : 
     569             : template <class T, class U>
     570             : inline bool
     571        3590 : operator!=(const RefPtr<T>& aLhs, U* aRhs)
     572             : {
     573        3590 :   return static_cast<const T*>(aLhs.get()) != const_cast<const U*>(aRhs);
     574             : }
     575             : 
     576             : template <class T, class U>
     577             : inline bool
     578       25263 : operator!=(U* aLhs, const RefPtr<T>& aRhs)
     579             : {
     580       25263 :   return const_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
     581             : }
     582             : 
     583             : // Comparing an |RefPtr| to |nullptr|
     584             : 
     585             : template <class T>
     586             : inline bool
     587      184924 : operator==(const RefPtr<T>& aLhs, decltype(nullptr))
     588             : {
     589      184924 :   return aLhs.get() == nullptr;
     590             : }
     591             : 
     592             : template <class T>
     593             : inline bool
     594        2988 : operator==(decltype(nullptr), const RefPtr<T>& aRhs)
     595             : {
     596        2988 :   return nullptr == aRhs.get();
     597             : }
     598             : 
     599             : template <class T>
     600             : inline bool
     601        6671 : operator!=(const RefPtr<T>& aLhs, decltype(nullptr))
     602             : {
     603        6671 :   return aLhs.get() != nullptr;
     604             : }
     605             : 
     606             : template <class T>
     607             : inline bool
     608          28 : operator!=(decltype(nullptr), const RefPtr<T>& aRhs)
     609             : {
     610          28 :   return nullptr != aRhs.get();
     611             : }
     612             : 
     613             : /*****************************************************************************/
     614             : 
     615             : template <class T>
     616             : inline already_AddRefed<T>
     617        3568 : do_AddRef(T* aObj)
     618             : {
     619        7136 :   RefPtr<T> ref(aObj);
     620        7136 :   return ref.forget();
     621             : }
     622             : 
     623             : template <class T>
     624             : inline already_AddRefed<T>
     625          99 : do_AddRef(const RefPtr<T>& aObj)
     626             : {
     627         198 :   RefPtr<T> ref(aObj);
     628         198 :   return ref.forget();
     629             : }
     630             : 
     631             : namespace mozilla {
     632             : 
     633             : /**
     634             :  * Helper function to be able to conveniently write things like:
     635             :  *
     636             :  *   already_AddRefed<T>
     637             :  *   f(...)
     638             :  *   {
     639             :  *     return MakeAndAddRef<T>(...);
     640             :  *   }
     641             :  */
     642             : template<typename T, typename... Args>
     643             : already_AddRefed<T>
     644         315 : MakeAndAddRef(Args&&... aArgs)
     645             : {
     646         945 :   RefPtr<T> p(new T(Forward<Args>(aArgs)...));
     647         630 :   return p.forget();
     648             : }
     649             : 
     650             : /**
     651             :  * Helper function to be able to conveniently write things like:
     652             :  *
     653             :  *   auto runnable = MakeRefPtr<ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>>(
     654             :  *       mOnSuccess, mOnFailure, *error, mWindowID);
     655             :  */
     656             : template<typename T, typename... Args>
     657             : RefPtr<T>
     658           0 : MakeRefPtr(Args&&... aArgs)
     659             : {
     660           0 :   RefPtr<T> p(new T(Forward<Args>(aArgs)...));
     661           0 :   return p;
     662             : }
     663             : 
     664             : } // namespace mozilla
     665             : 
     666             : #endif /* mozilla_RefPtr_h */

Generated by: LCOV version 1.13