LCOV - code coverage report
Current view: directory - xpcom/base - nsAutoPtr.h (source / functions) Found Hit Coverage
Test: app.info Lines: 142 84 59.2 %
Date: 2012-06-02 Functions: 204 61 29.9 %

       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                 :       begin_assignment()
      61                 :         {
      62                 :           assign(0);
      63                 :           return reinterpret_cast<void**>(&mRawPtr);
      64                 :         }
      65                 : 
      66                 :       void
      67            2842 :       assign( T* newPtr )
      68                 :         {
      69            2842 :           NS_ABORT_IF_FALSE(mRawPtr != newPtr || !newPtr, "This makes no sense!");
      70            2842 :           T* oldPtr = mRawPtr;
      71            2842 :           mRawPtr = newPtr;
      72            2842 :           delete oldPtr;
      73            2842 :         }
      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        24892394 :             Ptr( T* aPtr )
      84        24892394 :                   : mPtr(aPtr)
      85                 :               {
      86        24892394 :               }
      87                 : 
      88        24892391 :             operator T*() const
      89                 :               {
      90        24892391 :                 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        24898221 :      ~nsAutoPtr()
     104                 :         {
     105        24898221 :           delete mRawPtr;
     106        24898221 :         }
     107                 : 
     108                 :         // Constructors
     109                 : 
     110            5839 :       nsAutoPtr()
     111            5839 :             : mRawPtr(0)
     112                 :           // default constructor
     113                 :         {
     114            5839 :         }
     115                 : 
     116        24892389 :       nsAutoPtr( Ptr aRawPtr )
     117        24892389 :             : mRawPtr(aRawPtr)
     118                 :           // construct from a raw pointer (of the right type)
     119                 :         {
     120        24892390 :         }
     121                 : 
     122                 :       nsAutoPtr( nsAutoPtr<T>& aSmartPtr )
     123                 :             : mRawPtr( aSmartPtr.forget() )
     124                 :           // Construct by transferring ownership from another smart pointer.
     125                 :         {
     126                 :         }
     127                 : 
     128                 : 
     129                 :         // Assignment operators
     130                 : 
     131                 :       nsAutoPtr<T>&
     132            2842 :       operator=( T* rhs )
     133                 :           // assign from a raw pointer (of the right type)
     134                 :         {
     135            2842 :           assign(rhs);
     136            2842 :           return *this;
     137                 :         }
     138                 : 
     139                 :       nsAutoPtr<T>& operator=( nsAutoPtr<T>& rhs )
     140                 :           // assign by transferring ownership from another smart pointer.
     141                 :         {
     142                 :           assign(rhs.forget());
     143                 :           return *this;
     144                 :         }
     145                 : 
     146                 :         // Other pointer operators
     147                 : 
     148                 :       T*
     149        24911201 :       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        24911201 :           return mRawPtr;
     157                 :         }
     158                 : 
     159        24911201 :       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        24911201 :           return get();
     171                 :         }
     172                 : 
     173                 :       T*
     174               0 :       forget()
     175                 :         {
     176               0 :           T* temp = mRawPtr;
     177               0 :           mRawPtr = 0;
     178               0 :           return temp;
     179                 :         }
     180                 : 
     181                 :       T*
     182               0 :       operator->() const
     183                 :         {
     184               0 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->().");
     185               0 :           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                 :       operator->*(U V::* aMember)
     195                 :         {
     196                 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->*().");
     197                 :           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               0 :       operator*() const
     220                 :         {
     221               0 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator*().");
     222               0 :           return *get();
     223                 :         }
     224                 : 
     225                 :       T**
     226                 :       StartAssignment()
     227                 :         {
     228                 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
     229                 :           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                 :       nsAutoPtrGetterTransfers( nsAutoPtr<T>& aSmartPtr )
     276                 :           : mTargetSmartPtr(aSmartPtr)
     277                 :         {
     278                 :           // nothing else to do
     279                 :         }
     280                 : 
     281                 :       operator void**()
     282                 :         {
     283                 :           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
     284                 :         }
     285                 : 
     286                 :       operator T**()
     287                 :         {
     288                 :           return mTargetSmartPtr.StartAssignment();
     289                 :         }
     290                 : 
     291                 :       T*&
     292                 :       operator*()
     293                 :         {
     294                 :           return *(mTargetSmartPtr.StartAssignment());
     295                 :         }
     296                 : 
     297                 :     private:
     298                 :       nsAutoPtr<T>& mTargetSmartPtr;
     299                 :   };
     300                 : 
     301                 : template <class T>
     302                 : inline
     303                 : nsAutoPtrGetterTransfers<T>
     304                 : getter_Transfers( nsAutoPtr<T>& aSmartPtr )
     305                 :     /*
     306                 :       Used around a |nsAutoPtr| when 
     307                 :       ...makes the class |nsAutoPtrGetterTransfers<T>| invisible.
     308                 :     */
     309                 :   {
     310                 :     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                 : operator==( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
     321                 :   {
     322                 :     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                 : operator==( const nsAutoPtr<T>& lhs, U* rhs )
     381                 :   {
     382                 :     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                 : operator==( U* lhs, const nsAutoPtr<T>& rhs )
     389                 :   {
     390                 :     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                 : operator!=( const nsAutoPtr<T>& lhs, U* rhs )
     397                 :   {
     398                 :     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                 : operator!=( U* lhs, const nsAutoPtr<T>& rhs )
     405                 :   {
     406                 :     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                 : operator==( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
     418                 :     // specifically to allow |smartPtr == 0|
     419                 :   {
     420                 :     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                 : operator!=( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
     436                 :     // specifically to allow |smartPtr != 0|
     437                 :   {
     438                 :     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                 :       begin_assignment()
     486                 :         {
     487                 :           assign(0);
     488                 :           return reinterpret_cast<void**>(&mRawPtr);
     489                 :         }
     490                 : 
     491                 :       void
     492               0 :       assign( T* newPtr )
     493                 :         {
     494               0 :           T* oldPtr = mRawPtr;
     495               0 :           mRawPtr = newPtr;
     496               0 :           delete [] oldPtr;
     497               0 :         }
     498                 : 
     499                 :     private:
     500                 :       T* mRawPtr;
     501                 : 
     502                 :     public:
     503                 :       typedef T element_type;
     504                 :       
     505               0 :      ~nsAutoArrayPtr()
     506                 :         {
     507               0 :           delete [] mRawPtr;
     508               0 :         }
     509                 : 
     510                 :         // Constructors
     511                 : 
     512                 :       nsAutoArrayPtr()
     513                 :             : mRawPtr(0)
     514                 :           // default constructor
     515                 :         {
     516                 :         }
     517                 : 
     518               0 :       nsAutoArrayPtr( T* aRawPtr )
     519               0 :             : mRawPtr(aRawPtr)
     520                 :           // construct from a raw pointer (of the right type)
     521                 :         {
     522               0 :         }
     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               0 :       operator=( T* rhs )
     535                 :           // assign from a raw pointer (of the right type)
     536                 :         {
     537               0 :           assign(rhs);
     538               0 :           return *this;
     539                 :         }
     540                 : 
     541                 :       nsAutoArrayPtr<T>& operator=( nsAutoArrayPtr<T>& rhs )
     542                 :           // assign by transferring ownership from another smart pointer.
     543                 :         {
     544                 :           assign(rhs.forget());
     545                 :           return *this;
     546                 :         }
     547                 : 
     548                 :         // Other pointer operators
     549                 : 
     550                 :       T*
     551               0 :       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               0 :           return mRawPtr;
     559                 :         }
     560                 : 
     561               0 :       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               0 :           return get();
     573                 :         }
     574                 : 
     575                 :       T*
     576                 :       forget()
     577                 :         {
     578                 :           T* temp = mRawPtr;
     579                 :           mRawPtr = 0;
     580                 :           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                 :       StartAssignment()
     616                 :         {
     617                 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
     618                 :           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                 :       nsAutoArrayPtrGetterTransfers( nsAutoArrayPtr<T>& aSmartPtr )
     665                 :           : mTargetSmartPtr(aSmartPtr)
     666                 :         {
     667                 :           // nothing else to do
     668                 :         }
     669                 : 
     670                 :       operator void**()
     671                 :         {
     672                 :           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
     673                 :         }
     674                 : 
     675                 :       operator T**()
     676                 :         {
     677                 :           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                 : getter_Transfers( nsAutoArrayPtr<T>& aSmartPtr )
     694                 :     /*
     695                 :       Used around a |nsAutoArrayPtr| when 
     696                 :       ...makes the class |nsAutoArrayPtrGetterTransfers<T>| invisible.
     697                 :     */
     698                 :   {
     699                 :     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                 : operator==( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
     807                 :     // specifically to allow |smartPtr == 0|
     808                 :   {
     809                 :     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            3156 :       assign_with_AddRef( T* rawPtr )
     877                 :         {
     878            3156 :           if ( rawPtr )
     879            1165 :             rawPtr->AddRef();
     880            3156 :           assign_assuming_AddRef(rawPtr);
     881            3156 :         }
     882                 : 
     883                 :       void**
     884            1592 :       begin_assignment()
     885                 :         {
     886            1592 :           assign_assuming_AddRef(0);
     887            1592 :           return reinterpret_cast<void**>(&mRawPtr);
     888                 :         }
     889                 : 
     890                 :       void
     891            4748 :       assign_assuming_AddRef( T* newPtr )
     892                 :         {
     893            4748 :           T* oldPtr = mRawPtr;
     894            4748 :           mRawPtr = newPtr;
     895            4748 :           if ( oldPtr )
     896            1807 :             oldPtr->Release();
     897            4748 :         }
     898                 : 
     899                 :     private:
     900                 :       T* mRawPtr;
     901                 : 
     902                 :     public:
     903                 :       typedef T element_type;
     904                 :       
     905            5743 :      ~nsRefPtr()
     906                 :         {
     907            5743 :           if ( mRawPtr )
     908            3023 :             mRawPtr->Release();
     909            5743 :         }
     910                 : 
     911                 :         // Constructors
     912                 : 
     913            2640 :       nsRefPtr()
     914            2640 :             : mRawPtr(0)
     915                 :           // default constructor
     916                 :         {
     917            2640 :         }
     918                 : 
     919            1673 :       nsRefPtr( const nsRefPtr<T>& aSmartPtr )
     920            1673 :             : mRawPtr(aSmartPtr.mRawPtr)
     921                 :           // copy-constructor
     922                 :         {
     923            1673 :           if ( mRawPtr )
     924             815 :             mRawPtr->AddRef();
     925            1673 :         }
     926                 : 
     927              11 :       nsRefPtr( T* aRawPtr )
     928              11 :             : mRawPtr(aRawPtr)
     929                 :           // construct from a raw pointer (of the right type)
     930                 :         {
     931              11 :           if ( mRawPtr )
     932              11 :             mRawPtr->AddRef();
     933              11 :         }
     934                 : 
     935                 :       template <typename I>
     936               0 :       nsRefPtr( const already_AddRefed<I>& aSmartPtr )
     937               0 :             : mRawPtr(aSmartPtr.mRawPtr)
     938                 :           // construct from |dont_AddRef(expr)|
     939                 :         {
     940               0 :         }
     941                 : 
     942                 :       nsRefPtr( const nsCOMPtr_helper& helper )
     943                 :         {
     944                 :           void* newRawPtr;
     945                 :           if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
     946                 :             newRawPtr = 0;
     947                 :           mRawPtr = static_cast<T*>(newRawPtr);
     948                 :         }
     949                 : 
     950                 :         // Assignment operators
     951                 : 
     952                 :       nsRefPtr<T>&
     953            2804 :       operator=( const nsRefPtr<T>& rhs )
     954                 :           // copy assignment operator
     955                 :         {
     956            2804 :           assign_with_AddRef(rhs.mRawPtr);
     957            2804 :           return *this;
     958                 :         }
     959                 : 
     960                 :       nsRefPtr<T>&
     961             352 :       operator=( T* rhs )
     962                 :           // assign from a raw pointer (of the right type)
     963                 :         {
     964             352 :           assign_with_AddRef(rhs);
     965             352 :           return *this;
     966                 :         }
     967                 : 
     968                 :       template <typename I>
     969                 :       nsRefPtr<T>&
     970                 :       operator=( const already_AddRefed<I>& rhs )
     971                 :           // assign from |dont_AddRef(expr)|
     972                 :         {
     973                 :           assign_assuming_AddRef(rhs.mRawPtr);
     974                 :           return *this;
     975                 :         }
     976                 : 
     977                 :       nsRefPtr<T>&
     978                 :       operator=( const nsCOMPtr_helper& helper )
     979                 :         {
     980                 :           void* newRawPtr;
     981                 :           if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
     982                 :             newRawPtr = 0;
     983                 :           assign_assuming_AddRef(static_cast<T*>(newRawPtr));
     984                 :           return *this;
     985                 :         }
     986                 : 
     987                 :         // Other pointer operators
     988                 : 
     989                 :       void
     990               0 :       swap( nsRefPtr<T>& rhs )
     991                 :           // ...exchange ownership with |rhs|; can save a pair of refcount operations
     992                 :         {
     993               0 :           T* temp = rhs.mRawPtr;
     994               0 :           rhs.mRawPtr = mRawPtr;
     995               0 :           mRawPtr = temp;
     996               0 :         }
     997                 : 
     998                 :       void
     999               0 :       swap( T*& rhs )
    1000                 :           // ...exchange ownership with |rhs|; can save a pair of refcount operations
    1001                 :         {
    1002               0 :           T* temp = rhs;
    1003               0 :           rhs = mRawPtr;
    1004               0 :           mRawPtr = temp;
    1005               0 :         }
    1006                 : 
    1007                 :       already_AddRefed<T>
    1008               0 :       forget()
    1009                 :           // return the value of mRawPtr and null out mRawPtr. Useful for
    1010                 :           // already_AddRefed return values.
    1011                 :         {
    1012               0 :           T* temp = 0;
    1013               0 :           swap(temp);
    1014               0 :           return temp;
    1015                 :         }
    1016                 : 
    1017                 :       template <typename I>
    1018                 :       void
    1019               0 :       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               0 :           NS_ASSERTION(rhs, "Null pointer passed to forget!");
    1026               0 :           *rhs = mRawPtr;
    1027               0 :           mRawPtr = 0;
    1028               0 :         }
    1029                 : 
    1030                 :       T*
    1031           25952 :       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           25952 :           return const_cast<T*>(mRawPtr);
    1038                 :         }
    1039                 : 
    1040           11186 :       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           11186 :           return get();
    1051                 :         }
    1052                 : 
    1053                 :       T*
    1054           12971 :       operator->() const
    1055                 :         {
    1056           12971 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->().");
    1057           12971 :           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                 :       get_address()
    1075                 :           // This is not intended to be used by clients.  See |address_of|
    1076                 :           // below.
    1077                 :         {
    1078                 :           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                 :       operator*() const
    1092                 :         {
    1093                 :           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator*().");
    1094                 :           return *get();
    1095                 :         }
    1096                 : 
    1097                 :       T**
    1098            1592 :       StartAssignment()
    1099                 :         {
    1100                 : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
    1101            1592 :           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                 : address_of( nsRefPtr<T>& aPtr )
    1113                 :   {
    1114                 :     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            1592 :       nsRefPtrGetterAddRefs( nsRefPtr<T>& aSmartPtr )
    1148            1592 :           : mTargetSmartPtr(aSmartPtr)
    1149                 :         {
    1150                 :           // nothing else to do
    1151            1592 :         }
    1152                 : 
    1153                 :       operator void**()
    1154                 :         {
    1155                 :           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
    1156                 :         }
    1157                 : 
    1158            1592 :       operator T**()
    1159                 :         {
    1160            1592 :           return mTargetSmartPtr.StartAssignment();
    1161                 :         }
    1162                 : 
    1163                 :       T*&
    1164                 :       operator*()
    1165                 :         {
    1166                 :           return *(mTargetSmartPtr.StartAssignment());
    1167                 :         }
    1168                 : 
    1169                 :     private:
    1170                 :       nsRefPtr<T>& mTargetSmartPtr;
    1171                 :   };
    1172                 : 
    1173                 : template <class T>
    1174                 : inline
    1175                 : nsRefPtrGetterAddRefs<T>
    1176            1592 : getter_AddRefs( nsRefPtr<T>& aSmartPtr )
    1177                 :     /*
    1178                 :       Used around a |nsRefPtr| when 
    1179                 :       ...makes the class |nsRefPtrGetterAddRefs<T>| invisible.
    1180                 :     */
    1181                 :   {
    1182            1592 :     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               0 : operator==( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
    1193                 :   {
    1194               0 :     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                 : operator!=( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
    1202                 :   {
    1203                 :     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                 : operator==( const nsRefPtr<T>& lhs, const U* rhs )
    1213                 :   {
    1214                 :     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                 : operator==( const U* lhs, const nsRefPtr<T>& rhs )
    1221                 :   {
    1222                 :     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                 : operator!=( const nsRefPtr<T>& lhs, const U* rhs )
    1229                 :   {
    1230                 :     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                 : operator!=( const U* lhs, const nsRefPtr<T>& rhs )
    1237                 :   {
    1238                 :     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               0 : operator==( const nsRefPtr<T>& lhs, U* rhs )
    1253                 :   {
    1254               0 :     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             166 : operator==( U* lhs, const nsRefPtr<T>& rhs )
    1261                 :   {
    1262             166 :     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               0 : operator!=( const nsRefPtr<T>& lhs, U* rhs )
    1269                 :   {
    1270               0 :     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                 : operator!=( U* lhs, const nsRefPtr<T>& rhs )
    1277                 :   {
    1278                 :     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               0 : operator==( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
    1290                 :     // specifically to allow |smartPtr == 0|
    1291                 :   {
    1292               0 :     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
    1293                 :   }
    1294                 : 
    1295                 : template <class T>
    1296                 : inline
    1297                 : bool
    1298                 : operator==( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
    1299                 :     // specifically to allow |0 == smartPtr|
    1300                 :   {
    1301                 :     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
    1302                 :   }
    1303                 : 
    1304                 : template <class T>
    1305                 : inline
    1306                 : bool
    1307            1629 : operator!=( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
    1308                 :     // specifically to allow |smartPtr != 0|
    1309                 :   {
    1310            1629 :     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
    1311                 :   }
    1312                 : 
    1313                 : template <class T>
    1314                 : inline
    1315                 : bool
    1316                 : operator!=( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
    1317                 :     // specifically to allow |0 != smartPtr|
    1318                 :   {
    1319                 :     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                 : CallQueryInterface( nsRefPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr )
    1352                 :   {
    1353                 :     return CallQueryInterface(aSourcePtr.get(), aDestPtr);
    1354                 :   }
    1355                 : 
    1356                 : /*****************************************************************************/
    1357                 : 
    1358                 : template<class T>
    1359                 : class nsQueryObject : public nsCOMPtr_helper
    1360                 : {
    1361                 : public:
    1362                 :   nsQueryObject(T* aRawPtr)
    1363                 :     : mRawPtr(aRawPtr) {}
    1364                 : 
    1365                 :   virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
    1366                 :     nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
    1367                 :                               : NS_ERROR_NULL_POINTER;
    1368                 :     return status;
    1369                 :   }
    1370                 : private:
    1371                 :   T* mRawPtr;
    1372                 : };
    1373                 : 
    1374                 : template<class T>
    1375                 : class nsQueryObjectWithError : public nsCOMPtr_helper
    1376                 : {
    1377                 : public:
    1378                 :   nsQueryObjectWithError(T* aRawPtr, nsresult* aErrorPtr)
    1379                 :     : mRawPtr(aRawPtr), mErrorPtr(aErrorPtr) {}
    1380                 : 
    1381                 :   virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
    1382                 :     nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
    1383                 :                               : NS_ERROR_NULL_POINTER;
    1384                 :     if (mErrorPtr)
    1385                 :       *mErrorPtr = status;
    1386                 :     return status;
    1387                 :   }
    1388                 : private:
    1389                 :   T* mRawPtr;
    1390                 :   nsresult* mErrorPtr;
    1391                 : };
    1392                 : 
    1393                 : template<class T>
    1394                 : inline
    1395                 : nsQueryObject<T>
    1396                 : do_QueryObject(T* aRawPtr)
    1397                 : {
    1398                 :   return nsQueryObject<T>(aRawPtr);
    1399                 : }
    1400                 : 
    1401                 : template<class T>
    1402                 : inline
    1403                 : nsQueryObject<T>
    1404                 : do_QueryObject(nsCOMPtr<T>& aRawPtr)
    1405                 : {
    1406                 :   return nsQueryObject<T>(aRawPtr);
    1407                 : }
    1408                 : 
    1409                 : template<class T>
    1410                 : inline
    1411                 : nsQueryObject<T>
    1412                 : do_QueryObject(nsRefPtr<T>& aRawPtr)
    1413                 : {
    1414                 :   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                 : do_QueryObject(nsRefPtr<T>& aRawPtr, nsresult* aErrorPtr)
    1437                 : {
    1438                 :   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
    1439                 : }
    1440                 : 
    1441                 : /*****************************************************************************/
    1442                 : 
    1443                 : #endif // !defined(nsAutoPtr_h___)

Generated by: LCOV version 1.7