LCOV - code coverage report
Current view: directory - objdir/dist/include - nsAutoPtr.h (source / functions) Found Hit Coverage
Test: app.info Lines: 267 251 94.0 %
Date: 2012-06-02 Functions: 8854 2691 30.4 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Scott Collins <scc@mozilla.org> (original author of nsCOMPtr)
      24                 :  *   L. David Baron <dbaron@dbaron.org>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or 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 nsAutoPtr_h___
      41                 : #define nsAutoPtr_h___
      42                 : 
      43                 :   // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
      44                 : #ifndef nsCOMPtr_h___
      45                 :   // For |already_AddRefed|, |NSCAP_Zero|,
      46                 :   // |NSCAP_DONT_PROVIDE_NONCONST_OPEQ|,
      47                 :   // |NSCAP_FEATURE_INLINE_STARTASSIGNMENT|
      48                 : #include "nsCOMPtr.h"
      49                 : #endif
      50                 : 
      51                 : /*****************************************************************************/
      52                 : 
      53                 : // template <class T> class nsAutoPtrGetterTransfers;
      54                 : 
      55                 : template <class T>
      56                 : class nsAutoPtr
      57                 :   {
      58                 :     private:
      59                 :       void**
      60             323 :       begin_assignment()
      61                 :         {
      62             323 :           assign(0);
      63             323 :           return reinterpret_cast<void**>(&mRawPtr);
      64                 :         }
      65                 : 
      66                 :       void
      67          398300 :       assign( T* newPtr )
      68                 :         {
      69          398300 :           NS_ABORT_IF_FALSE(mRawPtr != newPtr || !newPtr, "This makes no sense!");
      70          398300 :           T* oldPtr = mRawPtr;
      71          398300 :           mRawPtr = newPtr;
      72          398295 :           delete oldPtr;
      73          398300 :         }
      74                 : 
      75                 :       // |class Ptr| helps us prevent implicit "copy construction"
      76                 :       // through |operator T*() const| from a |const nsAutoPtr<T>|
      77                 :       // because two implicit conversions in a row aren't allowed.
      78                 :       // It still allows assignment from T* through implicit conversion
      79                 :       // from |T*| to |nsAutoPtr<T>::Ptr|
      80                 :       class Ptr
      81                 :         {
      82                 :           public:
      83         1970739 :             Ptr( T* aPtr )
      84         1970739 :                   : mPtr(aPtr)
      85                 :               {
      86         1970739 :               }
      87                 : 
      88         1970743 :             operator T*() const
      89                 :               {
      90         1970743 :                 return mPtr;
      91                 :               }
      92                 : 
      93                 :           private:
      94                 :             T* mPtr;
      95                 :         };
      96                 : 
      97                 :     private:
      98                 :       T* mRawPtr;
      99                 : 
     100                 :     public:
     101                 :       typedef T element_type;
     102                 :       
     103         2468607 :      ~nsAutoPtr()
     104                 :         {
     105         2468607 :           delete mRawPtr;
     106         2468607 :         }
     107                 : 
     108                 :         // Constructors
     109                 : 
     110          498342 :       nsAutoPtr()
     111          498342 :             : mRawPtr(0)
     112                 :           // default constructor
     113                 :         {
     114          498342 :         }
     115                 : 
     116         1970744 :       nsAutoPtr( Ptr aRawPtr )
     117         1970744 :             : mRawPtr(aRawPtr)
     118                 :           // construct from a raw pointer (of the right type)
     119                 :         {
     120         1970745 :         }
     121                 : 
     122              46 :       nsAutoPtr( nsAutoPtr<T>& aSmartPtr )
     123              46 :             : mRawPtr( aSmartPtr.forget() )
     124                 :           // Construct by transferring ownership from another smart pointer.
     125                 :         {
     126              46 :         }
     127                 : 
     128                 : 
     129                 :         // Assignment operators
     130                 : 
     131                 :       nsAutoPtr<T>&
     132          385088 :       operator=( T* rhs )
     133                 :           // assign from a raw pointer (of the right type)
     134                 :         {
     135          385088 :           assign(rhs);
     136          385088 :           return *this;
     137                 :         }
     138                 : 
     139           12889 :       nsAutoPtr<T>& operator=( nsAutoPtr<T>& rhs )
     140                 :           // assign by transferring ownership from another smart pointer.
     141                 :         {
     142           12889 :           assign(rhs.forget());
     143           12889 :           return *this;
     144                 :         }
     145                 : 
     146                 :         // Other pointer operators
     147                 : 
     148                 :       T*
     149         3194962 :       get() const
     150                 :           /*
     151                 :             Prefer the implicit conversion provided automatically by
     152                 :             |operator T*() const|.  Use |get()| _only_ to resolve
     153                 :             ambiguity.
     154                 :           */
     155                 :         {
     156         3194962 :           return mRawPtr;
     157                 :         }
     158                 : 
     159         2752745 :       operator T*() const
     160                 :           /*
     161                 :             ...makes an |nsAutoPtr| act like its underlying raw pointer
     162                 :             type  whenever it is used in a context where a raw pointer
     163                 :             is expected.  It is this operator that makes an |nsAutoPtr|
     164                 :             substitutable for a raw pointer.
     165                 : 
     166                 :             Prefer the implicit use of this operator to calling |get()|,
     167                 :             except where necessary to resolve ambiguity.
     168                 :           */
     169                 :         {
     170         2752745 :           return get();
     171                 :         }
     172                 : 
     173                 :       T*
     174           32807 :       forget()
     175                 :         {
     176           32807 :           T* temp = mRawPtr;
     177           32807 :           mRawPtr = 0;
     178           32807 :           return temp;
     179                 :         }
     180                 : 
     181                 :       T*
     182          391720 :       operator->() const
     183                 :         {
     184          391720 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->().");
     185          391720 :           return get();
     186                 :         }
     187                 : 
     188                 :       // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
     189                 :       // causes internal compiler errors for some MSVC versions.  (It's not
     190                 :       // clear to me whether it should be needed.)
     191                 : #ifndef _MSC_VER
     192                 :       template <class U, class V>
     193                 :       U&
     194               0 :       operator->*(U V::* aMember)
     195                 :         {
     196               0 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->*().");
     197               0 :           return get()->*aMember;
     198                 :         }
     199                 : #endif
     200                 : 
     201                 :       nsAutoPtr<T>*
     202                 :       get_address()
     203                 :           // This is not intended to be used by clients.  See |address_of|
     204                 :           // below.
     205                 :         {
     206                 :           return this;
     207                 :         }
     208                 : 
     209                 :       const nsAutoPtr<T>*
     210                 :       get_address() const
     211                 :           // This is not intended to be used by clients.  See |address_of|
     212                 :           // below.
     213                 :         {
     214                 :           return this;
     215                 :         }
     216                 : 
     217                 :     public:
     218                 :       T&
     219           50219 :       operator*() const
     220                 :         {
     221           50219 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator*().");
     222           50219 :           return *get();
     223                 :         }
     224                 : 
     225                 :       T**
     226             323 :       StartAssignment()
     227                 :         {
     228                 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
     229             323 :           return reinterpret_cast<T**>(begin_assignment());
     230                 : #else
     231                 :           assign(0);
     232                 :           return reinterpret_cast<T**>(&mRawPtr);
     233                 : #endif
     234                 :         }
     235                 :   };
     236                 : 
     237                 : template <class T>
     238                 : inline
     239                 : nsAutoPtr<T>*
     240                 : address_of( nsAutoPtr<T>& aPtr )
     241                 :   {
     242                 :     return aPtr.get_address();
     243                 :   }
     244                 : 
     245                 : template <class T>
     246                 : inline
     247                 : const nsAutoPtr<T>*
     248                 : address_of( const nsAutoPtr<T>& aPtr )
     249                 :   {
     250                 :     return aPtr.get_address();
     251                 :   }
     252                 : 
     253                 : template <class T>
     254                 : class nsAutoPtrGetterTransfers
     255                 :     /*
     256                 :       ...
     257                 : 
     258                 :       This class is designed to be used for anonymous temporary objects in the
     259                 :       argument list of calls that return COM interface pointers, e.g.,
     260                 : 
     261                 :         nsAutoPtr<IFoo> fooP;
     262                 :         ...->GetTransferedPointer(getter_Transfers(fooP))
     263                 : 
     264                 :       DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
     265                 : 
     266                 :       When initialized with a |nsAutoPtr|, as in the example above, it returns
     267                 :       a |void**|, a |T**|, or an |nsISupports**| as needed, that the
     268                 :       outer call (|GetTransferedPointer| in this case) can fill in.
     269                 : 
     270                 :       This type should be a nested class inside |nsAutoPtr<T>|.
     271                 :     */
     272                 :   {
     273                 :     public:
     274                 :       explicit
     275             323 :       nsAutoPtrGetterTransfers( nsAutoPtr<T>& aSmartPtr )
     276             323 :           : mTargetSmartPtr(aSmartPtr)
     277                 :         {
     278                 :           // nothing else to do
     279             323 :         }
     280                 : 
     281               0 :       operator void**()
     282                 :         {
     283               0 :           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
     284                 :         }
     285                 : 
     286             323 :       operator T**()
     287                 :         {
     288             323 :           return mTargetSmartPtr.StartAssignment();
     289                 :         }
     290                 : 
     291                 :       T*&
     292               0 :       operator*()
     293                 :         {
     294               0 :           return *(mTargetSmartPtr.StartAssignment());
     295                 :         }
     296                 : 
     297                 :     private:
     298                 :       nsAutoPtr<T>& mTargetSmartPtr;
     299                 :   };
     300                 : 
     301                 : template <class T>
     302                 : inline
     303                 : nsAutoPtrGetterTransfers<T>
     304             323 : getter_Transfers( nsAutoPtr<T>& aSmartPtr )
     305                 :     /*
     306                 :       Used around a |nsAutoPtr| when 
     307                 :       ...makes the class |nsAutoPtrGetterTransfers<T>| invisible.
     308                 :     */
     309                 :   {
     310             323 :     return nsAutoPtrGetterTransfers<T>(aSmartPtr);
     311                 :   }
     312                 : 
     313                 : 
     314                 : 
     315                 :   // Comparing two |nsAutoPtr|s
     316                 : 
     317                 : template <class T, class U>
     318                 : inline
     319                 : bool
     320               0 : operator==( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
     321                 :   {
     322               0 :     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
     323                 :   }
     324                 : 
     325                 : 
     326                 : template <class T, class U>
     327                 : inline
     328                 : bool
     329                 : operator!=( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
     330                 :   {
     331                 :     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
     332                 :   }
     333                 : 
     334                 : 
     335                 :   // Comparing an |nsAutoPtr| to a raw pointer
     336                 : 
     337                 : template <class T, class U>
     338                 : inline
     339                 : bool
     340                 : operator==( const nsAutoPtr<T>& lhs, const U* rhs )
     341                 :   {
     342                 :     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
     343                 :   }
     344                 : 
     345                 : template <class T, class U>
     346                 : inline
     347                 : bool
     348                 : operator==( const U* lhs, const nsAutoPtr<T>& rhs )
     349                 :   {
     350                 :     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
     351                 :   }
     352                 : 
     353                 : template <class T, class U>
     354                 : inline
     355                 : bool
     356                 : operator!=( const nsAutoPtr<T>& lhs, const U* rhs )
     357                 :   {
     358                 :     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
     359                 :   }
     360                 : 
     361                 : template <class T, class U>
     362                 : inline
     363                 : bool
     364                 : operator!=( const U* lhs, const nsAutoPtr<T>& rhs )
     365                 :   {
     366                 :     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
     367                 :   }
     368                 : 
     369                 :   // To avoid ambiguities caused by the presence of builtin |operator==|s
     370                 :   // creating a situation where one of the |operator==| defined above
     371                 :   // has a better conversion for one argument and the builtin has a
     372                 :   // better conversion for the other argument, define additional
     373                 :   // |operator==| without the |const| on the raw pointer.
     374                 :   // See bug 65664 for details.
     375                 : 
     376                 : #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
     377                 : template <class T, class U>
     378                 : inline
     379                 : bool
     380               2 : operator==( const nsAutoPtr<T>& lhs, U* rhs )
     381                 :   {
     382               2 :     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
     383                 :   }
     384                 : 
     385                 : template <class T, class U>
     386                 : inline
     387                 : bool
     388               2 : operator==( U* lhs, const nsAutoPtr<T>& rhs )
     389                 :   {
     390               2 :     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
     391                 :   }
     392                 : 
     393                 : template <class T, class U>
     394                 : inline
     395                 : bool
     396               2 : operator!=( const nsAutoPtr<T>& lhs, U* rhs )
     397                 :   {
     398               2 :     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
     399                 :   }
     400                 : 
     401                 : template <class T, class U>
     402                 : inline
     403                 : bool
     404               2 : operator!=( U* lhs, const nsAutoPtr<T>& rhs )
     405                 :   {
     406               2 :     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
     407                 :   }
     408                 : #endif
     409                 : 
     410                 : 
     411                 : 
     412                 :   // Comparing an |nsAutoPtr| to |0|
     413                 : 
     414                 : template <class T>
     415                 : inline
     416                 : bool
     417             141 : operator==( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
     418                 :     // specifically to allow |smartPtr == 0|
     419                 :   {
     420             141 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
     421                 :   }
     422                 : 
     423                 : template <class T>
     424                 : inline
     425                 : bool
     426                 : operator==( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
     427                 :     // specifically to allow |0 == smartPtr|
     428                 :   {
     429                 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
     430                 :   }
     431                 : 
     432                 : template <class T>
     433                 : inline
     434                 : bool
     435               0 : operator!=( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
     436                 :     // specifically to allow |smartPtr != 0|
     437                 :   {
     438               0 :     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
     439                 :   }
     440                 : 
     441                 : template <class T>
     442                 : inline
     443                 : bool
     444                 : operator!=( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
     445                 :     // specifically to allow |0 != smartPtr|
     446                 :   {
     447                 :     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
     448                 :   }
     449                 : 
     450                 : 
     451                 : #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
     452                 : 
     453                 :   // We need to explicitly define comparison operators for `int'
     454                 :   // because the compiler is lame.
     455                 : 
     456                 : template <class T>
     457                 : inline
     458                 : bool
     459                 : operator==( const nsAutoPtr<T>& lhs, int rhs )
     460                 :     // specifically to allow |smartPtr == 0|
     461                 :   {
     462                 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
     463                 :   }
     464                 : 
     465                 : template <class T>
     466                 : inline
     467                 : bool
     468                 : operator==( int lhs, const nsAutoPtr<T>& rhs )
     469                 :     // specifically to allow |0 == smartPtr|
     470                 :   {
     471                 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
     472                 :   }
     473                 : 
     474                 : #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
     475                 : 
     476                 : /*****************************************************************************/
     477                 : 
     478                 : // template <class T> class nsAutoArrayPtrGetterTransfers;
     479                 : 
     480                 : template <class T>
     481                 : class nsAutoArrayPtr
     482                 :   {
     483                 :     private:
     484                 :       void**
     485           15475 :       begin_assignment()
     486                 :         {
     487           15475 :           assign(0);
     488           15475 :           return reinterpret_cast<void**>(&mRawPtr);
     489                 :         }
     490                 : 
     491                 :       void
     492          357261 :       assign( T* newPtr )
     493                 :         {
     494          357261 :           T* oldPtr = mRawPtr;
     495          357261 :           mRawPtr = newPtr;
     496          357261 :           delete [] oldPtr;
     497          357261 :         }
     498                 : 
     499                 :     private:
     500                 :       T* mRawPtr;
     501                 : 
     502                 :     public:
     503                 :       typedef T element_type;
     504                 :       
     505          548053 :      ~nsAutoArrayPtr()
     506                 :         {
     507          548053 :           delete [] mRawPtr;
     508          548053 :         }
     509                 : 
     510                 :         // Constructors
     511                 : 
     512          334544 :       nsAutoArrayPtr()
     513          334544 :             : mRawPtr(0)
     514                 :           // default constructor
     515                 :         {
     516          334544 :         }
     517                 : 
     518          213509 :       nsAutoArrayPtr( T* aRawPtr )
     519          213509 :             : mRawPtr(aRawPtr)
     520                 :           // construct from a raw pointer (of the right type)
     521                 :         {
     522          213509 :         }
     523                 : 
     524                 :       nsAutoArrayPtr( nsAutoArrayPtr<T>& aSmartPtr )
     525                 :             : mRawPtr( aSmartPtr.forget() )
     526                 :           // Construct by transferring ownership from another smart pointer.
     527                 :         {
     528                 :         }
     529                 : 
     530                 : 
     531                 :         // Assignment operators
     532                 : 
     533                 :       nsAutoArrayPtr<T>&
     534          341786 :       operator=( T* rhs )
     535                 :           // assign from a raw pointer (of the right type)
     536                 :         {
     537          341786 :           assign(rhs);
     538          341786 :           return *this;
     539                 :         }
     540                 : 
     541               0 :       nsAutoArrayPtr<T>& operator=( nsAutoArrayPtr<T>& rhs )
     542                 :           // assign by transferring ownership from another smart pointer.
     543                 :         {
     544               0 :           assign(rhs.forget());
     545               0 :           return *this;
     546                 :         }
     547                 : 
     548                 :         // Other pointer operators
     549                 : 
     550                 :       T*
     551         1701051 :       get() const
     552                 :           /*
     553                 :             Prefer the implicit conversion provided automatically by
     554                 :             |operator T*() const|.  Use |get()| _only_ to resolve
     555                 :             ambiguity.
     556                 :           */
     557                 :         {
     558         1701051 :           return mRawPtr;
     559                 :         }
     560                 : 
     561          980061 :       operator T*() const
     562                 :           /*
     563                 :             ...makes an |nsAutoArrayPtr| act like its underlying raw pointer
     564                 :             type  whenever it is used in a context where a raw pointer
     565                 :             is expected.  It is this operator that makes an |nsAutoArrayPtr|
     566                 :             substitutable for a raw pointer.
     567                 : 
     568                 :             Prefer the implicit use of this operator to calling |get()|,
     569                 :             except where necessary to resolve ambiguity.
     570                 :           */
     571                 :         {
     572          980061 :           return get();
     573                 :         }
     574                 : 
     575                 :       T*
     576           15400 :       forget()
     577                 :         {
     578           15400 :           T* temp = mRawPtr;
     579           15400 :           mRawPtr = 0;
     580           15400 :           return temp;
     581                 :         }
     582                 : 
     583                 :       T*
     584                 :       operator->() const
     585                 :         {
     586                 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoArrayPtr with operator->().");
     587                 :           return get();
     588                 :         }
     589                 : 
     590                 :       nsAutoArrayPtr<T>*
     591                 :       get_address()
     592                 :           // This is not intended to be used by clients.  See |address_of|
     593                 :           // below.
     594                 :         {
     595                 :           return this;
     596                 :         }
     597                 : 
     598                 :       const nsAutoArrayPtr<T>*
     599                 :       get_address() const
     600                 :           // This is not intended to be used by clients.  See |address_of|
     601                 :           // below.
     602                 :         {
     603                 :           return this;
     604                 :         }
     605                 : 
     606                 :     public:
     607                 :       T&
     608                 :       operator*() const
     609                 :         {
     610                 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoArrayPtr with operator*().");
     611                 :           return *get();
     612                 :         }
     613                 : 
     614                 :       T**
     615           15475 :       StartAssignment()
     616                 :         {
     617                 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
     618           15475 :           return reinterpret_cast<T**>(begin_assignment());
     619                 : #else
     620                 :           assign(0);
     621                 :           return reinterpret_cast<T**>(&mRawPtr);
     622                 : #endif
     623                 :         }
     624                 :   };
     625                 : 
     626                 : template <class T>
     627                 : inline
     628                 : nsAutoArrayPtr<T>*
     629                 : address_of( nsAutoArrayPtr<T>& aPtr )
     630                 :   {
     631                 :     return aPtr.get_address();
     632                 :   }
     633                 : 
     634                 : template <class T>
     635                 : inline
     636                 : const nsAutoArrayPtr<T>*
     637                 : address_of( const nsAutoArrayPtr<T>& aPtr )
     638                 :   {
     639                 :     return aPtr.get_address();
     640                 :   }
     641                 : 
     642                 : template <class T>
     643                 : class nsAutoArrayPtrGetterTransfers
     644                 :     /*
     645                 :       ...
     646                 : 
     647                 :       This class is designed to be used for anonymous temporary objects in the
     648                 :       argument list of calls that return COM interface pointers, e.g.,
     649                 : 
     650                 :         nsAutoArrayPtr<IFoo> fooP;
     651                 :         ...->GetTransferedPointer(getter_Transfers(fooP))
     652                 : 
     653                 :       DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
     654                 : 
     655                 :       When initialized with a |nsAutoArrayPtr|, as in the example above, it returns
     656                 :       a |void**|, a |T**|, or an |nsISupports**| as needed, that the
     657                 :       outer call (|GetTransferedPointer| in this case) can fill in.
     658                 : 
     659                 :       This type should be a nested class inside |nsAutoArrayPtr<T>|.
     660                 :     */
     661                 :   {
     662                 :     public:
     663                 :       explicit
     664           15475 :       nsAutoArrayPtrGetterTransfers( nsAutoArrayPtr<T>& aSmartPtr )
     665           15475 :           : mTargetSmartPtr(aSmartPtr)
     666                 :         {
     667                 :           // nothing else to do
     668           15475 :         }
     669                 : 
     670                 :       operator void**()
     671                 :         {
     672                 :           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
     673                 :         }
     674                 : 
     675           15475 :       operator T**()
     676                 :         {
     677           15475 :           return mTargetSmartPtr.StartAssignment();
     678                 :         }
     679                 : 
     680                 :       T*&
     681                 :       operator*()
     682                 :         {
     683                 :           return *(mTargetSmartPtr.StartAssignment());
     684                 :         }
     685                 : 
     686                 :     private:
     687                 :       nsAutoArrayPtr<T>& mTargetSmartPtr;
     688                 :   };
     689                 : 
     690                 : template <class T>
     691                 : inline
     692                 : nsAutoArrayPtrGetterTransfers<T>
     693           15475 : getter_Transfers( nsAutoArrayPtr<T>& aSmartPtr )
     694                 :     /*
     695                 :       Used around a |nsAutoArrayPtr| when 
     696                 :       ...makes the class |nsAutoArrayPtrGetterTransfers<T>| invisible.
     697                 :     */
     698                 :   {
     699           15475 :     return nsAutoArrayPtrGetterTransfers<T>(aSmartPtr);
     700                 :   }
     701                 : 
     702                 : 
     703                 : 
     704                 :   // Comparing two |nsAutoArrayPtr|s
     705                 : 
     706                 : template <class T, class U>
     707                 : inline
     708                 : bool
     709                 : operator==( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
     710                 :   {
     711                 :     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
     712                 :   }
     713                 : 
     714                 : 
     715                 : template <class T, class U>
     716                 : inline
     717                 : bool
     718                 : operator!=( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
     719                 :   {
     720                 :     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
     721                 :   }
     722                 : 
     723                 : 
     724                 :   // Comparing an |nsAutoArrayPtr| to a raw pointer
     725                 : 
     726                 : template <class T, class U>
     727                 : inline
     728                 : bool
     729                 : operator==( const nsAutoArrayPtr<T>& lhs, const U* rhs )
     730                 :   {
     731                 :     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
     732                 :   }
     733                 : 
     734                 : template <class T, class U>
     735                 : inline
     736                 : bool
     737                 : operator==( const U* lhs, const nsAutoArrayPtr<T>& rhs )
     738                 :   {
     739                 :     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
     740                 :   }
     741                 : 
     742                 : template <class T, class U>
     743                 : inline
     744                 : bool
     745                 : operator!=( const nsAutoArrayPtr<T>& lhs, const U* rhs )
     746                 :   {
     747                 :     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
     748                 :   }
     749                 : 
     750                 : template <class T, class U>
     751                 : inline
     752                 : bool
     753                 : operator!=( const U* lhs, const nsAutoArrayPtr<T>& rhs )
     754                 :   {
     755                 :     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
     756                 :   }
     757                 : 
     758                 :   // To avoid ambiguities caused by the presence of builtin |operator==|s
     759                 :   // creating a situation where one of the |operator==| defined above
     760                 :   // has a better conversion for one argument and the builtin has a
     761                 :   // better conversion for the other argument, define additional
     762                 :   // |operator==| without the |const| on the raw pointer.
     763                 :   // See bug 65664 for details.
     764                 : 
     765                 : #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
     766                 : template <class T, class U>
     767                 : inline
     768                 : bool
     769                 : operator==( const nsAutoArrayPtr<T>& lhs, U* rhs )
     770                 :   {
     771                 :     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
     772                 :   }
     773                 : 
     774                 : template <class T, class U>
     775                 : inline
     776                 : bool
     777                 : operator==( U* lhs, const nsAutoArrayPtr<T>& rhs )
     778                 :   {
     779                 :     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
     780                 :   }
     781                 : 
     782                 : template <class T, class U>
     783                 : inline
     784                 : bool
     785                 : operator!=( const nsAutoArrayPtr<T>& lhs, U* rhs )
     786                 :   {
     787                 :     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
     788                 :   }
     789                 : 
     790                 : template <class T, class U>
     791                 : inline
     792                 : bool
     793                 : operator!=( U* lhs, const nsAutoArrayPtr<T>& rhs )
     794                 :   {
     795                 :     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
     796                 :   }
     797                 : #endif
     798                 : 
     799                 : 
     800                 : 
     801                 :   // Comparing an |nsAutoArrayPtr| to |0|
     802                 : 
     803                 : template <class T>
     804                 : inline
     805                 : bool
     806            8531 : operator==( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
     807                 :     // specifically to allow |smartPtr == 0|
     808                 :   {
     809            8531 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
     810                 :   }
     811                 : 
     812                 : template <class T>
     813                 : inline
     814                 : bool
     815                 : operator==( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
     816                 :     // specifically to allow |0 == smartPtr|
     817                 :   {
     818                 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
     819                 :   }
     820                 : 
     821                 : template <class T>
     822                 : inline
     823                 : bool
     824                 : operator!=( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
     825                 :     // specifically to allow |smartPtr != 0|
     826                 :   {
     827                 :     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
     828                 :   }
     829                 : 
     830                 : template <class T>
     831                 : inline
     832                 : bool
     833                 : operator!=( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
     834                 :     // specifically to allow |0 != smartPtr|
     835                 :   {
     836                 :     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
     837                 :   }
     838                 : 
     839                 : 
     840                 : #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
     841                 : 
     842                 :   // We need to explicitly define comparison operators for `int'
     843                 :   // because the compiler is lame.
     844                 : 
     845                 : template <class T>
     846                 : inline
     847                 : bool
     848                 : operator==( const nsAutoArrayPtr<T>& lhs, int rhs )
     849                 :     // specifically to allow |smartPtr == 0|
     850                 :   {
     851                 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
     852                 :   }
     853                 : 
     854                 : template <class T>
     855                 : inline
     856                 : bool
     857                 : operator==( int lhs, const nsAutoArrayPtr<T>& rhs )
     858                 :     // specifically to allow |0 == smartPtr|
     859                 :   {
     860                 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
     861                 :   }
     862                 : 
     863                 : #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
     864                 : 
     865                 : 
     866                 : /*****************************************************************************/
     867                 : 
     868                 : // template <class T> class nsRefPtrGetterAddRefs;
     869                 : 
     870                 : template <class T>
     871                 : class nsRefPtr
     872                 :   {
     873                 :     private:
     874                 : 
     875                 :       void
     876         7402259 :       assign_with_AddRef( T* rawPtr )
     877                 :         {
     878         7402259 :           if ( rawPtr )
     879         5046801 :             rawPtr->AddRef();
     880         7402259 :           assign_assuming_AddRef(rawPtr);
     881         7402260 :         }
     882                 : 
     883                 :       void**
     884         2141906 :       begin_assignment()
     885                 :         {
     886         2141906 :           assign_assuming_AddRef(0);
     887         2141906 :           return reinterpret_cast<void**>(&mRawPtr);
     888                 :         }
     889                 : 
     890                 :       void
     891         9580466 :       assign_assuming_AddRef( T* newPtr )
     892                 :         {
     893         9580466 :           T* oldPtr = mRawPtr;
     894         9580466 :           mRawPtr = newPtr;
     895         9580466 :           if ( oldPtr )
     896         1463252 :             oldPtr->Release();
     897         9580466 :         }
     898                 : 
     899                 :     private:
     900                 :       T* mRawPtr;
     901                 : 
     902                 :     public:
     903                 :       typedef T element_type;
     904                 :       
     905        10861295 :      ~nsRefPtr()
     906                 :         {
     907        10861295 :           if ( mRawPtr )
     908         4010382 :             mRawPtr->Release();
     909        10861295 :         }
     910                 : 
     911                 :         // Constructors
     912                 : 
     913         9185887 :       nsRefPtr()
     914         9185887 :             : mRawPtr(0)
     915                 :           // default constructor
     916                 :         {
     917         9185887 :         }
     918                 : 
     919          268073 :       nsRefPtr( const nsRefPtr<T>& aSmartPtr )
     920          268073 :             : mRawPtr(aSmartPtr.mRawPtr)
     921                 :           // copy-constructor
     922                 :         {
     923          268073 :           if ( mRawPtr )
     924          263114 :             mRawPtr->AddRef();
     925          268073 :         }
     926                 : 
     927         1299768 :       nsRefPtr( T* aRawPtr )
     928         1299768 :             : mRawPtr(aRawPtr)
     929                 :           // construct from a raw pointer (of the right type)
     930                 :         {
     931         1299768 :           if ( mRawPtr )
     932         1233250 :             mRawPtr->AddRef();
     933         1299769 :         }
     934                 : 
     935                 :       template <typename I>
     936          110197 :       nsRefPtr( const already_AddRefed<I>& aSmartPtr )
     937          110197 :             : mRawPtr(aSmartPtr.mRawPtr)
     938                 :           // construct from |dont_AddRef(expr)|
     939                 :         {
     940          110197 :         }
     941                 : 
     942              72 :       nsRefPtr( const nsCOMPtr_helper& helper )
     943                 :         {
     944                 :           void* newRawPtr;
     945              72 :           if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
     946              62 :             newRawPtr = 0;
     947              72 :           mRawPtr = static_cast<T*>(newRawPtr);
     948              72 :         }
     949                 : 
     950                 :         // Assignment operators
     951                 : 
     952                 :       nsRefPtr<T>&
     953           65362 :       operator=( const nsRefPtr<T>& rhs )
     954                 :           // copy assignment operator
     955                 :         {
     956           65362 :           assign_with_AddRef(rhs.mRawPtr);
     957           65362 :           return *this;
     958                 :         }
     959                 : 
     960                 :       nsRefPtr<T>&
     961         7336897 :       operator=( T* rhs )
     962                 :           // assign from a raw pointer (of the right type)
     963                 :         {
     964         7336897 :           assign_with_AddRef(rhs);
     965         7336898 :           return *this;
     966                 :         }
     967                 : 
     968                 :       template <typename I>
     969                 :       nsRefPtr<T>&
     970           35683 :       operator=( const already_AddRefed<I>& rhs )
     971                 :           // assign from |dont_AddRef(expr)|
     972                 :         {
     973           35683 :           assign_assuming_AddRef(rhs.mRawPtr);
     974           35683 :           return *this;
     975                 :         }
     976                 : 
     977                 :       nsRefPtr<T>&
     978             617 :       operator=( const nsCOMPtr_helper& helper )
     979                 :         {
     980                 :           void* newRawPtr;
     981             617 :           if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
     982              62 :             newRawPtr = 0;
     983             617 :           assign_assuming_AddRef(static_cast<T*>(newRawPtr));
     984             617 :           return *this;
     985                 :         }
     986                 : 
     987                 :         // Other pointer operators
     988                 : 
     989                 :       void
     990            1495 :       swap( nsRefPtr<T>& rhs )
     991                 :           // ...exchange ownership with |rhs|; can save a pair of refcount operations
     992                 :         {
     993            1495 :           T* temp = rhs.mRawPtr;
     994            1495 :           rhs.mRawPtr = mRawPtr;
     995            1495 :           mRawPtr = temp;
     996            1495 :         }
     997                 : 
     998                 :       void
     999         3223787 :       swap( T*& rhs )
    1000                 :           // ...exchange ownership with |rhs|; can save a pair of refcount operations
    1001                 :         {
    1002         3223787 :           T* temp = rhs;
    1003         3223787 :           rhs = mRawPtr;
    1004         3223787 :           mRawPtr = temp;
    1005         3223787 :         }
    1006                 : 
    1007                 :       already_AddRefed<T>
    1008         2895394 :       forget()
    1009                 :           // return the value of mRawPtr and null out mRawPtr. Useful for
    1010                 :           // already_AddRefed return values.
    1011                 :         {
    1012         2895394 :           T* temp = 0;
    1013         2895394 :           swap(temp);
    1014         2895394 :           return temp;
    1015                 :         }
    1016                 : 
    1017                 :       template <typename I>
    1018                 :       void
    1019           60762 :       forget( I** rhs)
    1020                 :           // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
    1021                 :           // Useful to avoid unnecessary AddRef/Release pairs with "out"
    1022                 :           // parameters where rhs bay be a T** or an I** where I is a base class
    1023                 :           // of T.
    1024                 :         {
    1025           60762 :           NS_ASSERTION(rhs, "Null pointer passed to forget!");
    1026           60762 :           *rhs = mRawPtr;
    1027           60762 :           mRawPtr = 0;
    1028           60762 :         }
    1029                 : 
    1030                 :       T*
    1031        41437878 :       get() const
    1032                 :           /*
    1033                 :             Prefer the implicit conversion provided automatically by |operator T*() const|.
    1034                 :             Use |get()| to resolve ambiguity or to get a castable pointer.
    1035                 :           */
    1036                 :         {
    1037        41437878 :           return const_cast<T*>(mRawPtr);
    1038                 :         }
    1039                 : 
    1040        20553827 :       operator T*() const
    1041                 :           /*
    1042                 :             ...makes an |nsRefPtr| act like its underlying raw pointer type whenever it
    1043                 :             is used in a context where a raw pointer is expected.  It is this operator
    1044                 :             that makes an |nsRefPtr| substitutable for a raw pointer.
    1045                 : 
    1046                 :             Prefer the implicit use of this operator to calling |get()|, except where
    1047                 :             necessary to resolve ambiguity.
    1048                 :           */
    1049                 :         {
    1050        20553827 :           return get();
    1051                 :         }
    1052                 : 
    1053                 :       T*
    1054        19527314 :       operator->() const
    1055                 :         {
    1056        19527314 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->().");
    1057        19527314 :           return get();
    1058                 :         }
    1059                 : 
    1060                 :       // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
    1061                 :       // causes internal compiler errors for some MSVC versions.  (It's not
    1062                 :       // clear to me whether it should be needed.)
    1063                 : #ifndef _MSC_VER
    1064                 :       template <class U, class V>
    1065                 :       U&
    1066                 :       operator->*(U V::* aMember)
    1067                 :         {
    1068                 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->*().");
    1069                 :           return get()->*aMember;
    1070                 :         }
    1071                 : #endif
    1072                 : 
    1073                 :       nsRefPtr<T>*
    1074               1 :       get_address()
    1075                 :           // This is not intended to be used by clients.  See |address_of|
    1076                 :           // below.
    1077                 :         {
    1078               1 :           return this;
    1079                 :         }
    1080                 : 
    1081                 :       const nsRefPtr<T>*
    1082                 :       get_address() const
    1083                 :           // This is not intended to be used by clients.  See |address_of|
    1084                 :           // below.
    1085                 :         {
    1086                 :           return this;
    1087                 :         }
    1088                 : 
    1089                 :     public:
    1090                 :       T&
    1091             142 :       operator*() const
    1092                 :         {
    1093             142 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator*().");
    1094             142 :           return *get();
    1095                 :         }
    1096                 : 
    1097                 :       T**
    1098         2141906 :       StartAssignment()
    1099                 :         {
    1100                 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
    1101         2141906 :           return reinterpret_cast<T**>(begin_assignment());
    1102                 : #else
    1103                 :           assign_assuming_AddRef(0);
    1104                 :           return reinterpret_cast<T**>(&mRawPtr);
    1105                 : #endif
    1106                 :         }
    1107                 :   };
    1108                 : 
    1109                 : template <class T>
    1110                 : inline
    1111                 : nsRefPtr<T>*
    1112               1 : address_of( nsRefPtr<T>& aPtr )
    1113                 :   {
    1114               1 :     return aPtr.get_address();
    1115                 :   }
    1116                 : 
    1117                 : template <class T>
    1118                 : inline
    1119                 : const nsRefPtr<T>*
    1120                 : address_of( const nsRefPtr<T>& aPtr )
    1121                 :   {
    1122                 :     return aPtr.get_address();
    1123                 :   }
    1124                 : 
    1125                 : template <class T>
    1126                 : class nsRefPtrGetterAddRefs
    1127                 :     /*
    1128                 :       ...
    1129                 : 
    1130                 :       This class is designed to be used for anonymous temporary objects in the
    1131                 :       argument list of calls that return COM interface pointers, e.g.,
    1132                 : 
    1133                 :         nsRefPtr<IFoo> fooP;
    1134                 :         ...->GetAddRefedPointer(getter_AddRefs(fooP))
    1135                 : 
    1136                 :       DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
    1137                 : 
    1138                 :       When initialized with a |nsRefPtr|, as in the example above, it returns
    1139                 :       a |void**|, a |T**|, or an |nsISupports**| as needed, that the
    1140                 :       outer call (|GetAddRefedPointer| in this case) can fill in.
    1141                 : 
    1142                 :       This type should be a nested class inside |nsRefPtr<T>|.
    1143                 :     */
    1144                 :   {
    1145                 :     public:
    1146                 :       explicit
    1147         2141897 :       nsRefPtrGetterAddRefs( nsRefPtr<T>& aSmartPtr )
    1148         2141897 :           : mTargetSmartPtr(aSmartPtr)
    1149                 :         {
    1150                 :           // nothing else to do
    1151         2141897 :         }
    1152                 : 
    1153           27671 :       operator void**()
    1154                 :         {
    1155           27671 :           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
    1156                 :         }
    1157                 : 
    1158         2114226 :       operator T**()
    1159                 :         {
    1160         2114226 :           return mTargetSmartPtr.StartAssignment();
    1161                 :         }
    1162                 : 
    1163                 :       T*&
    1164               0 :       operator*()
    1165                 :         {
    1166               0 :           return *(mTargetSmartPtr.StartAssignment());
    1167                 :         }
    1168                 : 
    1169                 :     private:
    1170                 :       nsRefPtr<T>& mTargetSmartPtr;
    1171                 :   };
    1172                 : 
    1173                 : template <class T>
    1174                 : inline
    1175                 : nsRefPtrGetterAddRefs<T>
    1176         2141896 : getter_AddRefs( nsRefPtr<T>& aSmartPtr )
    1177                 :     /*
    1178                 :       Used around a |nsRefPtr| when 
    1179                 :       ...makes the class |nsRefPtrGetterAddRefs<T>| invisible.
    1180                 :     */
    1181                 :   {
    1182         2141896 :     return nsRefPtrGetterAddRefs<T>(aSmartPtr);
    1183                 :   }
    1184                 : 
    1185                 : 
    1186                 : 
    1187                 :   // Comparing two |nsRefPtr|s
    1188                 : 
    1189                 : template <class T, class U>
    1190                 : inline
    1191                 : bool
    1192            7662 : operator==( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
    1193                 :   {
    1194            7662 :     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
    1195                 :   }
    1196                 : 
    1197                 : 
    1198                 : template <class T, class U>
    1199                 : inline
    1200                 : bool
    1201               7 : operator!=( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
    1202                 :   {
    1203               7 :     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
    1204                 :   }
    1205                 : 
    1206                 : 
    1207                 :   // Comparing an |nsRefPtr| to a raw pointer
    1208                 : 
    1209                 : template <class T, class U>
    1210                 : inline
    1211                 : bool
    1212               4 : operator==( const nsRefPtr<T>& lhs, const U* rhs )
    1213                 :   {
    1214               4 :     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
    1215                 :   }
    1216                 : 
    1217                 : template <class T, class U>
    1218                 : inline
    1219                 : bool
    1220               4 : operator==( const U* lhs, const nsRefPtr<T>& rhs )
    1221                 :   {
    1222               4 :     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
    1223                 :   }
    1224                 : 
    1225                 : template <class T, class U>
    1226                 : inline
    1227                 : bool
    1228               4 : operator!=( const nsRefPtr<T>& lhs, const U* rhs )
    1229                 :   {
    1230               4 :     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
    1231                 :   }
    1232                 : 
    1233                 : template <class T, class U>
    1234                 : inline
    1235                 : bool
    1236               4 : operator!=( const U* lhs, const nsRefPtr<T>& rhs )
    1237                 :   {
    1238               4 :     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
    1239                 :   }
    1240                 : 
    1241                 :   // To avoid ambiguities caused by the presence of builtin |operator==|s
    1242                 :   // creating a situation where one of the |operator==| defined above
    1243                 :   // has a better conversion for one argument and the builtin has a
    1244                 :   // better conversion for the other argument, define additional
    1245                 :   // |operator==| without the |const| on the raw pointer.
    1246                 :   // See bug 65664 for details.
    1247                 : 
    1248                 : #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
    1249                 : template <class T, class U>
    1250                 : inline
    1251                 : bool
    1252         1276142 : operator==( const nsRefPtr<T>& lhs, U* rhs )
    1253                 :   {
    1254         1276142 :     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
    1255                 :   }
    1256                 : 
    1257                 : template <class T, class U>
    1258                 : inline
    1259                 : bool
    1260           47563 : operator==( U* lhs, const nsRefPtr<T>& rhs )
    1261                 :   {
    1262           47563 :     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
    1263                 :   }
    1264                 : 
    1265                 : template <class T, class U>
    1266                 : inline
    1267                 : bool
    1268            1061 : operator!=( const nsRefPtr<T>& lhs, U* rhs )
    1269                 :   {
    1270            1061 :     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
    1271                 :   }
    1272                 : 
    1273                 : template <class T, class U>
    1274                 : inline
    1275                 : bool
    1276             423 : operator!=( U* lhs, const nsRefPtr<T>& rhs )
    1277                 :   {
    1278             423 :     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
    1279                 :   }
    1280                 : #endif
    1281                 : 
    1282                 : 
    1283                 : 
    1284                 :   // Comparing an |nsRefPtr| to |0|
    1285                 : 
    1286                 : template <class T>
    1287                 : inline
    1288                 : bool
    1289             361 : operator==( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
    1290                 :     // specifically to allow |smartPtr == 0|
    1291                 :   {
    1292             361 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
    1293                 :   }
    1294                 : 
    1295                 : template <class T>
    1296                 : inline
    1297                 : bool
    1298               1 : operator==( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
    1299                 :     // specifically to allow |0 == smartPtr|
    1300                 :   {
    1301               1 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
    1302                 :   }
    1303                 : 
    1304                 : template <class T>
    1305                 : inline
    1306                 : bool
    1307            1043 : operator!=( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
    1308                 :     // specifically to allow |smartPtr != 0|
    1309                 :   {
    1310            1043 :     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
    1311                 :   }
    1312                 : 
    1313                 : template <class T>
    1314                 : inline
    1315                 : bool
    1316               1 : operator!=( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
    1317                 :     // specifically to allow |0 != smartPtr|
    1318                 :   {
    1319               1 :     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
    1320                 :   }
    1321                 : 
    1322                 : 
    1323                 : #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
    1324                 : 
    1325                 :   // We need to explicitly define comparison operators for `int'
    1326                 :   // because the compiler is lame.
    1327                 : 
    1328                 : template <class T>
    1329                 : inline
    1330                 : bool
    1331                 : operator==( const nsRefPtr<T>& lhs, int rhs )
    1332                 :     // specifically to allow |smartPtr == 0|
    1333                 :   {
    1334                 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
    1335                 :   }
    1336                 : 
    1337                 : template <class T>
    1338                 : inline
    1339                 : bool
    1340                 : operator==( int lhs, const nsRefPtr<T>& rhs )
    1341                 :     // specifically to allow |0 == smartPtr|
    1342                 :   {
    1343                 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
    1344                 :   }
    1345                 : 
    1346                 : #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
    1347                 : 
    1348                 : template <class SourceType, class DestinationType>
    1349                 : inline
    1350                 : nsresult
    1351              11 : CallQueryInterface( nsRefPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr )
    1352                 :   {
    1353              11 :     return CallQueryInterface(aSourcePtr.get(), aDestPtr);
    1354                 :   }
    1355                 : 
    1356                 : /*****************************************************************************/
    1357                 : 
    1358                 : template<class T>
    1359                 : class nsQueryObject : public nsCOMPtr_helper
    1360                 : {
    1361                 : public:
    1362             147 :   nsQueryObject(T* aRawPtr)
    1363             147 :     : mRawPtr(aRawPtr) {}
    1364                 : 
    1365             147 :   virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
    1366                 :     nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
    1367             147 :                               : NS_ERROR_NULL_POINTER;
    1368             147 :     return status;
    1369                 :   }
    1370                 : private:
    1371                 :   T* mRawPtr;
    1372                 : };
    1373                 : 
    1374                 : template<class T>
    1375                 : class nsQueryObjectWithError : public nsCOMPtr_helper
    1376                 : {
    1377                 : public:
    1378               1 :   nsQueryObjectWithError(T* aRawPtr, nsresult* aErrorPtr)
    1379               1 :     : mRawPtr(aRawPtr), mErrorPtr(aErrorPtr) {}
    1380                 : 
    1381               1 :   virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
    1382                 :     nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
    1383               1 :                               : NS_ERROR_NULL_POINTER;
    1384               1 :     if (mErrorPtr)
    1385               1 :       *mErrorPtr = status;
    1386               1 :     return status;
    1387                 :   }
    1388                 : private:
    1389                 :   T* mRawPtr;
    1390                 :   nsresult* mErrorPtr;
    1391                 : };
    1392                 : 
    1393                 : template<class T>
    1394                 : inline
    1395                 : nsQueryObject<T>
    1396              22 : do_QueryObject(T* aRawPtr)
    1397                 : {
    1398              22 :   return nsQueryObject<T>(aRawPtr);
    1399                 : }
    1400                 : 
    1401                 : template<class T>
    1402                 : inline
    1403                 : nsQueryObject<T>
    1404             124 : do_QueryObject(nsCOMPtr<T>& aRawPtr)
    1405                 : {
    1406             124 :   return nsQueryObject<T>(aRawPtr);
    1407                 : }
    1408                 : 
    1409                 : template<class T>
    1410                 : inline
    1411                 : nsQueryObject<T>
    1412               1 : do_QueryObject(nsRefPtr<T>& aRawPtr)
    1413                 : {
    1414               1 :   return nsQueryObject<T>(aRawPtr);
    1415                 : }
    1416                 : 
    1417                 : template<class T>
    1418                 : inline
    1419                 : nsQueryObjectWithError<T>
    1420                 : do_QueryObject(T* aRawPtr, nsresult* aErrorPtr)
    1421                 : {
    1422                 :   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
    1423                 : }
    1424                 : 
    1425                 : template<class T>
    1426                 : inline
    1427                 : nsQueryObjectWithError<T>
    1428                 : do_QueryObject(nsCOMPtr<T>& aRawPtr, nsresult* aErrorPtr)
    1429                 : {
    1430                 :   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
    1431                 : }
    1432                 : 
    1433                 : template<class T>
    1434                 : inline
    1435                 : nsQueryObjectWithError<T>
    1436               1 : do_QueryObject(nsRefPtr<T>& aRawPtr, nsresult* aErrorPtr)
    1437                 : {
    1438               1 :   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
    1439                 : }
    1440                 : 
    1441                 : /*****************************************************************************/
    1442                 : 
    1443                 : #endif // !defined(nsAutoPtr_h___)

Generated by: LCOV version 1.7