xpcom/base/nsAutoPtr.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsAutoPtr_h___
     7 #define nsAutoPtr_h___
     9 #include "nsCOMPtr.h"
    11 #include "nsCycleCollectionNoteChild.h"
    12 #include "mozilla/MemoryReporting.h"
    14 /*****************************************************************************/
    16 // template <class T> class nsAutoPtrGetterTransfers;
    18 template <class T>
    19 class nsAutoPtr
    20   {
    21     private:
    22       void**
    23       begin_assignment()
    24         {
    25           assign(0);
    26           return reinterpret_cast<void**>(&mRawPtr);
    27         }
    29       void
    30       assign( T* newPtr )
    31         {
    32           T* oldPtr = mRawPtr;
    34           if (newPtr != nullptr && newPtr == oldPtr) {
    35             NS_RUNTIMEABORT("Logic flaw in the caller");
    36           }
    38           mRawPtr = newPtr;
    39           delete oldPtr;
    40         }
    42       // |class Ptr| helps us prevent implicit "copy construction"
    43       // through |operator T*() const| from a |const nsAutoPtr<T>|
    44       // because two implicit conversions in a row aren't allowed.
    45       // It still allows assignment from T* through implicit conversion
    46       // from |T*| to |nsAutoPtr<T>::Ptr|
    47       class Ptr
    48         {
    49           public:
    50             Ptr( T* aPtr )
    51                   : mPtr(aPtr)
    52               {
    53               }
    55             operator T*() const
    56               {
    57                 return mPtr;
    58               }
    60           private:
    61             T* mPtr;
    62         };
    64     private:
    65       T* mRawPtr;
    67     public:
    68       typedef T element_type;
    70      ~nsAutoPtr()
    71         {
    72           delete mRawPtr;
    73         }
    75         // Constructors
    77       nsAutoPtr()
    78             : mRawPtr(0)
    79           // default constructor
    80         {
    81         }
    83       nsAutoPtr( Ptr aRawPtr )
    84             : mRawPtr(aRawPtr)
    85           // construct from a raw pointer (of the right type)
    86         {
    87         }
    89       // This constructor shouldn't exist; we should just use the &&
    90       // constructor.
    91       nsAutoPtr( nsAutoPtr<T>& aSmartPtr )
    92             : mRawPtr( aSmartPtr.forget() )
    93           // Construct by transferring ownership from another smart pointer.
    94         {
    95         }
    97       nsAutoPtr( nsAutoPtr<T>&& aSmartPtr )
    98             : mRawPtr( aSmartPtr.forget() )
    99           // Construct by transferring ownership from another smart pointer.
   100         {
   101         }
   103         // Assignment operators
   105       nsAutoPtr<T>&
   106       operator=( T* rhs )
   107           // assign from a raw pointer (of the right type)
   108         {
   109           assign(rhs);
   110           return *this;
   111         }
   113       nsAutoPtr<T>& operator=( nsAutoPtr<T>& rhs )
   114           // assign by transferring ownership from another smart pointer.
   115         {
   116           assign(rhs.forget());
   117           return *this;
   118         }
   120         // Other pointer operators
   122       T*
   123       get() const
   124           /*
   125             Prefer the implicit conversion provided automatically by
   126             |operator T*() const|.  Use |get()| _only_ to resolve
   127             ambiguity.
   128           */
   129         {
   130           return mRawPtr;
   131         }
   133       operator T*() const
   134           /*
   135             ...makes an |nsAutoPtr| act like its underlying raw pointer
   136             type  whenever it is used in a context where a raw pointer
   137             is expected.  It is this operator that makes an |nsAutoPtr|
   138             substitutable for a raw pointer.
   140             Prefer the implicit use of this operator to calling |get()|,
   141             except where necessary to resolve ambiguity.
   142           */
   143         {
   144           return get();
   145         }
   147       T*
   148       forget()
   149         {
   150           T* temp = mRawPtr;
   151           mRawPtr = 0;
   152           return temp;
   153         }
   155       T*
   156       operator->() const
   157         {
   158           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->().");
   159           return get();
   160         }
   162       // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
   163       // causes internal compiler errors for some MSVC versions.  (It's not
   164       // clear to me whether it should be needed.)
   165 #ifndef _MSC_VER
   166       template <class U, class V>
   167       U&
   168       operator->*(U V::* aMember)
   169         {
   170           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->*().");
   171           return get()->*aMember;
   172         }
   173 #endif
   175       nsAutoPtr<T>*
   176       get_address()
   177           // This is not intended to be used by clients.  See |address_of|
   178           // below.
   179         {
   180           return this;
   181         }
   183       const nsAutoPtr<T>*
   184       get_address() const
   185           // This is not intended to be used by clients.  See |address_of|
   186           // below.
   187         {
   188           return this;
   189         }
   191     public:
   192       T&
   193       operator*() const
   194         {
   195           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator*().");
   196           return *get();
   197         }
   199       T**
   200       StartAssignment()
   201         {
   202 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
   203           return reinterpret_cast<T**>(begin_assignment());
   204 #else
   205           assign(0);
   206           return reinterpret_cast<T**>(&mRawPtr);
   207 #endif
   208         }
   209   };
   211 template <class T>
   212 inline
   213 nsAutoPtr<T>*
   214 address_of( nsAutoPtr<T>& aPtr )
   215   {
   216     return aPtr.get_address();
   217   }
   219 template <class T>
   220 inline
   221 const nsAutoPtr<T>*
   222 address_of( const nsAutoPtr<T>& aPtr )
   223   {
   224     return aPtr.get_address();
   225   }
   227 template <class T>
   228 class nsAutoPtrGetterTransfers
   229     /*
   230       ...
   232       This class is designed to be used for anonymous temporary objects in the
   233       argument list of calls that return COM interface pointers, e.g.,
   235         nsAutoPtr<IFoo> fooP;
   236         ...->GetTransferedPointer(getter_Transfers(fooP))
   238       DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
   240       When initialized with a |nsAutoPtr|, as in the example above, it returns
   241       a |void**|, a |T**|, or an |nsISupports**| as needed, that the
   242       outer call (|GetTransferedPointer| in this case) can fill in.
   244       This type should be a nested class inside |nsAutoPtr<T>|.
   245     */
   246   {
   247     public:
   248       explicit
   249       nsAutoPtrGetterTransfers( nsAutoPtr<T>& aSmartPtr )
   250           : mTargetSmartPtr(aSmartPtr)
   251         {
   252           // nothing else to do
   253         }
   255       operator void**()
   256         {
   257           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
   258         }
   260       operator T**()
   261         {
   262           return mTargetSmartPtr.StartAssignment();
   263         }
   265       T*&
   266       operator*()
   267         {
   268           return *(mTargetSmartPtr.StartAssignment());
   269         }
   271     private:
   272       nsAutoPtr<T>& mTargetSmartPtr;
   273   };
   275 template <class T>
   276 inline
   277 nsAutoPtrGetterTransfers<T>
   278 getter_Transfers( nsAutoPtr<T>& aSmartPtr )
   279     /*
   280       Used around a |nsAutoPtr| when 
   281       ...makes the class |nsAutoPtrGetterTransfers<T>| invisible.
   282     */
   283   {
   284     return nsAutoPtrGetterTransfers<T>(aSmartPtr);
   285   }
   289   // Comparing two |nsAutoPtr|s
   291 template <class T, class U>
   292 inline
   293 bool
   294 operator==( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
   295   {
   296     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
   297   }
   300 template <class T, class U>
   301 inline
   302 bool
   303 operator!=( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
   304   {
   305     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
   306   }
   309   // Comparing an |nsAutoPtr| to a raw pointer
   311 template <class T, class U>
   312 inline
   313 bool
   314 operator==( const nsAutoPtr<T>& lhs, const U* rhs )
   315   {
   316     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
   317   }
   319 template <class T, class U>
   320 inline
   321 bool
   322 operator==( const U* lhs, const nsAutoPtr<T>& rhs )
   323   {
   324     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   325   }
   327 template <class T, class U>
   328 inline
   329 bool
   330 operator!=( const nsAutoPtr<T>& lhs, const U* rhs )
   331   {
   332     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
   333   }
   335 template <class T, class U>
   336 inline
   337 bool
   338 operator!=( const U* lhs, const nsAutoPtr<T>& rhs )
   339   {
   340     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   341   }
   343   // To avoid ambiguities caused by the presence of builtin |operator==|s
   344   // creating a situation where one of the |operator==| defined above
   345   // has a better conversion for one argument and the builtin has a
   346   // better conversion for the other argument, define additional
   347   // |operator==| without the |const| on the raw pointer.
   348   // See bug 65664 for details.
   350 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
   351 template <class T, class U>
   352 inline
   353 bool
   354 operator==( const nsAutoPtr<T>& lhs, U* rhs )
   355   {
   356     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
   357   }
   359 template <class T, class U>
   360 inline
   361 bool
   362 operator==( U* lhs, const nsAutoPtr<T>& rhs )
   363   {
   364     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   365   }
   367 template <class T, class U>
   368 inline
   369 bool
   370 operator!=( const nsAutoPtr<T>& lhs, U* rhs )
   371   {
   372     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
   373   }
   375 template <class T, class U>
   376 inline
   377 bool
   378 operator!=( U* lhs, const nsAutoPtr<T>& rhs )
   379   {
   380     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   381   }
   382 #endif
   386   // Comparing an |nsAutoPtr| to |0|
   388 template <class T>
   389 inline
   390 bool
   391 operator==( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
   392     // specifically to allow |smartPtr == 0|
   393   {
   394     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   395   }
   397 template <class T>
   398 inline
   399 bool
   400 operator==( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
   401     // specifically to allow |0 == smartPtr|
   402   {
   403     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   404   }
   406 template <class T>
   407 inline
   408 bool
   409 operator!=( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
   410     // specifically to allow |smartPtr != 0|
   411   {
   412     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
   413   }
   415 template <class T>
   416 inline
   417 bool
   418 operator!=( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
   419     // specifically to allow |0 != smartPtr|
   420   {
   421     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
   422   }
   425 #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
   427   // We need to explicitly define comparison operators for `int'
   428   // because the compiler is lame.
   430 template <class T>
   431 inline
   432 bool
   433 operator==( const nsAutoPtr<T>& lhs, int rhs )
   434     // specifically to allow |smartPtr == 0|
   435   {
   436     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   437   }
   439 template <class T>
   440 inline
   441 bool
   442 operator==( int lhs, const nsAutoPtr<T>& rhs )
   443     // specifically to allow |0 == smartPtr|
   444   {
   445     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   446   }
   448 #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
   450 /*****************************************************************************/
   452 // template <class T> class nsAutoArrayPtrGetterTransfers;
   454 template <class T>
   455 class nsAutoArrayPtr
   456   {
   457     private:
   458       void**
   459       begin_assignment()
   460         {
   461           assign(0);
   462           return reinterpret_cast<void**>(&mRawPtr);
   463         }
   465       void
   466       assign( T* newPtr )
   467         {
   468           T* oldPtr = mRawPtr;
   469           mRawPtr = newPtr;
   470           delete [] oldPtr;
   471         }
   473     private:
   474       T* mRawPtr;
   476     public:
   477       typedef T element_type;
   479      ~nsAutoArrayPtr()
   480         {
   481           delete [] mRawPtr;
   482         }
   484         // Constructors
   486       nsAutoArrayPtr()
   487             : mRawPtr(0)
   488           // default constructor
   489         {
   490         }
   492       nsAutoArrayPtr( T* aRawPtr )
   493             : mRawPtr(aRawPtr)
   494           // construct from a raw pointer (of the right type)
   495         {
   496         }
   498       nsAutoArrayPtr( nsAutoArrayPtr<T>& aSmartPtr )
   499             : mRawPtr( aSmartPtr.forget() )
   500           // Construct by transferring ownership from another smart pointer.
   501         {
   502         }
   505         // Assignment operators
   507       nsAutoArrayPtr<T>&
   508       operator=( T* rhs )
   509           // assign from a raw pointer (of the right type)
   510         {
   511           assign(rhs);
   512           return *this;
   513         }
   515       nsAutoArrayPtr<T>& operator=( nsAutoArrayPtr<T>& rhs )
   516           // assign by transferring ownership from another smart pointer.
   517         {
   518           assign(rhs.forget());
   519           return *this;
   520         }
   522         // Other pointer operators
   524       T*
   525       get() const
   526           /*
   527             Prefer the implicit conversion provided automatically by
   528             |operator T*() const|.  Use |get()| _only_ to resolve
   529             ambiguity.
   530           */
   531         {
   532           return mRawPtr;
   533         }
   535       operator T*() const
   536           /*
   537             ...makes an |nsAutoArrayPtr| act like its underlying raw pointer
   538             type  whenever it is used in a context where a raw pointer
   539             is expected.  It is this operator that makes an |nsAutoArrayPtr|
   540             substitutable for a raw pointer.
   542             Prefer the implicit use of this operator to calling |get()|,
   543             except where necessary to resolve ambiguity.
   544           */
   545         {
   546           return get();
   547         }
   549       T*
   550       forget()
   551         {
   552           T* temp = mRawPtr;
   553           mRawPtr = 0;
   554           return temp;
   555         }
   557       T*
   558       operator->() const
   559         {
   560           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoArrayPtr with operator->().");
   561           return get();
   562         }
   564       nsAutoArrayPtr<T>*
   565       get_address()
   566           // This is not intended to be used by clients.  See |address_of|
   567           // below.
   568         {
   569           return this;
   570         }
   572       const nsAutoArrayPtr<T>*
   573       get_address() const
   574           // This is not intended to be used by clients.  See |address_of|
   575           // below.
   576         {
   577           return this;
   578         }
   580     public:
   581       T&
   582       operator*() const
   583         {
   584           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoArrayPtr with operator*().");
   585           return *get();
   586         }
   588       T**
   589       StartAssignment()
   590         {
   591 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
   592           return reinterpret_cast<T**>(begin_assignment());
   593 #else
   594           assign(0);
   595           return reinterpret_cast<T**>(&mRawPtr);
   596 #endif
   597         }
   599       size_t
   600       SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   601         {
   602           return aMallocSizeOf(mRawPtr);
   603         }
   605       size_t
   606       SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   607         {
   608           return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   609         }
   610   };
   612 template <class T>
   613 inline
   614 nsAutoArrayPtr<T>*
   615 address_of( nsAutoArrayPtr<T>& aPtr )
   616   {
   617     return aPtr.get_address();
   618   }
   620 template <class T>
   621 inline
   622 const nsAutoArrayPtr<T>*
   623 address_of( const nsAutoArrayPtr<T>& aPtr )
   624   {
   625     return aPtr.get_address();
   626   }
   628 template <class T>
   629 class nsAutoArrayPtrGetterTransfers
   630     /*
   631       ...
   633       This class is designed to be used for anonymous temporary objects in the
   634       argument list of calls that return COM interface pointers, e.g.,
   636         nsAutoArrayPtr<IFoo> fooP;
   637         ...->GetTransferedPointer(getter_Transfers(fooP))
   639       DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
   641       When initialized with a |nsAutoArrayPtr|, as in the example above, it returns
   642       a |void**|, a |T**|, or an |nsISupports**| as needed, that the
   643       outer call (|GetTransferedPointer| in this case) can fill in.
   645       This type should be a nested class inside |nsAutoArrayPtr<T>|.
   646     */
   647   {
   648     public:
   649       explicit
   650       nsAutoArrayPtrGetterTransfers( nsAutoArrayPtr<T>& aSmartPtr )
   651           : mTargetSmartPtr(aSmartPtr)
   652         {
   653           // nothing else to do
   654         }
   656       operator void**()
   657         {
   658           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
   659         }
   661       operator T**()
   662         {
   663           return mTargetSmartPtr.StartAssignment();
   664         }
   666       T*&
   667       operator*()
   668         {
   669           return *(mTargetSmartPtr.StartAssignment());
   670         }
   672     private:
   673       nsAutoArrayPtr<T>& mTargetSmartPtr;
   674   };
   676 template <class T>
   677 inline
   678 nsAutoArrayPtrGetterTransfers<T>
   679 getter_Transfers( nsAutoArrayPtr<T>& aSmartPtr )
   680     /*
   681       Used around a |nsAutoArrayPtr| when 
   682       ...makes the class |nsAutoArrayPtrGetterTransfers<T>| invisible.
   683     */
   684   {
   685     return nsAutoArrayPtrGetterTransfers<T>(aSmartPtr);
   686   }
   690   // Comparing two |nsAutoArrayPtr|s
   692 template <class T, class U>
   693 inline
   694 bool
   695 operator==( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
   696   {
   697     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
   698   }
   701 template <class T, class U>
   702 inline
   703 bool
   704 operator!=( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
   705   {
   706     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
   707   }
   710   // Comparing an |nsAutoArrayPtr| to a raw pointer
   712 template <class T, class U>
   713 inline
   714 bool
   715 operator==( const nsAutoArrayPtr<T>& lhs, const U* rhs )
   716   {
   717     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
   718   }
   720 template <class T, class U>
   721 inline
   722 bool
   723 operator==( const U* lhs, const nsAutoArrayPtr<T>& rhs )
   724   {
   725     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   726   }
   728 template <class T, class U>
   729 inline
   730 bool
   731 operator!=( const nsAutoArrayPtr<T>& lhs, const U* rhs )
   732   {
   733     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
   734   }
   736 template <class T, class U>
   737 inline
   738 bool
   739 operator!=( const U* lhs, const nsAutoArrayPtr<T>& rhs )
   740   {
   741     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   742   }
   744   // To avoid ambiguities caused by the presence of builtin |operator==|s
   745   // creating a situation where one of the |operator==| defined above
   746   // has a better conversion for one argument and the builtin has a
   747   // better conversion for the other argument, define additional
   748   // |operator==| without the |const| on the raw pointer.
   749   // See bug 65664 for details.
   751 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
   752 template <class T, class U>
   753 inline
   754 bool
   755 operator==( const nsAutoArrayPtr<T>& lhs, U* rhs )
   756   {
   757     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
   758   }
   760 template <class T, class U>
   761 inline
   762 bool
   763 operator==( U* lhs, const nsAutoArrayPtr<T>& rhs )
   764   {
   765     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   766   }
   768 template <class T, class U>
   769 inline
   770 bool
   771 operator!=( const nsAutoArrayPtr<T>& lhs, U* rhs )
   772   {
   773     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
   774   }
   776 template <class T, class U>
   777 inline
   778 bool
   779 operator!=( U* lhs, const nsAutoArrayPtr<T>& rhs )
   780   {
   781     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   782   }
   783 #endif
   787   // Comparing an |nsAutoArrayPtr| to |0|
   789 template <class T>
   790 inline
   791 bool
   792 operator==( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
   793     // specifically to allow |smartPtr == 0|
   794   {
   795     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   796   }
   798 template <class T>
   799 inline
   800 bool
   801 operator==( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
   802     // specifically to allow |0 == smartPtr|
   803   {
   804     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   805   }
   807 template <class T>
   808 inline
   809 bool
   810 operator!=( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
   811     // specifically to allow |smartPtr != 0|
   812   {
   813     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
   814   }
   816 template <class T>
   817 inline
   818 bool
   819 operator!=( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
   820     // specifically to allow |0 != smartPtr|
   821   {
   822     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
   823   }
   826 #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
   828   // We need to explicitly define comparison operators for `int'
   829   // because the compiler is lame.
   831 template <class T>
   832 inline
   833 bool
   834 operator==( const nsAutoArrayPtr<T>& lhs, int rhs )
   835     // specifically to allow |smartPtr == 0|
   836   {
   837     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   838   }
   840 template <class T>
   841 inline
   842 bool
   843 operator==( int lhs, const nsAutoArrayPtr<T>& rhs )
   844     // specifically to allow |0 == smartPtr|
   845   {
   846     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   847   }
   849 #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
   852 /*****************************************************************************/
   854 // template <class T> class nsRefPtrGetterAddRefs;
   856 template <class T>
   857 class nsRefPtr
   858   {
   859     private:
   861       void
   862       assign_with_AddRef( T* rawPtr )
   863         {
   864           if ( rawPtr )
   865             rawPtr->AddRef();
   866           assign_assuming_AddRef(rawPtr);
   867         }
   869       void**
   870       begin_assignment()
   871         {
   872           assign_assuming_AddRef(0);
   873           return reinterpret_cast<void**>(&mRawPtr);
   874         }
   876       void
   877       assign_assuming_AddRef( T* newPtr )
   878         {
   879           T* oldPtr = mRawPtr;
   880           mRawPtr = newPtr;
   881           if ( oldPtr )
   882             oldPtr->Release();
   883         }
   885     private:
   886       T* mRawPtr;
   888     public:
   889       typedef T element_type;
   891      ~nsRefPtr()
   892         {
   893           if ( mRawPtr )
   894             mRawPtr->Release();
   895         }
   897         // Constructors
   899       nsRefPtr()
   900             : mRawPtr(0)
   901           // default constructor
   902         {
   903         }
   905       nsRefPtr(const nsRefPtr<T>& aSmartPtr)
   906             : mRawPtr(aSmartPtr.mRawPtr)
   907           // copy-constructor
   908         {
   909           if ( mRawPtr )
   910             mRawPtr->AddRef();
   911         }
   913       nsRefPtr(nsRefPtr<T>&& aRefPtr)
   914             : mRawPtr(aRefPtr.mRawPtr)
   915         {
   916           aRefPtr.mRawPtr = nullptr;
   917         }
   919       // construct from a raw pointer (of the right type)
   921       nsRefPtr(T* aRawPtr)
   922         : mRawPtr(aRawPtr)
   923         {
   924           if ( mRawPtr )
   925             mRawPtr->AddRef();
   926         }
   928       template <typename I>
   929       nsRefPtr( already_AddRefed<I>& aSmartPtr )
   930             : mRawPtr(aSmartPtr.take())
   931           // construct from |already_AddRefed|
   932         {
   933         }
   935       template <typename I>
   936       nsRefPtr( already_AddRefed<I>&& aSmartPtr )
   937             : mRawPtr(aSmartPtr.take())
   938           // construct from |otherRefPtr.forget()|
   939         {
   940         }
   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         }
   950         // Assignment operators
   952       nsRefPtr<T>&
   953       operator=(const nsRefPtr<T>& rhs)
   954           // copy assignment operator
   955         {
   956           assign_with_AddRef(rhs.mRawPtr);
   957           return *this;
   958         }
   960       nsRefPtr<T>&
   961       operator=( T* rhs )
   962           // assign from a raw pointer (of the right type)
   963         {
   964           assign_with_AddRef(rhs);
   965           return *this;
   966         }
   968       template <typename I>
   969       nsRefPtr<T>&
   970       operator=( already_AddRefed<I>& rhs )
   971           // assign from |already_AddRefed|
   972         {
   973           assign_assuming_AddRef(rhs.take());
   974           return *this;
   975         }
   977       template <typename I>
   978       nsRefPtr<T>&
   979       operator=( already_AddRefed<I>&& rhs )
   980           // assign from |otherRefPtr.forget()|
   981         {
   982           assign_assuming_AddRef(rhs.take());
   983           return *this;
   984         }
   986       nsRefPtr<T>&
   987       operator=( const nsCOMPtr_helper& helper )
   988         {
   989           void* newRawPtr;
   990           if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
   991             newRawPtr = 0;
   992           assign_assuming_AddRef(static_cast<T*>(newRawPtr));
   993           return *this;
   994         }
   996       nsRefPtr<T>&
   997       operator=(nsRefPtr<T>&& aRefPtr)
   998       {
   999         assign_assuming_AddRef(aRefPtr.mRawPtr);
  1000         aRefPtr.mRawPtr = nullptr;
  1001         return *this;
  1004         // Other pointer operators
  1006       void
  1007       swap( nsRefPtr<T>& rhs )
  1008           // ...exchange ownership with |rhs|; can save a pair of refcount operations
  1010           T* temp = rhs.mRawPtr;
  1011           rhs.mRawPtr = mRawPtr;
  1012           mRawPtr = temp;
  1015       void
  1016       swap( T*& rhs )
  1017           // ...exchange ownership with |rhs|; can save a pair of refcount operations
  1019           T* temp = rhs;
  1020           rhs = mRawPtr;
  1021           mRawPtr = temp;
  1024       already_AddRefed<T>
  1025       forget()
  1026           // return the value of mRawPtr and null out mRawPtr. Useful for
  1027           // already_AddRefed return values.
  1029           T* temp = 0;
  1030           swap(temp);
  1031           return already_AddRefed<T>(temp);
  1034       template <typename I>
  1035       void
  1036       forget( I** rhs)
  1037           // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
  1038           // Useful to avoid unnecessary AddRef/Release pairs with "out"
  1039           // parameters where rhs bay be a T** or an I** where I is a base class
  1040           // of T.
  1042           NS_ASSERTION(rhs, "Null pointer passed to forget!");
  1043           *rhs = mRawPtr;
  1044           mRawPtr = 0;
  1047       T*
  1048       get() const
  1049           /*
  1050             Prefer the implicit conversion provided automatically by |operator T*() const|.
  1051             Use |get()| to resolve ambiguity or to get a castable pointer.
  1052           */
  1054           return const_cast<T*>(mRawPtr);
  1057       operator T*() const
  1058           /*
  1059             ...makes an |nsRefPtr| act like its underlying raw pointer type whenever it
  1060             is used in a context where a raw pointer is expected.  It is this operator
  1061             that makes an |nsRefPtr| substitutable for a raw pointer.
  1063             Prefer the implicit use of this operator to calling |get()|, except where
  1064             necessary to resolve ambiguity.
  1065           */
  1067           return get();
  1070       T*
  1071       operator->() const
  1073           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->().");
  1074           return get();
  1077       // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
  1078       // causes internal compiler errors for some MSVC versions.  (It's not
  1079       // clear to me whether it should be needed.)
  1080 #ifndef _MSC_VER
  1081       template <class U, class V>
  1082       U&
  1083       operator->*(U V::* aMember)
  1085           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->*().");
  1086           return get()->*aMember;
  1088 #endif
  1090       nsRefPtr<T>*
  1091       get_address()
  1092           // This is not intended to be used by clients.  See |address_of|
  1093           // below.
  1095           return this;
  1098       const nsRefPtr<T>*
  1099       get_address() const
  1100           // This is not intended to be used by clients.  See |address_of|
  1101           // below.
  1103           return this;
  1106     public:
  1107       T&
  1108       operator*() const
  1110           NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator*().");
  1111           return *get();
  1114       T**
  1115       StartAssignment()
  1117 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
  1118           return reinterpret_cast<T**>(begin_assignment());
  1119 #else
  1120           assign_assuming_AddRef(0);
  1121           return reinterpret_cast<T**>(&mRawPtr);
  1122 #endif
  1124   };
  1126 template <typename T>
  1127 inline void
  1128 ImplCycleCollectionUnlink(nsRefPtr<T>& aField)
  1130   aField = nullptr;
  1133 template <typename T>
  1134 inline void
  1135 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
  1136                             nsRefPtr<T>& aField,
  1137                             const char* aName,
  1138                             uint32_t aFlags = 0)
  1140   CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
  1143 template <class T>
  1144 inline
  1145 nsRefPtr<T>*
  1146 address_of( nsRefPtr<T>& aPtr )
  1148     return aPtr.get_address();
  1151 template <class T>
  1152 inline
  1153 const nsRefPtr<T>*
  1154 address_of( const nsRefPtr<T>& aPtr )
  1156     return aPtr.get_address();
  1159 template <class T>
  1160 class nsRefPtrGetterAddRefs
  1161     /*
  1162       ...
  1164       This class is designed to be used for anonymous temporary objects in the
  1165       argument list of calls that return COM interface pointers, e.g.,
  1167         nsRefPtr<IFoo> fooP;
  1168         ...->GetAddRefedPointer(getter_AddRefs(fooP))
  1170       DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
  1172       When initialized with a |nsRefPtr|, as in the example above, it returns
  1173       a |void**|, a |T**|, or an |nsISupports**| as needed, that the
  1174       outer call (|GetAddRefedPointer| in this case) can fill in.
  1176       This type should be a nested class inside |nsRefPtr<T>|.
  1177     */
  1179     public:
  1180       explicit
  1181       nsRefPtrGetterAddRefs( nsRefPtr<T>& aSmartPtr )
  1182           : mTargetSmartPtr(aSmartPtr)
  1184           // nothing else to do
  1187       operator void**()
  1189           return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
  1192       operator T**()
  1194           return mTargetSmartPtr.StartAssignment();
  1197       T*&
  1198       operator*()
  1200           return *(mTargetSmartPtr.StartAssignment());
  1203     private:
  1204       nsRefPtr<T>& mTargetSmartPtr;
  1205   };
  1207 template <class T>
  1208 inline
  1209 nsRefPtrGetterAddRefs<T>
  1210 getter_AddRefs( nsRefPtr<T>& aSmartPtr )
  1211     /*
  1212       Used around a |nsRefPtr| when 
  1213       ...makes the class |nsRefPtrGetterAddRefs<T>| invisible.
  1214     */
  1216     return nsRefPtrGetterAddRefs<T>(aSmartPtr);
  1221   // Comparing two |nsRefPtr|s
  1223 template <class T, class U>
  1224 inline
  1225 bool
  1226 operator==( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
  1228     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
  1232 template <class T, class U>
  1233 inline
  1234 bool
  1235 operator!=( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
  1237     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
  1241   // Comparing an |nsRefPtr| to a raw pointer
  1243 template <class T, class U>
  1244 inline
  1245 bool
  1246 operator==( const nsRefPtr<T>& lhs, const U* rhs )
  1248     return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
  1251 template <class T, class U>
  1252 inline
  1253 bool
  1254 operator==( const U* lhs, const nsRefPtr<T>& rhs )
  1256     return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
  1259 template <class T, class U>
  1260 inline
  1261 bool
  1262 operator!=( const nsRefPtr<T>& lhs, const U* rhs )
  1264     return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
  1267 template <class T, class U>
  1268 inline
  1269 bool
  1270 operator!=( const U* lhs, const nsRefPtr<T>& rhs )
  1272     return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
  1275   // To avoid ambiguities caused by the presence of builtin |operator==|s
  1276   // creating a situation where one of the |operator==| defined above
  1277   // has a better conversion for one argument and the builtin has a
  1278   // better conversion for the other argument, define additional
  1279   // |operator==| without the |const| on the raw pointer.
  1280   // See bug 65664 for details.
  1282 #ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
  1283 template <class T, class U>
  1284 inline
  1285 bool
  1286 operator==( const nsRefPtr<T>& lhs, U* rhs )
  1288     return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
  1291 template <class T, class U>
  1292 inline
  1293 bool
  1294 operator==( U* lhs, const nsRefPtr<T>& rhs )
  1296     return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
  1299 template <class T, class U>
  1300 inline
  1301 bool
  1302 operator!=( const nsRefPtr<T>& lhs, U* rhs )
  1304     return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
  1307 template <class T, class U>
  1308 inline
  1309 bool
  1310 operator!=( U* lhs, const nsRefPtr<T>& rhs )
  1312     return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
  1314 #endif
  1318   // Comparing an |nsRefPtr| to |0|
  1320 template <class T>
  1321 inline
  1322 bool
  1323 operator==( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
  1324     // specifically to allow |smartPtr == 0|
  1326     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
  1329 template <class T>
  1330 inline
  1331 bool
  1332 operator==( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
  1333     // specifically to allow |0 == smartPtr|
  1335     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
  1338 template <class T>
  1339 inline
  1340 bool
  1341 operator!=( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
  1342     // specifically to allow |smartPtr != 0|
  1344     return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
  1347 template <class T>
  1348 inline
  1349 bool
  1350 operator!=( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
  1351     // specifically to allow |0 != smartPtr|
  1353     return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
  1357 #ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
  1359   // We need to explicitly define comparison operators for `int'
  1360   // because the compiler is lame.
  1362 template <class T>
  1363 inline
  1364 bool
  1365 operator==( const nsRefPtr<T>& lhs, int rhs )
  1366     // specifically to allow |smartPtr == 0|
  1368     return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
  1371 template <class T>
  1372 inline
  1373 bool
  1374 operator==( int lhs, const nsRefPtr<T>& rhs )
  1375     // specifically to allow |0 == smartPtr|
  1377     return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
  1380 #endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
  1382 template <class SourceType, class DestinationType>
  1383 inline
  1384 nsresult
  1385 CallQueryInterface( nsRefPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr )
  1387     return CallQueryInterface(aSourcePtr.get(), aDestPtr);
  1390 /*****************************************************************************/
  1392 template<class T>
  1393 class nsQueryObject : public nsCOMPtr_helper
  1395 public:
  1396   nsQueryObject(T* aRawPtr)
  1397     : mRawPtr(aRawPtr) {}
  1399   virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
  1400     nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
  1401                               : NS_ERROR_NULL_POINTER;
  1402     return status;
  1404 private:
  1405   T* mRawPtr;
  1406 };
  1408 template<class T>
  1409 class nsQueryObjectWithError : public nsCOMPtr_helper
  1411 public:
  1412   nsQueryObjectWithError(T* aRawPtr, nsresult* aErrorPtr)
  1413     : mRawPtr(aRawPtr), mErrorPtr(aErrorPtr) {}
  1415   virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
  1416     nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
  1417                               : NS_ERROR_NULL_POINTER;
  1418     if (mErrorPtr)
  1419       *mErrorPtr = status;
  1420     return status;
  1422 private:
  1423   T* mRawPtr;
  1424   nsresult* mErrorPtr;
  1425 };
  1427 template<class T>
  1428 inline
  1429 nsQueryObject<T>
  1430 do_QueryObject(T* aRawPtr)
  1432   return nsQueryObject<T>(aRawPtr);
  1435 template<class T>
  1436 inline
  1437 nsQueryObject<T>
  1438 do_QueryObject(nsCOMPtr<T>& aRawPtr)
  1440   return nsQueryObject<T>(aRawPtr);
  1443 template<class T>
  1444 inline
  1445 nsQueryObject<T>
  1446 do_QueryObject(nsRefPtr<T>& aRawPtr)
  1448   return nsQueryObject<T>(aRawPtr);
  1451 template<class T>
  1452 inline
  1453 nsQueryObjectWithError<T>
  1454 do_QueryObject(T* aRawPtr, nsresult* aErrorPtr)
  1456   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
  1459 template<class T>
  1460 inline
  1461 nsQueryObjectWithError<T>
  1462 do_QueryObject(nsCOMPtr<T>& aRawPtr, nsresult* aErrorPtr)
  1464   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
  1467 template<class T>
  1468 inline
  1469 nsQueryObjectWithError<T>
  1470 do_QueryObject(nsRefPtr<T>& aRawPtr, nsresult* aErrorPtr)
  1472   return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
  1475 /*****************************************************************************/
  1477 #endif // !defined(nsAutoPtr_h___)

mercurial