1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/base/nsAutoRef.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,666 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef nsAutoRef_h_ 1.11 +#define nsAutoRef_h_ 1.12 + 1.13 +#include "mozilla/Attributes.h" 1.14 + 1.15 +#include "nscore.h" // for nullptr, bool 1.16 + 1.17 +template <class T> class nsSimpleRef; 1.18 +template <class T> class nsAutoRefBase; 1.19 +template <class T> class nsReturnRef; 1.20 +template <class T> class nsReturningRef; 1.21 + 1.22 +/** 1.23 + * template <class T> class nsAutoRef 1.24 + * 1.25 + * A class that holds a handle to a resource that must be released. 1.26 + * No reference is added on construction. 1.27 + * 1.28 + * No copy constructor nor copy assignment operators are available, so the 1.29 + * resource will be held until released on destruction or explicitly 1.30 + * |reset()| or transferred through provided methods. 1.31 + * 1.32 + * The publicly available methods are the public methods on this class and its 1.33 + * public base classes |nsAutoRefBase<T>| and |nsSimpleRef<T>|. 1.34 + * 1.35 + * For ref-counted resources see also |nsCountedRef<T>|. 1.36 + * For function return values see |nsReturnRef<T>|. 1.37 + * 1.38 + * For each class |T|, |nsAutoRefTraits<T>| or |nsSimpleRef<T>| must be 1.39 + * specialized to use |nsAutoRef<T>| and |nsCountedRef<T>|. 1.40 + * 1.41 + * @param T A class identifying the type of reference held by the 1.42 + * |nsAutoRef<T>| and the unique set methods for managing references 1.43 + * to the resource (defined by |nsAutoRefTraits<T>| or 1.44 + * |nsSimpleRef<T>|). 1.45 + * 1.46 + * Often this is the class representing the resource. Sometimes a 1.47 + * new possibly-incomplete class may need to be declared. 1.48 + * 1.49 + * 1.50 + * Example: An Automatically closing file descriptor 1.51 + * 1.52 + * // References that are simple integral types (as file-descriptors are) 1.53 + * // usually need a new class to represent the resource and how to handle its 1.54 + * // references. 1.55 + * class nsRawFD; 1.56 + * 1.57 + * // Specializing nsAutoRefTraits<nsRawFD> describes how to manage file 1.58 + * // descriptors, so that nsAutoRef<nsRawFD> provides automatic closing of 1.59 + * // its file descriptor on destruction. 1.60 + * template <> 1.61 + * class nsAutoRefTraits<nsRawFD> { 1.62 + * public: 1.63 + * // The file descriptor is held in an int. 1.64 + * typedef int RawRef; 1.65 + * // -1 means that there is no file associated with the handle. 1.66 + * static int Void() { return -1; } 1.67 + * // The file associated with a file descriptor is released with close(). 1.68 + * static void Release(RawRef aFD) { close(aFD); } 1.69 + * }; 1.70 + * 1.71 + * // A function returning a file descriptor that must be closed. 1.72 + * nsReturnRef<nsRawFD> get_file(const char *filename) { 1.73 + * // Constructing from a raw file descriptor assumes ownership. 1.74 + * nsAutoRef<nsRawFD> fd(open(filename, O_RDONLY)); 1.75 + * fcntl(fd, F_SETFD, FD_CLOEXEC); 1.76 + * return fd.out(); 1.77 + * } 1.78 + * 1.79 + * void f() { 1.80 + * unsigned char buf[1024]; 1.81 + * 1.82 + * // Hold a file descriptor for /etc/hosts in fd1. 1.83 + * nsAutoRef<nsRawFD> fd1(get_file("/etc/hosts")); 1.84 + * 1.85 + * nsAutoRef<nsRawFD> fd2; 1.86 + * fd2.steal(fd1); // fd2 takes the file descriptor from fd1 1.87 + * ssize_t count = read(fd1, buf, 1024); // error fd1 has no file 1.88 + * count = read(fd2, buf, 1024); // reads from /etc/hosts 1.89 + * 1.90 + * // If the file descriptor is not stored then it is closed. 1.91 + * get_file("/etc/login.defs"); // login.defs is closed 1.92 + * 1.93 + * // Now use fd1 to hold a file descriptor for /etc/passwd. 1.94 + * fd1 = get_file("/etc/passwd"); 1.95 + * 1.96 + * // The nsAutoRef<nsRawFD> can give up the file descriptor if explicitly 1.97 + * // instructed, but the caller must then ensure that the file is closed. 1.98 + * int rawfd = fd1.disown(); 1.99 + * 1.100 + * // Assume ownership of another file descriptor. 1.101 + * fd1.own(open("/proc/1/maps"); 1.102 + * 1.103 + * // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts, 1.104 + * // but /etc/passwd is not closed. 1.105 + * } 1.106 + * 1.107 + */ 1.108 + 1.109 + 1.110 +template <class T> 1.111 +class nsAutoRef : public nsAutoRefBase<T> 1.112 +{ 1.113 +protected: 1.114 + typedef nsAutoRef<T> ThisClass; 1.115 + typedef nsAutoRefBase<T> BaseClass; 1.116 + typedef nsSimpleRef<T> SimpleRef; 1.117 + typedef typename BaseClass::RawRefOnly RawRefOnly; 1.118 + typedef typename BaseClass::LocalSimpleRef LocalSimpleRef; 1.119 + 1.120 +public: 1.121 + nsAutoRef() 1.122 + { 1.123 + } 1.124 + 1.125 + // Explicit construction is required so as not to risk unintentionally 1.126 + // releasing the resource associated with a raw ref. 1.127 + explicit nsAutoRef(RawRefOnly aRefToRelease) 1.128 + : BaseClass(aRefToRelease) 1.129 + { 1.130 + } 1.131 + 1.132 + // Construction from a nsReturnRef<T> function return value, which expects 1.133 + // to give up ownership, transfers ownership. 1.134 + // (nsReturnRef<T> is converted to const nsReturningRef<T>.) 1.135 + explicit nsAutoRef(const nsReturningRef<T>& aReturning) 1.136 + : BaseClass(aReturning) 1.137 + { 1.138 + } 1.139 + 1.140 + // The only assignment operator provided is for transferring from an 1.141 + // nsReturnRef smart reference, which expects to pass its ownership to 1.142 + // another object. 1.143 + // 1.144 + // With raw references and other smart references, the type of the lhs and 1.145 + // its taking and releasing nature is often not obvious from an assignment 1.146 + // statement. Assignment from a raw ptr especially is not normally 1.147 + // expected to release the reference. 1.148 + // 1.149 + // Use |steal| for taking ownership from other smart refs. 1.150 + // 1.151 + // For raw references, use |own| to indicate intention to have the 1.152 + // resource released. 1.153 + // 1.154 + // Or, to create another owner of the same reference, use an nsCountedRef. 1.155 + 1.156 + ThisClass& operator=(const nsReturningRef<T>& aReturning) 1.157 + { 1.158 + BaseClass::steal(aReturning.mReturnRef); 1.159 + return *this; 1.160 + } 1.161 + 1.162 + // Conversion to a raw reference allow the nsAutoRef<T> to often be used 1.163 + // like a raw reference. 1.164 + operator typename SimpleRef::RawRef() const 1.165 + { 1.166 + return this->get(); 1.167 + } 1.168 + 1.169 + // Transfer ownership from another smart reference. 1.170 + void steal(ThisClass& aOtherRef) 1.171 + { 1.172 + BaseClass::steal(aOtherRef); 1.173 + } 1.174 + 1.175 + // Assume ownership of a raw ref. 1.176 + // 1.177 + // |own| has similar function to |steal|, and is useful for receiving 1.178 + // ownership from a return value of a function. It is named differently 1.179 + // because |own| requires more care to ensure that the function intends to 1.180 + // give away ownership, and so that |steal| can be safely used, knowing 1.181 + // that it won't steal ownership from any methods returning raw ptrs to 1.182 + // data owned by a foreign object. 1.183 + void own(RawRefOnly aRefToRelease) 1.184 + { 1.185 + BaseClass::own(aRefToRelease); 1.186 + } 1.187 + 1.188 + // Exchange ownership with |aOther| 1.189 + void swap(ThisClass& aOther) 1.190 + { 1.191 + LocalSimpleRef temp; 1.192 + temp.SimpleRef::operator=(*this); 1.193 + SimpleRef::operator=(aOther); 1.194 + aOther.SimpleRef::operator=(temp); 1.195 + } 1.196 + 1.197 + // Release the reference now. 1.198 + void reset() 1.199 + { 1.200 + this->SafeRelease(); 1.201 + LocalSimpleRef empty; 1.202 + SimpleRef::operator=(empty); 1.203 + } 1.204 + 1.205 + // Pass out the reference for a function return values. 1.206 + nsReturnRef<T> out() 1.207 + { 1.208 + return nsReturnRef<T>(this->disown()); 1.209 + } 1.210 + 1.211 + // operator->() and disown() are provided by nsAutoRefBase<T>. 1.212 + // The default nsSimpleRef<T> provides get(). 1.213 + 1.214 +private: 1.215 + // No copy constructor 1.216 + explicit nsAutoRef(ThisClass& aRefToSteal); 1.217 +}; 1.218 + 1.219 +/** 1.220 + * template <class T> class nsCountedRef 1.221 + * 1.222 + * A class that creates (adds) a new reference to a resource on construction 1.223 + * or assignment and releases on destruction. 1.224 + * 1.225 + * This class is similar to nsAutoRef<T> and inherits its methods, but also 1.226 + * provides copy construction and assignment operators that enable more than 1.227 + * one concurrent reference to the same resource. 1.228 + * 1.229 + * Specialize |nsAutoRefTraits<T>| or |nsSimpleRef<T>| to use this. This 1.230 + * class assumes that the resource itself counts references and so can only be 1.231 + * used when |T| represents a reference-counting resource. 1.232 + */ 1.233 + 1.234 +template <class T> 1.235 +class nsCountedRef : public nsAutoRef<T> 1.236 +{ 1.237 +protected: 1.238 + typedef nsCountedRef<T> ThisClass; 1.239 + typedef nsAutoRef<T> BaseClass; 1.240 + typedef nsSimpleRef<T> SimpleRef; 1.241 + typedef typename BaseClass::RawRef RawRef; 1.242 + 1.243 +public: 1.244 + nsCountedRef() 1.245 + { 1.246 + } 1.247 + 1.248 + // Construction and assignment from a another nsCountedRef 1.249 + // or a raw ref copies and increments the ref count. 1.250 + nsCountedRef(const ThisClass& aRefToCopy) 1.251 + { 1.252 + SimpleRef::operator=(aRefToCopy); 1.253 + SafeAddRef(); 1.254 + } 1.255 + ThisClass& operator=(const ThisClass& aRefToCopy) 1.256 + { 1.257 + if (this == &aRefToCopy) 1.258 + return *this; 1.259 + 1.260 + this->SafeRelease(); 1.261 + SimpleRef::operator=(aRefToCopy); 1.262 + SafeAddRef(); 1.263 + return *this; 1.264 + } 1.265 + 1.266 + // Implicit conversion from another smart ref argument (to a raw ref) is 1.267 + // accepted here because construction and assignment safely creates a new 1.268 + // reference without interfering with the reference to copy. 1.269 + explicit nsCountedRef(RawRef aRefToCopy) 1.270 + : BaseClass(aRefToCopy) 1.271 + { 1.272 + SafeAddRef(); 1.273 + } 1.274 + ThisClass& operator=(RawRef aRefToCopy) 1.275 + { 1.276 + this->own(aRefToCopy); 1.277 + SafeAddRef(); 1.278 + return *this; 1.279 + } 1.280 + 1.281 + // Construction and assignment from an nsReturnRef function return value, 1.282 + // which expects to give up ownership, transfers ownership. 1.283 + explicit nsCountedRef(const nsReturningRef<T>& aReturning) 1.284 + : BaseClass(aReturning) 1.285 + { 1.286 + } 1.287 + ThisClass& operator=(const nsReturningRef<T>& aReturning) 1.288 + { 1.289 + BaseClass::operator=(aReturning); 1.290 + return *this; 1.291 + } 1.292 + 1.293 +protected: 1.294 + // Increase the reference count if there is a resource. 1.295 + void SafeAddRef() 1.296 + { 1.297 + if (this->HaveResource()) 1.298 + this->AddRef(this->get()); 1.299 + } 1.300 +}; 1.301 + 1.302 +/** 1.303 + * template <class T> class nsReturnRef 1.304 + * 1.305 + * A type for function return values that hold a reference to a resource that 1.306 + * must be released. See also |nsAutoRef<T>::out()|. 1.307 + */ 1.308 + 1.309 +template <class T> 1.310 +class nsReturnRef : public nsAutoRefBase<T> 1.311 +{ 1.312 +protected: 1.313 + typedef nsAutoRefBase<T> BaseClass; 1.314 + typedef typename BaseClass::RawRefOnly RawRefOnly; 1.315 + 1.316 +public: 1.317 + // For constructing a return value with no resource 1.318 + nsReturnRef() 1.319 + { 1.320 + } 1.321 + 1.322 + // For returning a smart reference from a raw reference that must be 1.323 + // released. Explicit construction is required so as not to risk 1.324 + // unintentionally releasing the resource associated with a raw ref. 1.325 + explicit nsReturnRef(RawRefOnly aRefToRelease) 1.326 + : BaseClass(aRefToRelease) 1.327 + { 1.328 + } 1.329 + 1.330 + // Copy construction transfers ownership 1.331 + nsReturnRef(nsReturnRef<T>& aRefToSteal) 1.332 + : BaseClass(aRefToSteal) 1.333 + { 1.334 + } 1.335 + 1.336 + nsReturnRef(const nsReturningRef<T>& aReturning) 1.337 + : BaseClass(aReturning) 1.338 + { 1.339 + } 1.340 + 1.341 + // Conversion to a temporary (const) object referring to this object so 1.342 + // that the reference may be passed from a function return value 1.343 + // (temporary) to another smart reference. There is no need to use this 1.344 + // explicitly. Simply assign a nsReturnRef<T> function return value to a 1.345 + // smart reference. 1.346 + operator nsReturningRef<T>() 1.347 + { 1.348 + return nsReturningRef<T>(*this); 1.349 + } 1.350 + 1.351 + // No conversion to RawRef operator is provided on nsReturnRef, to ensure 1.352 + // that the return value is not carelessly assigned to a raw ptr (and the 1.353 + // resource then released). If passing to a function that takes a raw 1.354 + // ptr, use get or disown as appropriate. 1.355 +}; 1.356 + 1.357 +/** 1.358 + * template <class T> class nsReturningRef 1.359 + * 1.360 + * A class to allow ownership to be transferred from nsReturnRef function 1.361 + * return values. 1.362 + * 1.363 + * It should not be necessary for clients to reference this 1.364 + * class directly. Simply pass an nsReturnRef<T> to a parameter taking an 1.365 + * |nsReturningRef<T>|. 1.366 + * 1.367 + * The conversion operator on nsReturnRef constructs a temporary wrapper of 1.368 + * class nsReturningRef<T> around a non-const reference to the nsReturnRef. 1.369 + * The wrapper can then be passed as an rvalue parameter. 1.370 + */ 1.371 + 1.372 +template <class T> 1.373 +class nsReturningRef 1.374 +{ 1.375 +private: 1.376 + friend class nsReturnRef<T>; 1.377 + 1.378 + explicit nsReturningRef(nsReturnRef<T>& aReturnRef) 1.379 + : mReturnRef(aReturnRef) 1.380 + { 1.381 + } 1.382 +public: 1.383 + nsReturnRef<T>& mReturnRef; 1.384 +}; 1.385 + 1.386 +/** 1.387 + * template <class T> class nsAutoRefTraits 1.388 + * 1.389 + * A class describing traits of references managed by the default 1.390 + * |nsSimpleRef<T>| implementation and thus |nsAutoRef<T>| and |nsCountedRef|. 1.391 + * The default |nsSimpleRef<T> is suitable for resources with handles that 1.392 + * have a void value. (If there is no such void value for a handle, 1.393 + * specialize |nsSimpleRef<T>|.) 1.394 + * 1.395 + * Specializations must be provided for each class |T| according to the 1.396 + * following pattern: 1.397 + * 1.398 + * // The template parameter |T| should be a class such that the set of fields 1.399 + * // in class nsAutoRefTraits<T> is unique for class |T|. Usually the 1.400 + * // resource object class is sufficient. For handles that are simple 1.401 + * // integral typedefs, a new unique possibly-incomplete class may need to be 1.402 + * // declared. 1.403 + * 1.404 + * template <> 1.405 + * class nsAutoRefTraits<T> 1.406 + * { 1.407 + * // Specializations must provide a typedef for RawRef, describing the 1.408 + * // type of the handle to the resource. 1.409 + * typedef <handle-type> RawRef; 1.410 + * 1.411 + * // Specializations should define Void(), a function returning a value 1.412 + * // suitable for a handle that does not have an associated resource. 1.413 + * // 1.414 + * // The return type must be a suitable as the parameter to a RawRef 1.415 + * // constructor and operator==. 1.416 + * // 1.417 + * // If this method is not accessible then some limited nsAutoRef 1.418 + * // functionality will still be available, but the default constructor, 1.419 + * // |reset|, and most transfer of ownership methods will not be available. 1.420 + * static <return-type> Void(); 1.421 + * 1.422 + * // Specializations must define Release() to properly finalize the 1.423 + * // handle to a non-void custom-deleted or reference-counted resource. 1.424 + * static void Release(RawRef aRawRef); 1.425 + * 1.426 + * // For reference-counted resources, if |nsCountedRef<T>| is to be used, 1.427 + * // specializations must define AddRef to increment the reference count 1.428 + * // held by a non-void handle. 1.429 + * // (AddRef() is not necessary for |nsAutoRef<T>|.) 1.430 + * static void AddRef(RawRef aRawRef); 1.431 + * }; 1.432 + * 1.433 + * See nsPointerRefTraits for example specializations for simple pointer 1.434 + * references. See nsAutoRef for an example specialization for a non-pointer 1.435 + * reference. 1.436 + */ 1.437 + 1.438 +template <class T> class nsAutoRefTraits; 1.439 + 1.440 +/** 1.441 + * template <class T> class nsPointerRefTraits 1.442 + * 1.443 + * A convenience class useful as a base class for specializations of 1.444 + * |nsAutoRefTraits<T>| where the handle to the resource is a pointer to |T|. 1.445 + * By inheriting from this class, definitions of only Release(RawRef) and 1.446 + * possibly AddRef(RawRef) need to be added. 1.447 + * 1.448 + * Examples of use: 1.449 + * 1.450 + * template <> 1.451 + * class nsAutoRefTraits<PRFileDesc> : public nsPointerRefTraits<PRFileDesc> 1.452 + * { 1.453 + * public: 1.454 + * static void Release(PRFileDesc *ptr) { PR_Close(ptr); } 1.455 + * }; 1.456 + * 1.457 + * template <> 1.458 + * class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern> 1.459 + * { 1.460 + * public: 1.461 + * static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); } 1.462 + * static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); } 1.463 + * }; 1.464 + */ 1.465 + 1.466 +template <class T> 1.467 +class nsPointerRefTraits 1.468 +{ 1.469 +public: 1.470 + // The handle is a pointer to T. 1.471 + typedef T* RawRef; 1.472 + // A nullptr does not have a resource. 1.473 + static RawRef Void() { return nullptr; } 1.474 +}; 1.475 + 1.476 +/** 1.477 + * template <class T> class nsSimpleRef 1.478 + * 1.479 + * Constructs a non-smart reference, and provides methods to test whether 1.480 + * there is an associated resource and (if so) get its raw handle. 1.481 + * 1.482 + * A default implementation is suitable for resources with handles that have a 1.483 + * void value. This is not intended for direct use but used by |nsAutoRef<T>| 1.484 + * and thus |nsCountedRef<T>|. 1.485 + * 1.486 + * Specialize this class if there is no particular void value for the resource 1.487 + * handle. A specialized implementation must also provide Release(RawRef), 1.488 + * and, if |nsCountedRef<T>| is required, AddRef(RawRef), as described in 1.489 + * nsAutoRefTraits<T>. 1.490 + */ 1.491 + 1.492 +template <class T> 1.493 +class nsSimpleRef : protected nsAutoRefTraits<T> 1.494 +{ 1.495 +protected: 1.496 + // The default implementation uses nsAutoRefTrait<T>. 1.497 + // Specializations need not define this typedef. 1.498 + typedef nsAutoRefTraits<T> Traits; 1.499 + // The type of the handle to the resource. 1.500 + // A specialization must provide a typedef for RawRef. 1.501 + typedef typename Traits::RawRef RawRef; 1.502 + 1.503 + // Construct with no resource. 1.504 + // 1.505 + // If this constructor is not accessible then some limited nsAutoRef 1.506 + // functionality will still be available, but the default constructor, 1.507 + // |reset|, and most transfer of ownership methods will not be available. 1.508 + nsSimpleRef() 1.509 + : mRawRef(Traits::Void()) 1.510 + { 1.511 + } 1.512 + // Construct with a handle to a resource. 1.513 + // A specialization must provide this. 1.514 + nsSimpleRef(RawRef aRawRef) 1.515 + : mRawRef(aRawRef) 1.516 + { 1.517 + } 1.518 + 1.519 + // Test whether there is an associated resource. A specialization must 1.520 + // provide this. The function is permitted to always return true if the 1.521 + // default constructor is not accessible, or if Release (and AddRef) can 1.522 + // deal with void handles. 1.523 + bool HaveResource() const 1.524 + { 1.525 + return mRawRef != Traits::Void(); 1.526 + } 1.527 + 1.528 +public: 1.529 + // A specialization must provide get() or loose some functionality. This 1.530 + // is inherited by derived classes and the specialization may choose 1.531 + // whether it is public or protected. 1.532 + RawRef get() const 1.533 + { 1.534 + return mRawRef; 1.535 + } 1.536 + 1.537 +private: 1.538 + RawRef mRawRef; 1.539 +}; 1.540 + 1.541 + 1.542 +/** 1.543 + * template <class T> class nsAutoRefBase 1.544 + * 1.545 + * Internal base class for |nsAutoRef<T>| and |nsReturnRef<T>|. 1.546 + * Adds release on destruction to a |nsSimpleRef<T>|. 1.547 + */ 1.548 + 1.549 +template <class T> 1.550 +class nsAutoRefBase : public nsSimpleRef<T> 1.551 +{ 1.552 +protected: 1.553 + typedef nsAutoRefBase<T> ThisClass; 1.554 + typedef nsSimpleRef<T> SimpleRef; 1.555 + typedef typename SimpleRef::RawRef RawRef; 1.556 + 1.557 + nsAutoRefBase() 1.558 + { 1.559 + } 1.560 + 1.561 + // A type for parameters that should be passed a raw ref but should not 1.562 + // accept implicit conversions (from another smart ref). (The only 1.563 + // conversion to this type is from a raw ref so only raw refs will be 1.564 + // accepted.) 1.565 + class RawRefOnly 1.566 + { 1.567 + public: 1.568 + RawRefOnly(RawRef aRawRef) 1.569 + : mRawRef(aRawRef) 1.570 + { 1.571 + } 1.572 + operator RawRef() const 1.573 + { 1.574 + return mRawRef; 1.575 + } 1.576 + private: 1.577 + RawRef mRawRef; 1.578 + }; 1.579 + 1.580 + // Construction from a raw ref assumes ownership 1.581 + explicit nsAutoRefBase(RawRefOnly aRefToRelease) 1.582 + : SimpleRef(aRefToRelease) 1.583 + { 1.584 + } 1.585 + 1.586 + // Constructors that steal ownership 1.587 + explicit nsAutoRefBase(ThisClass& aRefToSteal) 1.588 + : SimpleRef(aRefToSteal.disown()) 1.589 + { 1.590 + } 1.591 + explicit nsAutoRefBase(const nsReturningRef<T>& aReturning) 1.592 + : SimpleRef(aReturning.mReturnRef.disown()) 1.593 + { 1.594 + } 1.595 + 1.596 + ~nsAutoRefBase() 1.597 + { 1.598 + SafeRelease(); 1.599 + } 1.600 + 1.601 + // An internal class providing access to protected nsSimpleRef<T> 1.602 + // constructors for construction of temporary simple references (that are 1.603 + // not ThisClass). 1.604 + class LocalSimpleRef : public SimpleRef 1.605 + { 1.606 + public: 1.607 + LocalSimpleRef() 1.608 + { 1.609 + } 1.610 + explicit LocalSimpleRef(RawRef aRawRef) 1.611 + : SimpleRef(aRawRef) 1.612 + { 1.613 + } 1.614 + }; 1.615 + 1.616 +private: 1.617 + ThisClass& operator=(const ThisClass& aSmartRef) MOZ_DELETE; 1.618 + 1.619 +public: 1.620 + RawRef operator->() const 1.621 + { 1.622 + return this->get(); 1.623 + } 1.624 + 1.625 + // Transfer ownership to a raw reference. 1.626 + // 1.627 + // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED. 1.628 + // 1.629 + // Is this really what you want to use? Using this removes any guarantee 1.630 + // of release. Use nsAutoRef<T>::out() for return values, or an 1.631 + // nsAutoRef<T> modifiable lvalue for an out parameter. Use disown() when 1.632 + // the reference must be stored in a POD type object, such as may be 1.633 + // preferred for a namespace-scope object with static storage duration, 1.634 + // for example. 1.635 + RawRef disown() 1.636 + { 1.637 + RawRef temp = this->get(); 1.638 + LocalSimpleRef empty; 1.639 + SimpleRef::operator=(empty); 1.640 + return temp; 1.641 + } 1.642 + 1.643 +protected: 1.644 + // steal and own are protected because they make no sense on nsReturnRef, 1.645 + // but steal is implemented on this class for access to aOtherRef.disown() 1.646 + // when aOtherRef is an nsReturnRef; 1.647 + 1.648 + // Transfer ownership from another smart reference. 1.649 + void steal(ThisClass& aOtherRef) 1.650 + { 1.651 + own(aOtherRef.disown()); 1.652 + } 1.653 + // Assume ownership of a raw ref. 1.654 + void own(RawRefOnly aRefToRelease) 1.655 + { 1.656 + SafeRelease(); 1.657 + LocalSimpleRef ref(aRefToRelease); 1.658 + SimpleRef::operator=(ref); 1.659 + } 1.660 + 1.661 + // Release a resource if there is one. 1.662 + void SafeRelease() 1.663 + { 1.664 + if (this->HaveResource()) 1.665 + this->Release(this->get()); 1.666 + } 1.667 +}; 1.668 + 1.669 +#endif // !defined(nsAutoRef_h_)