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___)