LCOV - code coverage report
Current view: top level - xpcom/base - nsAutoRef.h (source / functions) Hit Total Coverage
Test: output.info Lines: 74 127 58.3 %
Date: 2017-07-14 16:53:18 Functions: 67 291 23.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 nsAutoRef_h_
       8             : #define nsAutoRef_h_
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : 
      12             : #include "nscore.h" // for nullptr, bool
      13             : 
      14             : template <class T> class nsSimpleRef;
      15             : template <class T> class nsAutoRefBase;
      16             : template <class T> class nsReturnRef;
      17             : template <class T> class nsReturningRef;
      18             : 
      19             : /**
      20             :  * template <class T> class nsAutoRef
      21             :  *
      22             :  * A class that holds a handle to a resource that must be released.
      23             :  * No reference is added on construction.
      24             :  *
      25             :  * No copy constructor nor copy assignment operators are available, so the
      26             :  * resource will be held until released on destruction or explicitly
      27             :  * |reset()| or transferred through provided methods.
      28             :  *
      29             :  * The publicly available methods are the public methods on this class and its
      30             :  * public base classes |nsAutoRefBase<T>| and |nsSimpleRef<T>|.
      31             :  *
      32             :  * For ref-counted resources see also |nsCountedRef<T>|.
      33             :  * For function return values see |nsReturnRef<T>|.
      34             :  *
      35             :  * For each class |T|, |nsAutoRefTraits<T>| or |nsSimpleRef<T>| must be
      36             :  * specialized to use |nsAutoRef<T>| and |nsCountedRef<T>|.
      37             :  *
      38             :  * @param T  A class identifying the type of reference held by the
      39             :  *           |nsAutoRef<T>| and the unique set methods for managing references
      40             :  *           to the resource (defined by |nsAutoRefTraits<T>| or
      41             :  *           |nsSimpleRef<T>|).
      42             :  *
      43             :  *           Often this is the class representing the resource.  Sometimes a
      44             :  *           new possibly-incomplete class may need to be declared.
      45             :  *
      46             :  *
      47             :  * Example:  An Automatically closing file descriptor
      48             :  *
      49             :  * // References that are simple integral types (as file-descriptors are)
      50             :  * // usually need a new class to represent the resource and how to handle its
      51             :  * // references.
      52             :  * class nsRawFD;
      53             :  *
      54             :  * // Specializing nsAutoRefTraits<nsRawFD> describes how to manage file
      55             :  * // descriptors, so that nsAutoRef<nsRawFD> provides automatic closing of
      56             :  * // its file descriptor on destruction.
      57             :  * template <>
      58             :  * class nsAutoRefTraits<nsRawFD> {
      59             :  * public:
      60             :  *     // The file descriptor is held in an int.
      61             :  *     typedef int RawRef;
      62             :  *     // -1 means that there is no file associated with the handle.
      63             :  *     static int Void() { return -1; }
      64             :  *     // The file associated with a file descriptor is released with close().
      65             :  *     static void Release(RawRef aFD) { close(aFD); }
      66             :  * };
      67             :  *
      68             :  * // A function returning a file descriptor that must be closed.
      69             :  * nsReturnRef<nsRawFD> get_file(const char *filename) {
      70             :  *     // Constructing from a raw file descriptor assumes ownership.
      71             :  *     nsAutoRef<nsRawFD> fd(open(filename, O_RDONLY));
      72             :  *     fcntl(fd, F_SETFD, FD_CLOEXEC);
      73             :  *     return fd.out();
      74             :  * }
      75             :  *
      76             :  * void f() {
      77             :  *     unsigned char buf[1024];
      78             :  *
      79             :  *     // Hold a file descriptor for /etc/hosts in fd1.
      80             :  *     nsAutoRef<nsRawFD> fd1(get_file("/etc/hosts"));
      81             :  *
      82             :  *     nsAutoRef<nsRawFD> fd2;
      83             :  *     fd2.steal(fd1); // fd2 takes the file descriptor from fd1
      84             :  *     ssize_t count = read(fd1, buf, 1024); // error fd1 has no file
      85             :  *     count = read(fd2, buf, 1024); // reads from /etc/hosts
      86             :  *
      87             :  *     // If the file descriptor is not stored then it is closed.
      88             :  *     get_file("/etc/login.defs"); // login.defs is closed
      89             :  *
      90             :  *     // Now use fd1 to hold a file descriptor for /etc/passwd.
      91             :  *     fd1 = get_file("/etc/passwd");
      92             :  *
      93             :  *     // The nsAutoRef<nsRawFD> can give up the file descriptor if explicitly
      94             :  *     // instructed, but the caller must then ensure that the file is closed.
      95             :  *     int rawfd = fd1.disown();
      96             :  *
      97             :  *     // Assume ownership of another file descriptor.
      98             :  *     fd1.own(open("/proc/1/maps");
      99             :  *
     100             :  *     // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts,
     101             :  *     // but /etc/passwd is not closed.
     102             :  * }
     103             :  *
     104             :  */
     105             : 
     106             : 
     107             : template <class T>
     108        1833 : class nsAutoRef : public nsAutoRefBase<T>
     109             : {
     110             : protected:
     111             :   typedef nsAutoRef<T> ThisClass;
     112             :   typedef nsAutoRefBase<T> BaseClass;
     113             :   typedef nsSimpleRef<T> SimpleRef;
     114             :   typedef typename BaseClass::RawRefOnly RawRefOnly;
     115             :   typedef typename BaseClass::LocalSimpleRef LocalSimpleRef;
     116             : 
     117             : public:
     118        4312 :   nsAutoRef()
     119        4312 :   {
     120        4312 :   }
     121             : 
     122             :   // Explicit construction is required so as not to risk unintentionally
     123             :   // releasing the resource associated with a raw ref.
     124        1844 :   explicit nsAutoRef(RawRefOnly aRefToRelease)
     125        1844 :     : BaseClass(aRefToRelease)
     126             :   {
     127        1844 :   }
     128             : 
     129             :   // Construction from a nsReturnRef<T> function return value, which expects
     130             :   // to give up ownership, transfers ownership.
     131             :   // (nsReturnRef<T> is converted to const nsReturningRef<T>.)
     132           0 :   explicit nsAutoRef(const nsReturningRef<T>& aReturning)
     133           0 :     : BaseClass(aReturning)
     134             :   {
     135           0 :   }
     136             : 
     137             :   // The only assignment operator provided is for transferring from an
     138             :   // nsReturnRef smart reference, which expects to pass its ownership to
     139             :   // another object.
     140             :   //
     141             :   // With raw references and other smart references, the type of the lhs and
     142             :   // its taking and releasing nature is often not obvious from an assignment
     143             :   // statement.  Assignment from a raw ptr especially is not normally
     144             :   // expected to release the reference.
     145             :   //
     146             :   // Use |steal| for taking ownership from other smart refs.
     147             :   //
     148             :   // For raw references, use |own| to indicate intention to have the
     149             :   // resource released.
     150             :   //
     151             :   // Or, to create another owner of the same reference, use an nsCountedRef.
     152             : 
     153           0 :   ThisClass& operator=(const nsReturningRef<T>& aReturning)
     154             :   {
     155           0 :     BaseClass::steal(aReturning.mReturnRef);
     156           0 :     return *this;
     157             :   }
     158             : 
     159             :   // Conversion to a raw reference allow the nsAutoRef<T> to often be used
     160             :   // like a raw reference.
     161        1135 :   operator typename SimpleRef::RawRef() const
     162             :   {
     163        1135 :     return this->get();
     164             :   }
     165             : 
     166             :   // Transfer ownership from another smart reference.
     167           0 :   void steal(ThisClass& aOtherRef)
     168             :   {
     169           0 :     BaseClass::steal(aOtherRef);
     170           0 :   }
     171             : 
     172             :   // Assume ownership of a raw ref.
     173             :   //
     174             :   // |own| has similar function to |steal|, and is useful for receiving
     175             :   // ownership from a return value of a function.  It is named differently
     176             :   // because |own| requires more care to ensure that the function intends to
     177             :   // give away ownership, and so that |steal| can be safely used, knowing
     178             :   // that it won't steal ownership from any methods returning raw ptrs to
     179             :   // data owned by a foreign object.
     180        3402 :   void own(RawRefOnly aRefToRelease)
     181             :   {
     182        3402 :     BaseClass::own(aRefToRelease);
     183        3402 :   }
     184             : 
     185             :   // Exchange ownership with |aOther|
     186             :   void swap(ThisClass& aOther)
     187             :   {
     188             :     LocalSimpleRef temp;
     189             :     temp.SimpleRef::operator=(*this);
     190             :     SimpleRef::operator=(aOther);
     191             :     aOther.SimpleRef::operator=(temp);
     192             :   }
     193             : 
     194             :   // Release the reference now.
     195           0 :   void reset()
     196             :   {
     197           0 :     this->SafeRelease();
     198           0 :     LocalSimpleRef empty;
     199           0 :     SimpleRef::operator=(empty);
     200           0 :   }
     201             : 
     202             :   // Pass out the reference for a function return values.
     203           0 :   nsReturnRef<T> out()
     204             :   {
     205           0 :     return nsReturnRef<T>(this->disown());
     206             :   }
     207             : 
     208             :   // operator->() and disown() are provided by nsAutoRefBase<T>.
     209             :   // The default nsSimpleRef<T> provides get().
     210             : 
     211             : private:
     212             :   // No copy constructor
     213             :   explicit nsAutoRef(ThisClass& aRefToSteal);
     214             : };
     215             : 
     216             : /**
     217             :  * template <class T> class nsCountedRef
     218             :  *
     219             :  * A class that creates (adds) a new reference to a resource on construction
     220             :  * or assignment and releases on destruction.
     221             :  *
     222             :  * This class is similar to nsAutoRef<T> and inherits its methods, but also
     223             :  * provides copy construction and assignment operators that enable more than
     224             :  * one concurrent reference to the same resource.
     225             :  *
     226             :  * Specialize |nsAutoRefTraits<T>| or |nsSimpleRef<T>| to use this.  This
     227             :  * class assumes that the resource itself counts references and so can only be
     228             :  * used when |T| represents a reference-counting resource.
     229             :  */
     230             : 
     231             : template <class T>
     232        1805 : class nsCountedRef : public nsAutoRef<T>
     233             : {
     234             : protected:
     235             :   typedef nsCountedRef<T> ThisClass;
     236             :   typedef nsAutoRef<T> BaseClass;
     237             :   typedef nsSimpleRef<T> SimpleRef;
     238             :   typedef typename BaseClass::RawRef RawRef;
     239             : 
     240             : public:
     241        2614 :   nsCountedRef()
     242        2614 :   {
     243        2614 :   }
     244             : 
     245             :   // Construction and assignment from a another nsCountedRef
     246             :   // or a raw ref copies and increments the ref count.
     247        1698 :   nsCountedRef(const ThisClass& aRefToCopy)
     248        1698 :   {
     249        1698 :     SimpleRef::operator=(aRefToCopy);
     250        1698 :     SafeAddRef();
     251        1698 :   }
     252           0 :   ThisClass& operator=(const ThisClass& aRefToCopy)
     253             :   {
     254           0 :     if (this == &aRefToCopy) {
     255           0 :       return *this;
     256             :     }
     257             : 
     258           0 :     this->SafeRelease();
     259           0 :     SimpleRef::operator=(aRefToCopy);
     260           0 :     SafeAddRef();
     261           0 :     return *this;
     262             :   }
     263             : 
     264             :   // Implicit conversion from another smart ref argument (to a raw ref) is
     265             :   // accepted here because construction and assignment safely creates a new
     266             :   // reference without interfering with the reference to copy.
     267        1816 :   explicit nsCountedRef(RawRef aRefToCopy)
     268        1816 :     : BaseClass(aRefToCopy)
     269             :   {
     270        1816 :     SafeAddRef();
     271        1816 :   }
     272        3402 :   ThisClass& operator=(RawRef aRefToCopy)
     273             :   {
     274        3402 :     this->own(aRefToCopy);
     275        3402 :     SafeAddRef();
     276        3402 :     return *this;
     277             :   }
     278             : 
     279             :   // Construction and assignment from an nsReturnRef function return value,
     280             :   // which expects to give up ownership, transfers ownership.
     281             :   explicit nsCountedRef(const nsReturningRef<T>& aReturning)
     282             :     : BaseClass(aReturning)
     283             :   {
     284             :   }
     285             :   ThisClass& operator=(const nsReturningRef<T>& aReturning)
     286             :   {
     287             :     BaseClass::operator=(aReturning);
     288             :     return *this;
     289             :   }
     290             : 
     291             : protected:
     292             :   // Increase the reference count if there is a resource.
     293        6916 :   void SafeAddRef()
     294             :   {
     295        6916 :     if (this->HaveResource()) {
     296        6913 :       this->AddRef(this->get());
     297             :     }
     298        6916 :   }
     299             : };
     300             : 
     301             : /**
     302             :  * template <class T> class nsReturnRef
     303             :  *
     304             :  * A type for function return values that hold a reference to a resource that
     305             :  * must be released.  See also |nsAutoRef<T>::out()|.
     306             :  */
     307             : 
     308             : template <class T>
     309           0 : class nsReturnRef : public nsAutoRefBase<T>
     310             : {
     311             : protected:
     312             :   typedef nsAutoRefBase<T> BaseClass;
     313             :   typedef typename BaseClass::RawRefOnly RawRefOnly;
     314             : 
     315             : public:
     316             :   // For constructing a return value with no resource
     317           0 :   nsReturnRef()
     318           0 :   {
     319           0 :   }
     320             : 
     321             :   // For returning a smart reference from a raw reference that must be
     322             :   // released.  Explicit construction is required so as not to risk
     323             :   // unintentionally releasing the resource associated with a raw ref.
     324           0 :   MOZ_IMPLICIT nsReturnRef(RawRefOnly aRefToRelease)
     325           0 :     : BaseClass(aRefToRelease)
     326             :   {
     327           0 :   }
     328             : 
     329             :   // Copy construction transfers ownership
     330             :   nsReturnRef(nsReturnRef<T>& aRefToSteal)
     331             :     : BaseClass(aRefToSteal)
     332             :   {
     333             :   }
     334             : 
     335           0 :   MOZ_IMPLICIT nsReturnRef(const nsReturningRef<T>& aReturning)
     336           0 :     : BaseClass(aReturning)
     337             :   {
     338           0 :   }
     339             : 
     340             :   // Conversion to a temporary (const) object referring to this object so
     341             :   // that the reference may be passed from a function return value
     342             :   // (temporary) to another smart reference.  There is no need to use this
     343             :   // explicitly.  Simply assign a nsReturnRef<T> function return value to a
     344             :   // smart reference.
     345           0 :   operator nsReturningRef<T>()
     346             :   {
     347           0 :     return nsReturningRef<T>(*this);
     348             :   }
     349             : 
     350             :   // No conversion to RawRef operator is provided on nsReturnRef, to ensure
     351             :   // that the return value is not carelessly assigned to a raw ptr (and the
     352             :   // resource then released).  If passing to a function that takes a raw
     353             :   // ptr, use get or disown as appropriate.
     354             : };
     355             : 
     356             : /**
     357             :  * template <class T> class nsReturningRef
     358             :  *
     359             :  * A class to allow ownership to be transferred from nsReturnRef function
     360             :  * return values.
     361             :  *
     362             :  * It should not be necessary for clients to reference this
     363             :  * class directly.  Simply pass an nsReturnRef<T> to a parameter taking an
     364             :  * |nsReturningRef<T>|.
     365             :  *
     366             :  * The conversion operator on nsReturnRef constructs a temporary wrapper of
     367             :  * class nsReturningRef<T> around a non-const reference to the nsReturnRef.
     368             :  * The wrapper can then be passed as an rvalue parameter.
     369             :  */
     370             : 
     371             : template <class T>
     372             : class nsReturningRef
     373             : {
     374             : private:
     375             :   friend class nsReturnRef<T>;
     376             : 
     377           0 :   explicit nsReturningRef(nsReturnRef<T>& aReturnRef)
     378           0 :     : mReturnRef(aReturnRef)
     379             :   {
     380           0 :   }
     381             : public:
     382             :   nsReturnRef<T>& mReturnRef;
     383             : };
     384             : 
     385             : /**
     386             :  * template <class T> class nsAutoRefTraits
     387             :  *
     388             :  * A class describing traits of references managed by the default
     389             :  * |nsSimpleRef<T>| implementation and thus |nsAutoRef<T>| and |nsCountedRef|.
     390             :  * The default |nsSimpleRef<T> is suitable for resources with handles that
     391             :  * have a void value.  (If there is no such void value for a handle,
     392             :  * specialize |nsSimpleRef<T>|.)
     393             :  *
     394             :  * Specializations must be provided for each class |T| according to the
     395             :  * following pattern:
     396             :  *
     397             :  * // The template parameter |T| should be a class such that the set of fields
     398             :  * // in class nsAutoRefTraits<T> is unique for class |T|.  Usually the
     399             :  * // resource object class is sufficient.  For handles that are simple
     400             :  * // integral typedefs, a new unique possibly-incomplete class may need to be
     401             :  * // declared.
     402             :  *
     403             :  * template <>
     404             :  * class nsAutoRefTraits<T>
     405             :  * {
     406             :  *     // Specializations must provide a typedef for RawRef, describing the
     407             :  *     // type of the handle to the resource.
     408             :  *     typedef <handle-type> RawRef;
     409             :  *
     410             :  *     // Specializations should define Void(), a function returning a value
     411             :  *     // suitable for a handle that does not have an associated resource.
     412             :  *     //
     413             :  *     // The return type must be a suitable as the parameter to a RawRef
     414             :  *     // constructor and operator==.
     415             :  *     //
     416             :  *     // If this method is not accessible then some limited nsAutoRef
     417             :  *     // functionality will still be available, but the default constructor,
     418             :  *     // |reset|, and most transfer of ownership methods will not be available.
     419             :  *     static <return-type> Void();
     420             :  *
     421             :  *     // Specializations must define Release() to properly finalize the
     422             :  *     // handle to a non-void custom-deleted or reference-counted resource.
     423             :  *     static void Release(RawRef aRawRef);
     424             :  *
     425             :  *     // For reference-counted resources, if |nsCountedRef<T>| is to be used,
     426             :  *     // specializations must define AddRef to increment the reference count
     427             :  *     // held by a non-void handle.
     428             :  *     // (AddRef() is not necessary for |nsAutoRef<T>|.)
     429             :  *     static void AddRef(RawRef aRawRef);
     430             :  * };
     431             :  *
     432             :  * See nsPointerRefTraits for example specializations for simple pointer
     433             :  * references.  See nsAutoRef for an example specialization for a non-pointer
     434             :  * reference.
     435             :  */
     436             : 
     437             : template <class T> class nsAutoRefTraits;
     438             : 
     439             : /**
     440             :  * template <class T> class nsPointerRefTraits
     441             :  *
     442             :  * A convenience class useful as a base class for specializations of
     443             :  * |nsAutoRefTraits<T>| where the handle to the resource is a pointer to |T|.
     444             :  * By inheriting from this class, definitions of only Release(RawRef) and
     445             :  * possibly AddRef(RawRef) need to be added.
     446             :  *
     447             :  * Examples of use:
     448             :  *
     449             :  * template <>
     450             :  * class nsAutoRefTraits<PRFileDesc> : public nsPointerRefTraits<PRFileDesc>
     451             :  * {
     452             :  * public:
     453             :  *     static void Release(PRFileDesc *ptr) { PR_Close(ptr); }
     454             :  * };
     455             :  *
     456             :  * template <>
     457             :  * class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern>
     458             :  * {
     459             :  * public:
     460             :  *     static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); }
     461             :  *     static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); }
     462             :  * };
     463             :  */
     464             : 
     465             : template <class T>
     466        9558 : class nsPointerRefTraits
     467             : {
     468             : public:
     469             :   // The handle is a pointer to T.
     470             :   typedef T* RawRef;
     471             :   // A nullptr does not have a resource.
     472       16463 :   static RawRef Void()
     473             :   {
     474       16463 :     return nullptr;
     475             :   }
     476             : };
     477             : 
     478             : /**
     479             :  * template <class T> class nsSimpleRef
     480             :  *
     481             :  * Constructs a non-smart reference, and provides methods to test whether
     482             :  * there is an associated resource and (if so) get its raw handle.
     483             :  *
     484             :  * A default implementation is suitable for resources with handles that have a
     485             :  * void value.  This is not intended for direct use but used by |nsAutoRef<T>|
     486             :  * and thus |nsCountedRef<T>|.
     487             :  *
     488             :  * Specialize this class if there is no particular void value for the resource
     489             :  * handle.  A specialized implementation must also provide Release(RawRef),
     490             :  * and, if |nsCountedRef<T>| is required, AddRef(RawRef), as described in
     491             :  * nsAutoRefTraits<T>.
     492             :  */
     493             : 
     494             : template <class T>
     495           0 : class nsSimpleRef : protected nsAutoRefTraits<T>
     496             : {
     497             : protected:
     498             :   // The default implementation uses nsAutoRefTrait<T>.
     499             :   // Specializations need not define this typedef.
     500             :   typedef nsAutoRefTraits<T> Traits;
     501             :   // The type of the handle to the resource.
     502             :   // A specialization must provide a typedef for RawRef.
     503             :   typedef typename Traits::RawRef RawRef;
     504             : 
     505             :   // Construct with no resource.
     506             :   //
     507             :   // If this constructor is not accessible then some limited nsAutoRef
     508             :   // functionality will still be available, but the default constructor,
     509             :   // |reset|, and most transfer of ownership methods will not be available.
     510        4312 :   nsSimpleRef()
     511        4312 :     : mRawRef(Traits::Void())
     512             :   {
     513        4312 :   }
     514             :   // Construct with a handle to a resource.
     515             :   // A specialization must provide this.
     516        5246 :   explicit nsSimpleRef(RawRef aRawRef)
     517        5246 :     : mRawRef(aRawRef)
     518             :   {
     519        5246 :   }
     520             : 
     521             :   // Test whether there is an associated resource.  A specialization must
     522             :   // provide this.  The function is permitted to always return true if the
     523             :   // default constructor is not accessible, or if Release (and AddRef) can
     524             :   // deal with void handles.
     525       12151 :   bool HaveResource() const
     526             :   {
     527       12151 :     return mRawRef != Traits::Void();
     528             :   }
     529             : 
     530             : public:
     531             :   // A specialization must provide get() or loose some functionality.  This
     532             :   // is inherited by derived classes and the specialization may choose
     533             :   // whether it is public or protected.
     534       10798 :   RawRef get() const
     535             :   {
     536       10798 :     return mRawRef;
     537             :   }
     538             : 
     539             : private:
     540             :   RawRef mRawRef;
     541             : };
     542             : 
     543             : 
     544             : /**
     545             :  * template <class T> class nsAutoRefBase
     546             :  *
     547             :  * Internal base class for |nsAutoRef<T>| and |nsReturnRef<T>|.
     548             :  * Adds release on destruction to a |nsSimpleRef<T>|.
     549             :  */
     550             : 
     551             : template <class T>
     552             : class nsAutoRefBase : public nsSimpleRef<T>
     553             : {
     554             : protected:
     555             :   typedef nsAutoRefBase<T> ThisClass;
     556             :   typedef nsSimpleRef<T> SimpleRef;
     557             :   typedef typename SimpleRef::RawRef RawRef;
     558             : 
     559        4312 :   nsAutoRefBase()
     560        4312 :   {
     561        4312 :   }
     562             : 
     563             :   // A type for parameters that should be passed a raw ref but should not
     564             :   // accept implicit conversions (from another smart ref).  (The only
     565             :   // conversion to this type is from a raw ref so only raw refs will be
     566             :   // accepted.)
     567             :   class RawRefOnly
     568             :   {
     569             :   public:
     570        5246 :     MOZ_IMPLICIT RawRefOnly(RawRef aRawRef)
     571        5246 :       : mRawRef(aRawRef)
     572             :     {
     573        5246 :     }
     574        5246 :     operator RawRef() const
     575             :     {
     576        5246 :       return mRawRef;
     577             :     }
     578             :   private:
     579             :     RawRef mRawRef;
     580             :   };
     581             : 
     582             :   // Construction from a raw ref assumes ownership
     583        1844 :   explicit nsAutoRefBase(RawRefOnly aRefToRelease)
     584        1844 :     : SimpleRef(aRefToRelease)
     585             :   {
     586        1844 :   }
     587             : 
     588             :   // Constructors that steal ownership
     589             :   explicit nsAutoRefBase(ThisClass& aRefToSteal)
     590             :     : SimpleRef(aRefToSteal.disown())
     591             :   {
     592             :   }
     593           0 :   explicit nsAutoRefBase(const nsReturningRef<T>& aReturning)
     594           0 :     : SimpleRef(aReturning.mReturnRef.disown())
     595             :   {
     596           0 :   }
     597             : 
     598        1833 :   ~nsAutoRefBase()
     599             :   {
     600        1833 :     SafeRelease();
     601        1833 :   }
     602             : 
     603             :   // An internal class providing access to protected nsSimpleRef<T>
     604             :   // constructors for construction of temporary simple references (that are
     605             :   // not ThisClass).
     606             :   class LocalSimpleRef : public SimpleRef
     607             :   {
     608             :   public:
     609           0 :     LocalSimpleRef()
     610           0 :     {
     611           0 :     }
     612        3402 :     explicit LocalSimpleRef(RawRef aRawRef)
     613        3402 :       : SimpleRef(aRawRef)
     614             :     {
     615        3402 :     }
     616             :   };
     617             : 
     618             : private:
     619             :   ThisClass& operator=(const ThisClass& aSmartRef) = delete;
     620             : 
     621             : public:
     622         128 :   RawRef operator->() const
     623             :   {
     624         128 :     return this->get();
     625             :   }
     626             : 
     627             :   // Transfer ownership to a raw reference.
     628             :   //
     629             :   // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED.
     630             :   //
     631             :   // Is this really what you want to use?  Using this removes any guarantee
     632             :   // of release.  Use nsAutoRef<T>::out() for return values, or an
     633             :   // nsAutoRef<T> modifiable lvalue for an out parameter.  Use disown() when
     634             :   // the reference must be stored in a POD type object, such as may be
     635             :   // preferred for a namespace-scope object with static storage duration,
     636             :   // for example.
     637           0 :   RawRef disown()
     638             :   {
     639           0 :     RawRef temp = this->get();
     640           0 :     LocalSimpleRef empty;
     641           0 :     SimpleRef::operator=(empty);
     642           0 :     return temp;
     643             :   }
     644             : 
     645             : protected:
     646             :   // steal and own are protected because they make no sense on nsReturnRef,
     647             :   // but steal is implemented on this class for access to aOtherRef.disown()
     648             :   // when aOtherRef is an nsReturnRef;
     649             : 
     650             :   // Transfer ownership from another smart reference.
     651           0 :   void steal(ThisClass& aOtherRef)
     652             :   {
     653           0 :     own(aOtherRef.disown());
     654           0 :   }
     655             :   // Assume ownership of a raw ref.
     656        3402 :   void own(RawRefOnly aRefToRelease)
     657             :   {
     658        3402 :     SafeRelease();
     659        3402 :     LocalSimpleRef ref(aRefToRelease);
     660        3402 :     SimpleRef::operator=(ref);
     661        3402 :   }
     662             : 
     663             :   // Release a resource if there is one.
     664        5235 :   void SafeRelease()
     665             :   {
     666        5235 :     if (this->HaveResource()) {
     667        2622 :       this->Release(this->get());
     668             :     }
     669        5235 :   }
     670             : };
     671             : 
     672             : #endif // !defined(nsAutoRef_h_)

Generated by: LCOV version 1.13