LCOV - code coverage report
Current view: directory - objdir/dist/include - nsAutoRef.h (source / functions) Found Hit Coverage
Test: app.info Lines: 118 37 31.4 %
Date: 2012-06-02 Functions: 215 15 7.0 %

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

Generated by: LCOV version 1.7