xpcom/base/nsAutoPtr.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/base/nsAutoPtr.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1477 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsAutoPtr_h___
    1.10 +#define nsAutoPtr_h___
    1.11 +
    1.12 +#include "nsCOMPtr.h"
    1.13 +
    1.14 +#include "nsCycleCollectionNoteChild.h"
    1.15 +#include "mozilla/MemoryReporting.h"
    1.16 +
    1.17 +/*****************************************************************************/
    1.18 +
    1.19 +// template <class T> class nsAutoPtrGetterTransfers;
    1.20 +
    1.21 +template <class T>
    1.22 +class nsAutoPtr
    1.23 +  {
    1.24 +    private:
    1.25 +      void**
    1.26 +      begin_assignment()
    1.27 +        {
    1.28 +          assign(0);
    1.29 +          return reinterpret_cast<void**>(&mRawPtr);
    1.30 +        }
    1.31 +
    1.32 +      void
    1.33 +      assign( T* newPtr )
    1.34 +        {
    1.35 +          T* oldPtr = mRawPtr;
    1.36 +
    1.37 +          if (newPtr != nullptr && newPtr == oldPtr) {
    1.38 +            NS_RUNTIMEABORT("Logic flaw in the caller");
    1.39 +          }
    1.40 +
    1.41 +          mRawPtr = newPtr;
    1.42 +          delete oldPtr;
    1.43 +        }
    1.44 +
    1.45 +      // |class Ptr| helps us prevent implicit "copy construction"
    1.46 +      // through |operator T*() const| from a |const nsAutoPtr<T>|
    1.47 +      // because two implicit conversions in a row aren't allowed.
    1.48 +      // It still allows assignment from T* through implicit conversion
    1.49 +      // from |T*| to |nsAutoPtr<T>::Ptr|
    1.50 +      class Ptr
    1.51 +        {
    1.52 +          public:
    1.53 +            Ptr( T* aPtr )
    1.54 +                  : mPtr(aPtr)
    1.55 +              {
    1.56 +              }
    1.57 +
    1.58 +            operator T*() const
    1.59 +              {
    1.60 +                return mPtr;
    1.61 +              }
    1.62 +
    1.63 +          private:
    1.64 +            T* mPtr;
    1.65 +        };
    1.66 +
    1.67 +    private:
    1.68 +      T* mRawPtr;
    1.69 +
    1.70 +    public:
    1.71 +      typedef T element_type;
    1.72 +      
    1.73 +     ~nsAutoPtr()
    1.74 +        {
    1.75 +          delete mRawPtr;
    1.76 +        }
    1.77 +
    1.78 +        // Constructors
    1.79 +
    1.80 +      nsAutoPtr()
    1.81 +            : mRawPtr(0)
    1.82 +          // default constructor
    1.83 +        {
    1.84 +        }
    1.85 +
    1.86 +      nsAutoPtr( Ptr aRawPtr )
    1.87 +            : mRawPtr(aRawPtr)
    1.88 +          // construct from a raw pointer (of the right type)
    1.89 +        {
    1.90 +        }
    1.91 +
    1.92 +      // This constructor shouldn't exist; we should just use the &&
    1.93 +      // constructor.
    1.94 +      nsAutoPtr( nsAutoPtr<T>& aSmartPtr )
    1.95 +            : mRawPtr( aSmartPtr.forget() )
    1.96 +          // Construct by transferring ownership from another smart pointer.
    1.97 +        {
    1.98 +        }
    1.99 +
   1.100 +      nsAutoPtr( nsAutoPtr<T>&& aSmartPtr )
   1.101 +            : mRawPtr( aSmartPtr.forget() )
   1.102 +          // Construct by transferring ownership from another smart pointer.
   1.103 +        {
   1.104 +        }
   1.105 +
   1.106 +        // Assignment operators
   1.107 +
   1.108 +      nsAutoPtr<T>&
   1.109 +      operator=( T* rhs )
   1.110 +          // assign from a raw pointer (of the right type)
   1.111 +        {
   1.112 +          assign(rhs);
   1.113 +          return *this;
   1.114 +        }
   1.115 +
   1.116 +      nsAutoPtr<T>& operator=( nsAutoPtr<T>& rhs )
   1.117 +          // assign by transferring ownership from another smart pointer.
   1.118 +        {
   1.119 +          assign(rhs.forget());
   1.120 +          return *this;
   1.121 +        }
   1.122 +
   1.123 +        // Other pointer operators
   1.124 +
   1.125 +      T*
   1.126 +      get() const
   1.127 +          /*
   1.128 +            Prefer the implicit conversion provided automatically by
   1.129 +            |operator T*() const|.  Use |get()| _only_ to resolve
   1.130 +            ambiguity.
   1.131 +          */
   1.132 +        {
   1.133 +          return mRawPtr;
   1.134 +        }
   1.135 +
   1.136 +      operator T*() const
   1.137 +          /*
   1.138 +            ...makes an |nsAutoPtr| act like its underlying raw pointer
   1.139 +            type  whenever it is used in a context where a raw pointer
   1.140 +            is expected.  It is this operator that makes an |nsAutoPtr|
   1.141 +            substitutable for a raw pointer.
   1.142 +
   1.143 +            Prefer the implicit use of this operator to calling |get()|,
   1.144 +            except where necessary to resolve ambiguity.
   1.145 +          */
   1.146 +        {
   1.147 +          return get();
   1.148 +        }
   1.149 +
   1.150 +      T*
   1.151 +      forget()
   1.152 +        {
   1.153 +          T* temp = mRawPtr;
   1.154 +          mRawPtr = 0;
   1.155 +          return temp;
   1.156 +        }
   1.157 +
   1.158 +      T*
   1.159 +      operator->() const
   1.160 +        {
   1.161 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->().");
   1.162 +          return get();
   1.163 +        }
   1.164 +
   1.165 +      // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
   1.166 +      // causes internal compiler errors for some MSVC versions.  (It's not
   1.167 +      // clear to me whether it should be needed.)
   1.168 +#ifndef _MSC_VER
   1.169 +      template <class U, class V>
   1.170 +      U&
   1.171 +      operator->*(U V::* aMember)
   1.172 +        {
   1.173 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator->*().");
   1.174 +          return get()->*aMember;
   1.175 +        }
   1.176 +#endif
   1.177 +
   1.178 +      nsAutoPtr<T>*
   1.179 +      get_address()
   1.180 +          // This is not intended to be used by clients.  See |address_of|
   1.181 +          // below.
   1.182 +        {
   1.183 +          return this;
   1.184 +        }
   1.185 +
   1.186 +      const nsAutoPtr<T>*
   1.187 +      get_address() const
   1.188 +          // This is not intended to be used by clients.  See |address_of|
   1.189 +          // below.
   1.190 +        {
   1.191 +          return this;
   1.192 +        }
   1.193 +
   1.194 +    public:
   1.195 +      T&
   1.196 +      operator*() const
   1.197 +        {
   1.198 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoPtr with operator*().");
   1.199 +          return *get();
   1.200 +        }
   1.201 +
   1.202 +      T**
   1.203 +      StartAssignment()
   1.204 +        {
   1.205 +#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
   1.206 +          return reinterpret_cast<T**>(begin_assignment());
   1.207 +#else
   1.208 +          assign(0);
   1.209 +          return reinterpret_cast<T**>(&mRawPtr);
   1.210 +#endif
   1.211 +        }
   1.212 +  };
   1.213 +
   1.214 +template <class T>
   1.215 +inline
   1.216 +nsAutoPtr<T>*
   1.217 +address_of( nsAutoPtr<T>& aPtr )
   1.218 +  {
   1.219 +    return aPtr.get_address();
   1.220 +  }
   1.221 +
   1.222 +template <class T>
   1.223 +inline
   1.224 +const nsAutoPtr<T>*
   1.225 +address_of( const nsAutoPtr<T>& aPtr )
   1.226 +  {
   1.227 +    return aPtr.get_address();
   1.228 +  }
   1.229 +
   1.230 +template <class T>
   1.231 +class nsAutoPtrGetterTransfers
   1.232 +    /*
   1.233 +      ...
   1.234 +
   1.235 +      This class is designed to be used for anonymous temporary objects in the
   1.236 +      argument list of calls that return COM interface pointers, e.g.,
   1.237 +
   1.238 +        nsAutoPtr<IFoo> fooP;
   1.239 +        ...->GetTransferedPointer(getter_Transfers(fooP))
   1.240 +
   1.241 +      DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
   1.242 +
   1.243 +      When initialized with a |nsAutoPtr|, as in the example above, it returns
   1.244 +      a |void**|, a |T**|, or an |nsISupports**| as needed, that the
   1.245 +      outer call (|GetTransferedPointer| in this case) can fill in.
   1.246 +
   1.247 +      This type should be a nested class inside |nsAutoPtr<T>|.
   1.248 +    */
   1.249 +  {
   1.250 +    public:
   1.251 +      explicit
   1.252 +      nsAutoPtrGetterTransfers( nsAutoPtr<T>& aSmartPtr )
   1.253 +          : mTargetSmartPtr(aSmartPtr)
   1.254 +        {
   1.255 +          // nothing else to do
   1.256 +        }
   1.257 +
   1.258 +      operator void**()
   1.259 +        {
   1.260 +          return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
   1.261 +        }
   1.262 +
   1.263 +      operator T**()
   1.264 +        {
   1.265 +          return mTargetSmartPtr.StartAssignment();
   1.266 +        }
   1.267 +
   1.268 +      T*&
   1.269 +      operator*()
   1.270 +        {
   1.271 +          return *(mTargetSmartPtr.StartAssignment());
   1.272 +        }
   1.273 +
   1.274 +    private:
   1.275 +      nsAutoPtr<T>& mTargetSmartPtr;
   1.276 +  };
   1.277 +
   1.278 +template <class T>
   1.279 +inline
   1.280 +nsAutoPtrGetterTransfers<T>
   1.281 +getter_Transfers( nsAutoPtr<T>& aSmartPtr )
   1.282 +    /*
   1.283 +      Used around a |nsAutoPtr| when 
   1.284 +      ...makes the class |nsAutoPtrGetterTransfers<T>| invisible.
   1.285 +    */
   1.286 +  {
   1.287 +    return nsAutoPtrGetterTransfers<T>(aSmartPtr);
   1.288 +  }
   1.289 +
   1.290 +
   1.291 +
   1.292 +  // Comparing two |nsAutoPtr|s
   1.293 +
   1.294 +template <class T, class U>
   1.295 +inline
   1.296 +bool
   1.297 +operator==( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
   1.298 +  {
   1.299 +    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
   1.300 +  }
   1.301 +
   1.302 +
   1.303 +template <class T, class U>
   1.304 +inline
   1.305 +bool
   1.306 +operator!=( const nsAutoPtr<T>& lhs, const nsAutoPtr<U>& rhs )
   1.307 +  {
   1.308 +    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
   1.309 +  }
   1.310 +
   1.311 +
   1.312 +  // Comparing an |nsAutoPtr| to a raw pointer
   1.313 +
   1.314 +template <class T, class U>
   1.315 +inline
   1.316 +bool
   1.317 +operator==( const nsAutoPtr<T>& lhs, const U* rhs )
   1.318 +  {
   1.319 +    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
   1.320 +  }
   1.321 +
   1.322 +template <class T, class U>
   1.323 +inline
   1.324 +bool
   1.325 +operator==( const U* lhs, const nsAutoPtr<T>& rhs )
   1.326 +  {
   1.327 +    return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   1.328 +  }
   1.329 +
   1.330 +template <class T, class U>
   1.331 +inline
   1.332 +bool
   1.333 +operator!=( const nsAutoPtr<T>& lhs, const U* rhs )
   1.334 +  {
   1.335 +    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
   1.336 +  }
   1.337 +
   1.338 +template <class T, class U>
   1.339 +inline
   1.340 +bool
   1.341 +operator!=( const U* lhs, const nsAutoPtr<T>& rhs )
   1.342 +  {
   1.343 +    return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   1.344 +  }
   1.345 +
   1.346 +  // To avoid ambiguities caused by the presence of builtin |operator==|s
   1.347 +  // creating a situation where one of the |operator==| defined above
   1.348 +  // has a better conversion for one argument and the builtin has a
   1.349 +  // better conversion for the other argument, define additional
   1.350 +  // |operator==| without the |const| on the raw pointer.
   1.351 +  // See bug 65664 for details.
   1.352 +
   1.353 +#ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
   1.354 +template <class T, class U>
   1.355 +inline
   1.356 +bool
   1.357 +operator==( const nsAutoPtr<T>& lhs, U* rhs )
   1.358 +  {
   1.359 +    return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
   1.360 +  }
   1.361 +
   1.362 +template <class T, class U>
   1.363 +inline
   1.364 +bool
   1.365 +operator==( U* lhs, const nsAutoPtr<T>& rhs )
   1.366 +  {
   1.367 +    return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   1.368 +  }
   1.369 +
   1.370 +template <class T, class U>
   1.371 +inline
   1.372 +bool
   1.373 +operator!=( const nsAutoPtr<T>& lhs, U* rhs )
   1.374 +  {
   1.375 +    return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
   1.376 +  }
   1.377 +
   1.378 +template <class T, class U>
   1.379 +inline
   1.380 +bool
   1.381 +operator!=( U* lhs, const nsAutoPtr<T>& rhs )
   1.382 +  {
   1.383 +    return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   1.384 +  }
   1.385 +#endif
   1.386 +
   1.387 +
   1.388 +
   1.389 +  // Comparing an |nsAutoPtr| to |0|
   1.390 +
   1.391 +template <class T>
   1.392 +inline
   1.393 +bool
   1.394 +operator==( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
   1.395 +    // specifically to allow |smartPtr == 0|
   1.396 +  {
   1.397 +    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   1.398 +  }
   1.399 +
   1.400 +template <class T>
   1.401 +inline
   1.402 +bool
   1.403 +operator==( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
   1.404 +    // specifically to allow |0 == smartPtr|
   1.405 +  {
   1.406 +    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   1.407 +  }
   1.408 +
   1.409 +template <class T>
   1.410 +inline
   1.411 +bool
   1.412 +operator!=( const nsAutoPtr<T>& lhs, NSCAP_Zero* rhs )
   1.413 +    // specifically to allow |smartPtr != 0|
   1.414 +  {
   1.415 +    return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
   1.416 +  }
   1.417 +
   1.418 +template <class T>
   1.419 +inline
   1.420 +bool
   1.421 +operator!=( NSCAP_Zero* lhs, const nsAutoPtr<T>& rhs )
   1.422 +    // specifically to allow |0 != smartPtr|
   1.423 +  {
   1.424 +    return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
   1.425 +  }
   1.426 +
   1.427 +
   1.428 +#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
   1.429 +
   1.430 +  // We need to explicitly define comparison operators for `int'
   1.431 +  // because the compiler is lame.
   1.432 +
   1.433 +template <class T>
   1.434 +inline
   1.435 +bool
   1.436 +operator==( const nsAutoPtr<T>& lhs, int rhs )
   1.437 +    // specifically to allow |smartPtr == 0|
   1.438 +  {
   1.439 +    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   1.440 +  }
   1.441 +
   1.442 +template <class T>
   1.443 +inline
   1.444 +bool
   1.445 +operator==( int lhs, const nsAutoPtr<T>& rhs )
   1.446 +    // specifically to allow |0 == smartPtr|
   1.447 +  {
   1.448 +    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   1.449 +  }
   1.450 +
   1.451 +#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
   1.452 +
   1.453 +/*****************************************************************************/
   1.454 +
   1.455 +// template <class T> class nsAutoArrayPtrGetterTransfers;
   1.456 +
   1.457 +template <class T>
   1.458 +class nsAutoArrayPtr
   1.459 +  {
   1.460 +    private:
   1.461 +      void**
   1.462 +      begin_assignment()
   1.463 +        {
   1.464 +          assign(0);
   1.465 +          return reinterpret_cast<void**>(&mRawPtr);
   1.466 +        }
   1.467 +
   1.468 +      void
   1.469 +      assign( T* newPtr )
   1.470 +        {
   1.471 +          T* oldPtr = mRawPtr;
   1.472 +          mRawPtr = newPtr;
   1.473 +          delete [] oldPtr;
   1.474 +        }
   1.475 +
   1.476 +    private:
   1.477 +      T* mRawPtr;
   1.478 +
   1.479 +    public:
   1.480 +      typedef T element_type;
   1.481 +      
   1.482 +     ~nsAutoArrayPtr()
   1.483 +        {
   1.484 +          delete [] mRawPtr;
   1.485 +        }
   1.486 +
   1.487 +        // Constructors
   1.488 +
   1.489 +      nsAutoArrayPtr()
   1.490 +            : mRawPtr(0)
   1.491 +          // default constructor
   1.492 +        {
   1.493 +        }
   1.494 +
   1.495 +      nsAutoArrayPtr( T* aRawPtr )
   1.496 +            : mRawPtr(aRawPtr)
   1.497 +          // construct from a raw pointer (of the right type)
   1.498 +        {
   1.499 +        }
   1.500 +
   1.501 +      nsAutoArrayPtr( nsAutoArrayPtr<T>& aSmartPtr )
   1.502 +            : mRawPtr( aSmartPtr.forget() )
   1.503 +          // Construct by transferring ownership from another smart pointer.
   1.504 +        {
   1.505 +        }
   1.506 +
   1.507 +
   1.508 +        // Assignment operators
   1.509 +
   1.510 +      nsAutoArrayPtr<T>&
   1.511 +      operator=( T* rhs )
   1.512 +          // assign from a raw pointer (of the right type)
   1.513 +        {
   1.514 +          assign(rhs);
   1.515 +          return *this;
   1.516 +        }
   1.517 +
   1.518 +      nsAutoArrayPtr<T>& operator=( nsAutoArrayPtr<T>& rhs )
   1.519 +          // assign by transferring ownership from another smart pointer.
   1.520 +        {
   1.521 +          assign(rhs.forget());
   1.522 +          return *this;
   1.523 +        }
   1.524 +
   1.525 +        // Other pointer operators
   1.526 +
   1.527 +      T*
   1.528 +      get() const
   1.529 +          /*
   1.530 +            Prefer the implicit conversion provided automatically by
   1.531 +            |operator T*() const|.  Use |get()| _only_ to resolve
   1.532 +            ambiguity.
   1.533 +          */
   1.534 +        {
   1.535 +          return mRawPtr;
   1.536 +        }
   1.537 +
   1.538 +      operator T*() const
   1.539 +          /*
   1.540 +            ...makes an |nsAutoArrayPtr| act like its underlying raw pointer
   1.541 +            type  whenever it is used in a context where a raw pointer
   1.542 +            is expected.  It is this operator that makes an |nsAutoArrayPtr|
   1.543 +            substitutable for a raw pointer.
   1.544 +
   1.545 +            Prefer the implicit use of this operator to calling |get()|,
   1.546 +            except where necessary to resolve ambiguity.
   1.547 +          */
   1.548 +        {
   1.549 +          return get();
   1.550 +        }
   1.551 +
   1.552 +      T*
   1.553 +      forget()
   1.554 +        {
   1.555 +          T* temp = mRawPtr;
   1.556 +          mRawPtr = 0;
   1.557 +          return temp;
   1.558 +        }
   1.559 +
   1.560 +      T*
   1.561 +      operator->() const
   1.562 +        {
   1.563 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoArrayPtr with operator->().");
   1.564 +          return get();
   1.565 +        }
   1.566 +
   1.567 +      nsAutoArrayPtr<T>*
   1.568 +      get_address()
   1.569 +          // This is not intended to be used by clients.  See |address_of|
   1.570 +          // below.
   1.571 +        {
   1.572 +          return this;
   1.573 +        }
   1.574 +
   1.575 +      const nsAutoArrayPtr<T>*
   1.576 +      get_address() const
   1.577 +          // This is not intended to be used by clients.  See |address_of|
   1.578 +          // below.
   1.579 +        {
   1.580 +          return this;
   1.581 +        }
   1.582 +
   1.583 +    public:
   1.584 +      T&
   1.585 +      operator*() const
   1.586 +        {
   1.587 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsAutoArrayPtr with operator*().");
   1.588 +          return *get();
   1.589 +        }
   1.590 +
   1.591 +      T**
   1.592 +      StartAssignment()
   1.593 +        {
   1.594 +#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
   1.595 +          return reinterpret_cast<T**>(begin_assignment());
   1.596 +#else
   1.597 +          assign(0);
   1.598 +          return reinterpret_cast<T**>(&mRawPtr);
   1.599 +#endif
   1.600 +        }
   1.601 +
   1.602 +      size_t
   1.603 +      SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   1.604 +        {
   1.605 +          return aMallocSizeOf(mRawPtr);
   1.606 +        }
   1.607 +
   1.608 +      size_t
   1.609 +      SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   1.610 +        {
   1.611 +          return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   1.612 +        }
   1.613 +  };
   1.614 +
   1.615 +template <class T>
   1.616 +inline
   1.617 +nsAutoArrayPtr<T>*
   1.618 +address_of( nsAutoArrayPtr<T>& aPtr )
   1.619 +  {
   1.620 +    return aPtr.get_address();
   1.621 +  }
   1.622 +
   1.623 +template <class T>
   1.624 +inline
   1.625 +const nsAutoArrayPtr<T>*
   1.626 +address_of( const nsAutoArrayPtr<T>& aPtr )
   1.627 +  {
   1.628 +    return aPtr.get_address();
   1.629 +  }
   1.630 +
   1.631 +template <class T>
   1.632 +class nsAutoArrayPtrGetterTransfers
   1.633 +    /*
   1.634 +      ...
   1.635 +
   1.636 +      This class is designed to be used for anonymous temporary objects in the
   1.637 +      argument list of calls that return COM interface pointers, e.g.,
   1.638 +
   1.639 +        nsAutoArrayPtr<IFoo> fooP;
   1.640 +        ...->GetTransferedPointer(getter_Transfers(fooP))
   1.641 +
   1.642 +      DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
   1.643 +
   1.644 +      When initialized with a |nsAutoArrayPtr|, as in the example above, it returns
   1.645 +      a |void**|, a |T**|, or an |nsISupports**| as needed, that the
   1.646 +      outer call (|GetTransferedPointer| in this case) can fill in.
   1.647 +
   1.648 +      This type should be a nested class inside |nsAutoArrayPtr<T>|.
   1.649 +    */
   1.650 +  {
   1.651 +    public:
   1.652 +      explicit
   1.653 +      nsAutoArrayPtrGetterTransfers( nsAutoArrayPtr<T>& aSmartPtr )
   1.654 +          : mTargetSmartPtr(aSmartPtr)
   1.655 +        {
   1.656 +          // nothing else to do
   1.657 +        }
   1.658 +
   1.659 +      operator void**()
   1.660 +        {
   1.661 +          return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
   1.662 +        }
   1.663 +
   1.664 +      operator T**()
   1.665 +        {
   1.666 +          return mTargetSmartPtr.StartAssignment();
   1.667 +        }
   1.668 +
   1.669 +      T*&
   1.670 +      operator*()
   1.671 +        {
   1.672 +          return *(mTargetSmartPtr.StartAssignment());
   1.673 +        }
   1.674 +
   1.675 +    private:
   1.676 +      nsAutoArrayPtr<T>& mTargetSmartPtr;
   1.677 +  };
   1.678 +
   1.679 +template <class T>
   1.680 +inline
   1.681 +nsAutoArrayPtrGetterTransfers<T>
   1.682 +getter_Transfers( nsAutoArrayPtr<T>& aSmartPtr )
   1.683 +    /*
   1.684 +      Used around a |nsAutoArrayPtr| when 
   1.685 +      ...makes the class |nsAutoArrayPtrGetterTransfers<T>| invisible.
   1.686 +    */
   1.687 +  {
   1.688 +    return nsAutoArrayPtrGetterTransfers<T>(aSmartPtr);
   1.689 +  }
   1.690 +
   1.691 +
   1.692 +
   1.693 +  // Comparing two |nsAutoArrayPtr|s
   1.694 +
   1.695 +template <class T, class U>
   1.696 +inline
   1.697 +bool
   1.698 +operator==( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
   1.699 +  {
   1.700 +    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
   1.701 +  }
   1.702 +
   1.703 +
   1.704 +template <class T, class U>
   1.705 +inline
   1.706 +bool
   1.707 +operator!=( const nsAutoArrayPtr<T>& lhs, const nsAutoArrayPtr<U>& rhs )
   1.708 +  {
   1.709 +    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
   1.710 +  }
   1.711 +
   1.712 +
   1.713 +  // Comparing an |nsAutoArrayPtr| to a raw pointer
   1.714 +
   1.715 +template <class T, class U>
   1.716 +inline
   1.717 +bool
   1.718 +operator==( const nsAutoArrayPtr<T>& lhs, const U* rhs )
   1.719 +  {
   1.720 +    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
   1.721 +  }
   1.722 +
   1.723 +template <class T, class U>
   1.724 +inline
   1.725 +bool
   1.726 +operator==( const U* lhs, const nsAutoArrayPtr<T>& rhs )
   1.727 +  {
   1.728 +    return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   1.729 +  }
   1.730 +
   1.731 +template <class T, class U>
   1.732 +inline
   1.733 +bool
   1.734 +operator!=( const nsAutoArrayPtr<T>& lhs, const U* rhs )
   1.735 +  {
   1.736 +    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
   1.737 +  }
   1.738 +
   1.739 +template <class T, class U>
   1.740 +inline
   1.741 +bool
   1.742 +operator!=( const U* lhs, const nsAutoArrayPtr<T>& rhs )
   1.743 +  {
   1.744 +    return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   1.745 +  }
   1.746 +
   1.747 +  // To avoid ambiguities caused by the presence of builtin |operator==|s
   1.748 +  // creating a situation where one of the |operator==| defined above
   1.749 +  // has a better conversion for one argument and the builtin has a
   1.750 +  // better conversion for the other argument, define additional
   1.751 +  // |operator==| without the |const| on the raw pointer.
   1.752 +  // See bug 65664 for details.
   1.753 +
   1.754 +#ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
   1.755 +template <class T, class U>
   1.756 +inline
   1.757 +bool
   1.758 +operator==( const nsAutoArrayPtr<T>& lhs, U* rhs )
   1.759 +  {
   1.760 +    return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
   1.761 +  }
   1.762 +
   1.763 +template <class T, class U>
   1.764 +inline
   1.765 +bool
   1.766 +operator==( U* lhs, const nsAutoArrayPtr<T>& rhs )
   1.767 +  {
   1.768 +    return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
   1.769 +  }
   1.770 +
   1.771 +template <class T, class U>
   1.772 +inline
   1.773 +bool
   1.774 +operator!=( const nsAutoArrayPtr<T>& lhs, U* rhs )
   1.775 +  {
   1.776 +    return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
   1.777 +  }
   1.778 +
   1.779 +template <class T, class U>
   1.780 +inline
   1.781 +bool
   1.782 +operator!=( U* lhs, const nsAutoArrayPtr<T>& rhs )
   1.783 +  {
   1.784 +    return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
   1.785 +  }
   1.786 +#endif
   1.787 +
   1.788 +
   1.789 +
   1.790 +  // Comparing an |nsAutoArrayPtr| to |0|
   1.791 +
   1.792 +template <class T>
   1.793 +inline
   1.794 +bool
   1.795 +operator==( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
   1.796 +    // specifically to allow |smartPtr == 0|
   1.797 +  {
   1.798 +    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   1.799 +  }
   1.800 +
   1.801 +template <class T>
   1.802 +inline
   1.803 +bool
   1.804 +operator==( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
   1.805 +    // specifically to allow |0 == smartPtr|
   1.806 +  {
   1.807 +    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   1.808 +  }
   1.809 +
   1.810 +template <class T>
   1.811 +inline
   1.812 +bool
   1.813 +operator!=( const nsAutoArrayPtr<T>& lhs, NSCAP_Zero* rhs )
   1.814 +    // specifically to allow |smartPtr != 0|
   1.815 +  {
   1.816 +    return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
   1.817 +  }
   1.818 +
   1.819 +template <class T>
   1.820 +inline
   1.821 +bool
   1.822 +operator!=( NSCAP_Zero* lhs, const nsAutoArrayPtr<T>& rhs )
   1.823 +    // specifically to allow |0 != smartPtr|
   1.824 +  {
   1.825 +    return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
   1.826 +  }
   1.827 +
   1.828 +
   1.829 +#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
   1.830 +
   1.831 +  // We need to explicitly define comparison operators for `int'
   1.832 +  // because the compiler is lame.
   1.833 +
   1.834 +template <class T>
   1.835 +inline
   1.836 +bool
   1.837 +operator==( const nsAutoArrayPtr<T>& lhs, int rhs )
   1.838 +    // specifically to allow |smartPtr == 0|
   1.839 +  {
   1.840 +    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
   1.841 +  }
   1.842 +
   1.843 +template <class T>
   1.844 +inline
   1.845 +bool
   1.846 +operator==( int lhs, const nsAutoArrayPtr<T>& rhs )
   1.847 +    // specifically to allow |0 == smartPtr|
   1.848 +  {
   1.849 +    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
   1.850 +  }
   1.851 +
   1.852 +#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
   1.853 +
   1.854 +
   1.855 +/*****************************************************************************/
   1.856 +
   1.857 +// template <class T> class nsRefPtrGetterAddRefs;
   1.858 +
   1.859 +template <class T>
   1.860 +class nsRefPtr
   1.861 +  {
   1.862 +    private:
   1.863 +
   1.864 +      void
   1.865 +      assign_with_AddRef( T* rawPtr )
   1.866 +        {
   1.867 +          if ( rawPtr )
   1.868 +            rawPtr->AddRef();
   1.869 +          assign_assuming_AddRef(rawPtr);
   1.870 +        }
   1.871 +
   1.872 +      void**
   1.873 +      begin_assignment()
   1.874 +        {
   1.875 +          assign_assuming_AddRef(0);
   1.876 +          return reinterpret_cast<void**>(&mRawPtr);
   1.877 +        }
   1.878 +
   1.879 +      void
   1.880 +      assign_assuming_AddRef( T* newPtr )
   1.881 +        {
   1.882 +          T* oldPtr = mRawPtr;
   1.883 +          mRawPtr = newPtr;
   1.884 +          if ( oldPtr )
   1.885 +            oldPtr->Release();
   1.886 +        }
   1.887 +
   1.888 +    private:
   1.889 +      T* mRawPtr;
   1.890 +
   1.891 +    public:
   1.892 +      typedef T element_type;
   1.893 +      
   1.894 +     ~nsRefPtr()
   1.895 +        {
   1.896 +          if ( mRawPtr )
   1.897 +            mRawPtr->Release();
   1.898 +        }
   1.899 +
   1.900 +        // Constructors
   1.901 +
   1.902 +      nsRefPtr()
   1.903 +            : mRawPtr(0)
   1.904 +          // default constructor
   1.905 +        {
   1.906 +        }
   1.907 +
   1.908 +      nsRefPtr(const nsRefPtr<T>& aSmartPtr)
   1.909 +            : mRawPtr(aSmartPtr.mRawPtr)
   1.910 +          // copy-constructor
   1.911 +        {
   1.912 +          if ( mRawPtr )
   1.913 +            mRawPtr->AddRef();
   1.914 +        }
   1.915 +
   1.916 +      nsRefPtr(nsRefPtr<T>&& aRefPtr)
   1.917 +            : mRawPtr(aRefPtr.mRawPtr)
   1.918 +        {
   1.919 +          aRefPtr.mRawPtr = nullptr;
   1.920 +        }
   1.921 +
   1.922 +      // construct from a raw pointer (of the right type)
   1.923 +
   1.924 +      nsRefPtr(T* aRawPtr)
   1.925 +        : mRawPtr(aRawPtr)
   1.926 +        {
   1.927 +          if ( mRawPtr )
   1.928 +            mRawPtr->AddRef();
   1.929 +        }
   1.930 +
   1.931 +      template <typename I>
   1.932 +      nsRefPtr( already_AddRefed<I>& aSmartPtr )
   1.933 +            : mRawPtr(aSmartPtr.take())
   1.934 +          // construct from |already_AddRefed|
   1.935 +        {
   1.936 +        }
   1.937 +
   1.938 +      template <typename I>
   1.939 +      nsRefPtr( already_AddRefed<I>&& aSmartPtr )
   1.940 +            : mRawPtr(aSmartPtr.take())
   1.941 +          // construct from |otherRefPtr.forget()|
   1.942 +        {
   1.943 +        }
   1.944 +
   1.945 +      nsRefPtr( const nsCOMPtr_helper& helper )
   1.946 +        {
   1.947 +          void* newRawPtr;
   1.948 +          if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
   1.949 +            newRawPtr = 0;
   1.950 +          mRawPtr = static_cast<T*>(newRawPtr);
   1.951 +        }
   1.952 +
   1.953 +        // Assignment operators
   1.954 +
   1.955 +      nsRefPtr<T>&
   1.956 +      operator=(const nsRefPtr<T>& rhs)
   1.957 +          // copy assignment operator
   1.958 +        {
   1.959 +          assign_with_AddRef(rhs.mRawPtr);
   1.960 +          return *this;
   1.961 +        }
   1.962 +
   1.963 +      nsRefPtr<T>&
   1.964 +      operator=( T* rhs )
   1.965 +          // assign from a raw pointer (of the right type)
   1.966 +        {
   1.967 +          assign_with_AddRef(rhs);
   1.968 +          return *this;
   1.969 +        }
   1.970 +
   1.971 +      template <typename I>
   1.972 +      nsRefPtr<T>&
   1.973 +      operator=( already_AddRefed<I>& rhs )
   1.974 +          // assign from |already_AddRefed|
   1.975 +        {
   1.976 +          assign_assuming_AddRef(rhs.take());
   1.977 +          return *this;
   1.978 +        }
   1.979 +
   1.980 +      template <typename I>
   1.981 +      nsRefPtr<T>&
   1.982 +      operator=( already_AddRefed<I>&& rhs )
   1.983 +          // assign from |otherRefPtr.forget()|
   1.984 +        {
   1.985 +          assign_assuming_AddRef(rhs.take());
   1.986 +          return *this;
   1.987 +        }
   1.988 +
   1.989 +      nsRefPtr<T>&
   1.990 +      operator=( const nsCOMPtr_helper& helper )
   1.991 +        {
   1.992 +          void* newRawPtr;
   1.993 +          if (NS_FAILED(helper(NS_GET_TEMPLATE_IID(T), &newRawPtr)))
   1.994 +            newRawPtr = 0;
   1.995 +          assign_assuming_AddRef(static_cast<T*>(newRawPtr));
   1.996 +          return *this;
   1.997 +        }
   1.998 +
   1.999 +      nsRefPtr<T>&
  1.1000 +      operator=(nsRefPtr<T>&& aRefPtr)
  1.1001 +      {
  1.1002 +        assign_assuming_AddRef(aRefPtr.mRawPtr);
  1.1003 +        aRefPtr.mRawPtr = nullptr;
  1.1004 +        return *this;
  1.1005 +      }
  1.1006 +
  1.1007 +        // Other pointer operators
  1.1008 +
  1.1009 +      void
  1.1010 +      swap( nsRefPtr<T>& rhs )
  1.1011 +          // ...exchange ownership with |rhs|; can save a pair of refcount operations
  1.1012 +        {
  1.1013 +          T* temp = rhs.mRawPtr;
  1.1014 +          rhs.mRawPtr = mRawPtr;
  1.1015 +          mRawPtr = temp;
  1.1016 +        }
  1.1017 +
  1.1018 +      void
  1.1019 +      swap( T*& rhs )
  1.1020 +          // ...exchange ownership with |rhs|; can save a pair of refcount operations
  1.1021 +        {
  1.1022 +          T* temp = rhs;
  1.1023 +          rhs = mRawPtr;
  1.1024 +          mRawPtr = temp;
  1.1025 +        }
  1.1026 +
  1.1027 +      already_AddRefed<T>
  1.1028 +      forget()
  1.1029 +          // return the value of mRawPtr and null out mRawPtr. Useful for
  1.1030 +          // already_AddRefed return values.
  1.1031 +        {
  1.1032 +          T* temp = 0;
  1.1033 +          swap(temp);
  1.1034 +          return already_AddRefed<T>(temp);
  1.1035 +        }
  1.1036 +
  1.1037 +      template <typename I>
  1.1038 +      void
  1.1039 +      forget( I** rhs)
  1.1040 +          // Set the target of rhs to the value of mRawPtr and null out mRawPtr.
  1.1041 +          // Useful to avoid unnecessary AddRef/Release pairs with "out"
  1.1042 +          // parameters where rhs bay be a T** or an I** where I is a base class
  1.1043 +          // of T.
  1.1044 +        {
  1.1045 +          NS_ASSERTION(rhs, "Null pointer passed to forget!");
  1.1046 +          *rhs = mRawPtr;
  1.1047 +          mRawPtr = 0;
  1.1048 +        }
  1.1049 +
  1.1050 +      T*
  1.1051 +      get() const
  1.1052 +          /*
  1.1053 +            Prefer the implicit conversion provided automatically by |operator T*() const|.
  1.1054 +            Use |get()| to resolve ambiguity or to get a castable pointer.
  1.1055 +          */
  1.1056 +        {
  1.1057 +          return const_cast<T*>(mRawPtr);
  1.1058 +        }
  1.1059 +
  1.1060 +      operator T*() const
  1.1061 +          /*
  1.1062 +            ...makes an |nsRefPtr| act like its underlying raw pointer type whenever it
  1.1063 +            is used in a context where a raw pointer is expected.  It is this operator
  1.1064 +            that makes an |nsRefPtr| substitutable for a raw pointer.
  1.1065 +
  1.1066 +            Prefer the implicit use of this operator to calling |get()|, except where
  1.1067 +            necessary to resolve ambiguity.
  1.1068 +          */
  1.1069 +        {
  1.1070 +          return get();
  1.1071 +        }
  1.1072 +
  1.1073 +      T*
  1.1074 +      operator->() const
  1.1075 +        {
  1.1076 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->().");
  1.1077 +          return get();
  1.1078 +        }
  1.1079 +
  1.1080 +      // This operator is needed for gcc <= 4.0.* and for Sun Studio; it
  1.1081 +      // causes internal compiler errors for some MSVC versions.  (It's not
  1.1082 +      // clear to me whether it should be needed.)
  1.1083 +#ifndef _MSC_VER
  1.1084 +      template <class U, class V>
  1.1085 +      U&
  1.1086 +      operator->*(U V::* aMember)
  1.1087 +        {
  1.1088 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->*().");
  1.1089 +          return get()->*aMember;
  1.1090 +        }
  1.1091 +#endif
  1.1092 +
  1.1093 +      nsRefPtr<T>*
  1.1094 +      get_address()
  1.1095 +          // This is not intended to be used by clients.  See |address_of|
  1.1096 +          // below.
  1.1097 +        {
  1.1098 +          return this;
  1.1099 +        }
  1.1100 +
  1.1101 +      const nsRefPtr<T>*
  1.1102 +      get_address() const
  1.1103 +          // This is not intended to be used by clients.  See |address_of|
  1.1104 +          // below.
  1.1105 +        {
  1.1106 +          return this;
  1.1107 +        }
  1.1108 +
  1.1109 +    public:
  1.1110 +      T&
  1.1111 +      operator*() const
  1.1112 +        {
  1.1113 +          NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator*().");
  1.1114 +          return *get();
  1.1115 +        }
  1.1116 +
  1.1117 +      T**
  1.1118 +      StartAssignment()
  1.1119 +        {
  1.1120 +#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
  1.1121 +          return reinterpret_cast<T**>(begin_assignment());
  1.1122 +#else
  1.1123 +          assign_assuming_AddRef(0);
  1.1124 +          return reinterpret_cast<T**>(&mRawPtr);
  1.1125 +#endif
  1.1126 +        }
  1.1127 +  };
  1.1128 +
  1.1129 +template <typename T>
  1.1130 +inline void
  1.1131 +ImplCycleCollectionUnlink(nsRefPtr<T>& aField)
  1.1132 +{
  1.1133 +  aField = nullptr;
  1.1134 +}
  1.1135 +
  1.1136 +template <typename T>
  1.1137 +inline void
  1.1138 +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
  1.1139 +                            nsRefPtr<T>& aField,
  1.1140 +                            const char* aName,
  1.1141 +                            uint32_t aFlags = 0)
  1.1142 +{
  1.1143 +  CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
  1.1144 +}
  1.1145 +
  1.1146 +template <class T>
  1.1147 +inline
  1.1148 +nsRefPtr<T>*
  1.1149 +address_of( nsRefPtr<T>& aPtr )
  1.1150 +  {
  1.1151 +    return aPtr.get_address();
  1.1152 +  }
  1.1153 +
  1.1154 +template <class T>
  1.1155 +inline
  1.1156 +const nsRefPtr<T>*
  1.1157 +address_of( const nsRefPtr<T>& aPtr )
  1.1158 +  {
  1.1159 +    return aPtr.get_address();
  1.1160 +  }
  1.1161 +
  1.1162 +template <class T>
  1.1163 +class nsRefPtrGetterAddRefs
  1.1164 +    /*
  1.1165 +      ...
  1.1166 +
  1.1167 +      This class is designed to be used for anonymous temporary objects in the
  1.1168 +      argument list of calls that return COM interface pointers, e.g.,
  1.1169 +
  1.1170 +        nsRefPtr<IFoo> fooP;
  1.1171 +        ...->GetAddRefedPointer(getter_AddRefs(fooP))
  1.1172 +
  1.1173 +      DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
  1.1174 +
  1.1175 +      When initialized with a |nsRefPtr|, as in the example above, it returns
  1.1176 +      a |void**|, a |T**|, or an |nsISupports**| as needed, that the
  1.1177 +      outer call (|GetAddRefedPointer| in this case) can fill in.
  1.1178 +
  1.1179 +      This type should be a nested class inside |nsRefPtr<T>|.
  1.1180 +    */
  1.1181 +  {
  1.1182 +    public:
  1.1183 +      explicit
  1.1184 +      nsRefPtrGetterAddRefs( nsRefPtr<T>& aSmartPtr )
  1.1185 +          : mTargetSmartPtr(aSmartPtr)
  1.1186 +        {
  1.1187 +          // nothing else to do
  1.1188 +        }
  1.1189 +
  1.1190 +      operator void**()
  1.1191 +        {
  1.1192 +          return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
  1.1193 +        }
  1.1194 +
  1.1195 +      operator T**()
  1.1196 +        {
  1.1197 +          return mTargetSmartPtr.StartAssignment();
  1.1198 +        }
  1.1199 +
  1.1200 +      T*&
  1.1201 +      operator*()
  1.1202 +        {
  1.1203 +          return *(mTargetSmartPtr.StartAssignment());
  1.1204 +        }
  1.1205 +
  1.1206 +    private:
  1.1207 +      nsRefPtr<T>& mTargetSmartPtr;
  1.1208 +  };
  1.1209 +
  1.1210 +template <class T>
  1.1211 +inline
  1.1212 +nsRefPtrGetterAddRefs<T>
  1.1213 +getter_AddRefs( nsRefPtr<T>& aSmartPtr )
  1.1214 +    /*
  1.1215 +      Used around a |nsRefPtr| when 
  1.1216 +      ...makes the class |nsRefPtrGetterAddRefs<T>| invisible.
  1.1217 +    */
  1.1218 +  {
  1.1219 +    return nsRefPtrGetterAddRefs<T>(aSmartPtr);
  1.1220 +  }
  1.1221 +
  1.1222 +
  1.1223 +
  1.1224 +  // Comparing two |nsRefPtr|s
  1.1225 +
  1.1226 +template <class T, class U>
  1.1227 +inline
  1.1228 +bool
  1.1229 +operator==( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
  1.1230 +  {
  1.1231 +    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
  1.1232 +  }
  1.1233 +
  1.1234 +
  1.1235 +template <class T, class U>
  1.1236 +inline
  1.1237 +bool
  1.1238 +operator!=( const nsRefPtr<T>& lhs, const nsRefPtr<U>& rhs )
  1.1239 +  {
  1.1240 +    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
  1.1241 +  }
  1.1242 +
  1.1243 +
  1.1244 +  // Comparing an |nsRefPtr| to a raw pointer
  1.1245 +
  1.1246 +template <class T, class U>
  1.1247 +inline
  1.1248 +bool
  1.1249 +operator==( const nsRefPtr<T>& lhs, const U* rhs )
  1.1250 +  {
  1.1251 +    return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
  1.1252 +  }
  1.1253 +
  1.1254 +template <class T, class U>
  1.1255 +inline
  1.1256 +bool
  1.1257 +operator==( const U* lhs, const nsRefPtr<T>& rhs )
  1.1258 +  {
  1.1259 +    return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
  1.1260 +  }
  1.1261 +
  1.1262 +template <class T, class U>
  1.1263 +inline
  1.1264 +bool
  1.1265 +operator!=( const nsRefPtr<T>& lhs, const U* rhs )
  1.1266 +  {
  1.1267 +    return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
  1.1268 +  }
  1.1269 +
  1.1270 +template <class T, class U>
  1.1271 +inline
  1.1272 +bool
  1.1273 +operator!=( const U* lhs, const nsRefPtr<T>& rhs )
  1.1274 +  {
  1.1275 +    return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
  1.1276 +  }
  1.1277 +
  1.1278 +  // To avoid ambiguities caused by the presence of builtin |operator==|s
  1.1279 +  // creating a situation where one of the |operator==| defined above
  1.1280 +  // has a better conversion for one argument and the builtin has a
  1.1281 +  // better conversion for the other argument, define additional
  1.1282 +  // |operator==| without the |const| on the raw pointer.
  1.1283 +  // See bug 65664 for details.
  1.1284 +
  1.1285 +#ifndef NSCAP_DONT_PROVIDE_NONCONST_OPEQ
  1.1286 +template <class T, class U>
  1.1287 +inline
  1.1288 +bool
  1.1289 +operator==( const nsRefPtr<T>& lhs, U* rhs )
  1.1290 +  {
  1.1291 +    return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
  1.1292 +  }
  1.1293 +
  1.1294 +template <class T, class U>
  1.1295 +inline
  1.1296 +bool
  1.1297 +operator==( U* lhs, const nsRefPtr<T>& rhs )
  1.1298 +  {
  1.1299 +    return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
  1.1300 +  }
  1.1301 +
  1.1302 +template <class T, class U>
  1.1303 +inline
  1.1304 +bool
  1.1305 +operator!=( const nsRefPtr<T>& lhs, U* rhs )
  1.1306 +  {
  1.1307 +    return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
  1.1308 +  }
  1.1309 +
  1.1310 +template <class T, class U>
  1.1311 +inline
  1.1312 +bool
  1.1313 +operator!=( U* lhs, const nsRefPtr<T>& rhs )
  1.1314 +  {
  1.1315 +    return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
  1.1316 +  }
  1.1317 +#endif
  1.1318 +
  1.1319 +
  1.1320 +
  1.1321 +  // Comparing an |nsRefPtr| to |0|
  1.1322 +
  1.1323 +template <class T>
  1.1324 +inline
  1.1325 +bool
  1.1326 +operator==( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
  1.1327 +    // specifically to allow |smartPtr == 0|
  1.1328 +  {
  1.1329 +    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
  1.1330 +  }
  1.1331 +
  1.1332 +template <class T>
  1.1333 +inline
  1.1334 +bool
  1.1335 +operator==( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
  1.1336 +    // specifically to allow |0 == smartPtr|
  1.1337 +  {
  1.1338 +    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
  1.1339 +  }
  1.1340 +
  1.1341 +template <class T>
  1.1342 +inline
  1.1343 +bool
  1.1344 +operator!=( const nsRefPtr<T>& lhs, NSCAP_Zero* rhs )
  1.1345 +    // specifically to allow |smartPtr != 0|
  1.1346 +  {
  1.1347 +    return static_cast<const void*>(lhs.get()) != reinterpret_cast<const void*>(rhs);
  1.1348 +  }
  1.1349 +
  1.1350 +template <class T>
  1.1351 +inline
  1.1352 +bool
  1.1353 +operator!=( NSCAP_Zero* lhs, const nsRefPtr<T>& rhs )
  1.1354 +    // specifically to allow |0 != smartPtr|
  1.1355 +  {
  1.1356 +    return reinterpret_cast<const void*>(lhs) != static_cast<const void*>(rhs.get());
  1.1357 +  }
  1.1358 +
  1.1359 +
  1.1360 +#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
  1.1361 +
  1.1362 +  // We need to explicitly define comparison operators for `int'
  1.1363 +  // because the compiler is lame.
  1.1364 +
  1.1365 +template <class T>
  1.1366 +inline
  1.1367 +bool
  1.1368 +operator==( const nsRefPtr<T>& lhs, int rhs )
  1.1369 +    // specifically to allow |smartPtr == 0|
  1.1370 +  {
  1.1371 +    return static_cast<const void*>(lhs.get()) == reinterpret_cast<const void*>(rhs);
  1.1372 +  }
  1.1373 +
  1.1374 +template <class T>
  1.1375 +inline
  1.1376 +bool
  1.1377 +operator==( int lhs, const nsRefPtr<T>& rhs )
  1.1378 +    // specifically to allow |0 == smartPtr|
  1.1379 +  {
  1.1380 +    return reinterpret_cast<const void*>(lhs) == static_cast<const void*>(rhs.get());
  1.1381 +  }
  1.1382 +
  1.1383 +#endif // !defined(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
  1.1384 +
  1.1385 +template <class SourceType, class DestinationType>
  1.1386 +inline
  1.1387 +nsresult
  1.1388 +CallQueryInterface( nsRefPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr )
  1.1389 +  {
  1.1390 +    return CallQueryInterface(aSourcePtr.get(), aDestPtr);
  1.1391 +  }
  1.1392 +
  1.1393 +/*****************************************************************************/
  1.1394 +
  1.1395 +template<class T>
  1.1396 +class nsQueryObject : public nsCOMPtr_helper
  1.1397 +{
  1.1398 +public:
  1.1399 +  nsQueryObject(T* aRawPtr)
  1.1400 +    : mRawPtr(aRawPtr) {}
  1.1401 +
  1.1402 +  virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
  1.1403 +    nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
  1.1404 +                              : NS_ERROR_NULL_POINTER;
  1.1405 +    return status;
  1.1406 +  }
  1.1407 +private:
  1.1408 +  T* mRawPtr;
  1.1409 +};
  1.1410 +
  1.1411 +template<class T>
  1.1412 +class nsQueryObjectWithError : public nsCOMPtr_helper
  1.1413 +{
  1.1414 +public:
  1.1415 +  nsQueryObjectWithError(T* aRawPtr, nsresult* aErrorPtr)
  1.1416 +    : mRawPtr(aRawPtr), mErrorPtr(aErrorPtr) {}
  1.1417 +
  1.1418 +  virtual nsresult NS_FASTCALL operator()( const nsIID& aIID, void** aResult ) const {
  1.1419 +    nsresult status = mRawPtr ? mRawPtr->QueryInterface(aIID, aResult)
  1.1420 +                              : NS_ERROR_NULL_POINTER;
  1.1421 +    if (mErrorPtr)
  1.1422 +      *mErrorPtr = status;
  1.1423 +    return status;
  1.1424 +  }
  1.1425 +private:
  1.1426 +  T* mRawPtr;
  1.1427 +  nsresult* mErrorPtr;
  1.1428 +};
  1.1429 +
  1.1430 +template<class T>
  1.1431 +inline
  1.1432 +nsQueryObject<T>
  1.1433 +do_QueryObject(T* aRawPtr)
  1.1434 +{
  1.1435 +  return nsQueryObject<T>(aRawPtr);
  1.1436 +}
  1.1437 +
  1.1438 +template<class T>
  1.1439 +inline
  1.1440 +nsQueryObject<T>
  1.1441 +do_QueryObject(nsCOMPtr<T>& aRawPtr)
  1.1442 +{
  1.1443 +  return nsQueryObject<T>(aRawPtr);
  1.1444 +}
  1.1445 +
  1.1446 +template<class T>
  1.1447 +inline
  1.1448 +nsQueryObject<T>
  1.1449 +do_QueryObject(nsRefPtr<T>& aRawPtr)
  1.1450 +{
  1.1451 +  return nsQueryObject<T>(aRawPtr);
  1.1452 +}
  1.1453 +
  1.1454 +template<class T>
  1.1455 +inline
  1.1456 +nsQueryObjectWithError<T>
  1.1457 +do_QueryObject(T* aRawPtr, nsresult* aErrorPtr)
  1.1458 +{
  1.1459 +  return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
  1.1460 +}
  1.1461 +
  1.1462 +template<class T>
  1.1463 +inline
  1.1464 +nsQueryObjectWithError<T>
  1.1465 +do_QueryObject(nsCOMPtr<T>& aRawPtr, nsresult* aErrorPtr)
  1.1466 +{
  1.1467 +  return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
  1.1468 +}
  1.1469 +
  1.1470 +template<class T>
  1.1471 +inline
  1.1472 +nsQueryObjectWithError<T>
  1.1473 +do_QueryObject(nsRefPtr<T>& aRawPtr, nsresult* aErrorPtr)
  1.1474 +{
  1.1475 +  return nsQueryObjectWithError<T>(aRawPtr, aErrorPtr);
  1.1476 +}
  1.1477 +
  1.1478 +/*****************************************************************************/
  1.1479 +
  1.1480 +#endif // !defined(nsAutoPtr_h___)

mercurial