|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef nsAutoRef_h_ |
|
8 #define nsAutoRef_h_ |
|
9 |
|
10 #include "mozilla/Attributes.h" |
|
11 |
|
12 #include "nscore.h" // for nullptr, bool |
|
13 |
|
14 template <class T> class nsSimpleRef; |
|
15 template <class T> class nsAutoRefBase; |
|
16 template <class T> class nsReturnRef; |
|
17 template <class T> class nsReturningRef; |
|
18 |
|
19 /** |
|
20 * template <class T> class nsAutoRef |
|
21 * |
|
22 * A class that holds a handle to a resource that must be released. |
|
23 * No reference is added on construction. |
|
24 * |
|
25 * No copy constructor nor copy assignment operators are available, so the |
|
26 * resource will be held until released on destruction or explicitly |
|
27 * |reset()| or transferred through provided methods. |
|
28 * |
|
29 * The publicly available methods are the public methods on this class and its |
|
30 * public base classes |nsAutoRefBase<T>| and |nsSimpleRef<T>|. |
|
31 * |
|
32 * For ref-counted resources see also |nsCountedRef<T>|. |
|
33 * For function return values see |nsReturnRef<T>|. |
|
34 * |
|
35 * For each class |T|, |nsAutoRefTraits<T>| or |nsSimpleRef<T>| must be |
|
36 * specialized to use |nsAutoRef<T>| and |nsCountedRef<T>|. |
|
37 * |
|
38 * @param T A class identifying the type of reference held by the |
|
39 * |nsAutoRef<T>| and the unique set methods for managing references |
|
40 * to the resource (defined by |nsAutoRefTraits<T>| or |
|
41 * |nsSimpleRef<T>|). |
|
42 * |
|
43 * Often this is the class representing the resource. Sometimes a |
|
44 * new possibly-incomplete class may need to be declared. |
|
45 * |
|
46 * |
|
47 * Example: An Automatically closing file descriptor |
|
48 * |
|
49 * // References that are simple integral types (as file-descriptors are) |
|
50 * // usually need a new class to represent the resource and how to handle its |
|
51 * // references. |
|
52 * class nsRawFD; |
|
53 * |
|
54 * // Specializing nsAutoRefTraits<nsRawFD> describes how to manage file |
|
55 * // descriptors, so that nsAutoRef<nsRawFD> provides automatic closing of |
|
56 * // its file descriptor on destruction. |
|
57 * template <> |
|
58 * class nsAutoRefTraits<nsRawFD> { |
|
59 * public: |
|
60 * // The file descriptor is held in an int. |
|
61 * typedef int RawRef; |
|
62 * // -1 means that there is no file associated with the handle. |
|
63 * static int Void() { return -1; } |
|
64 * // The file associated with a file descriptor is released with close(). |
|
65 * static void Release(RawRef aFD) { close(aFD); } |
|
66 * }; |
|
67 * |
|
68 * // A function returning a file descriptor that must be closed. |
|
69 * nsReturnRef<nsRawFD> get_file(const char *filename) { |
|
70 * // Constructing from a raw file descriptor assumes ownership. |
|
71 * nsAutoRef<nsRawFD> fd(open(filename, O_RDONLY)); |
|
72 * fcntl(fd, F_SETFD, FD_CLOEXEC); |
|
73 * return fd.out(); |
|
74 * } |
|
75 * |
|
76 * void f() { |
|
77 * unsigned char buf[1024]; |
|
78 * |
|
79 * // Hold a file descriptor for /etc/hosts in fd1. |
|
80 * nsAutoRef<nsRawFD> fd1(get_file("/etc/hosts")); |
|
81 * |
|
82 * nsAutoRef<nsRawFD> fd2; |
|
83 * fd2.steal(fd1); // fd2 takes the file descriptor from fd1 |
|
84 * ssize_t count = read(fd1, buf, 1024); // error fd1 has no file |
|
85 * count = read(fd2, buf, 1024); // reads from /etc/hosts |
|
86 * |
|
87 * // If the file descriptor is not stored then it is closed. |
|
88 * get_file("/etc/login.defs"); // login.defs is closed |
|
89 * |
|
90 * // Now use fd1 to hold a file descriptor for /etc/passwd. |
|
91 * fd1 = get_file("/etc/passwd"); |
|
92 * |
|
93 * // The nsAutoRef<nsRawFD> can give up the file descriptor if explicitly |
|
94 * // instructed, but the caller must then ensure that the file is closed. |
|
95 * int rawfd = fd1.disown(); |
|
96 * |
|
97 * // Assume ownership of another file descriptor. |
|
98 * fd1.own(open("/proc/1/maps"); |
|
99 * |
|
100 * // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts, |
|
101 * // but /etc/passwd is not closed. |
|
102 * } |
|
103 * |
|
104 */ |
|
105 |
|
106 |
|
107 template <class T> |
|
108 class nsAutoRef : public nsAutoRefBase<T> |
|
109 { |
|
110 protected: |
|
111 typedef nsAutoRef<T> ThisClass; |
|
112 typedef nsAutoRefBase<T> BaseClass; |
|
113 typedef nsSimpleRef<T> SimpleRef; |
|
114 typedef typename BaseClass::RawRefOnly RawRefOnly; |
|
115 typedef typename BaseClass::LocalSimpleRef LocalSimpleRef; |
|
116 |
|
117 public: |
|
118 nsAutoRef() |
|
119 { |
|
120 } |
|
121 |
|
122 // Explicit construction is required so as not to risk unintentionally |
|
123 // releasing the resource associated with a raw ref. |
|
124 explicit nsAutoRef(RawRefOnly aRefToRelease) |
|
125 : BaseClass(aRefToRelease) |
|
126 { |
|
127 } |
|
128 |
|
129 // Construction from a nsReturnRef<T> function return value, which expects |
|
130 // to give up ownership, transfers ownership. |
|
131 // (nsReturnRef<T> is converted to const nsReturningRef<T>.) |
|
132 explicit nsAutoRef(const nsReturningRef<T>& aReturning) |
|
133 : BaseClass(aReturning) |
|
134 { |
|
135 } |
|
136 |
|
137 // The only assignment operator provided is for transferring from an |
|
138 // nsReturnRef smart reference, which expects to pass its ownership to |
|
139 // another object. |
|
140 // |
|
141 // With raw references and other smart references, the type of the lhs and |
|
142 // its taking and releasing nature is often not obvious from an assignment |
|
143 // statement. Assignment from a raw ptr especially is not normally |
|
144 // expected to release the reference. |
|
145 // |
|
146 // Use |steal| for taking ownership from other smart refs. |
|
147 // |
|
148 // For raw references, use |own| to indicate intention to have the |
|
149 // resource released. |
|
150 // |
|
151 // Or, to create another owner of the same reference, use an nsCountedRef. |
|
152 |
|
153 ThisClass& operator=(const nsReturningRef<T>& aReturning) |
|
154 { |
|
155 BaseClass::steal(aReturning.mReturnRef); |
|
156 return *this; |
|
157 } |
|
158 |
|
159 // Conversion to a raw reference allow the nsAutoRef<T> to often be used |
|
160 // like a raw reference. |
|
161 operator typename SimpleRef::RawRef() const |
|
162 { |
|
163 return this->get(); |
|
164 } |
|
165 |
|
166 // Transfer ownership from another smart reference. |
|
167 void steal(ThisClass& aOtherRef) |
|
168 { |
|
169 BaseClass::steal(aOtherRef); |
|
170 } |
|
171 |
|
172 // Assume ownership of a raw ref. |
|
173 // |
|
174 // |own| has similar function to |steal|, and is useful for receiving |
|
175 // ownership from a return value of a function. It is named differently |
|
176 // because |own| requires more care to ensure that the function intends to |
|
177 // give away ownership, and so that |steal| can be safely used, knowing |
|
178 // that it won't steal ownership from any methods returning raw ptrs to |
|
179 // data owned by a foreign object. |
|
180 void own(RawRefOnly aRefToRelease) |
|
181 { |
|
182 BaseClass::own(aRefToRelease); |
|
183 } |
|
184 |
|
185 // Exchange ownership with |aOther| |
|
186 void swap(ThisClass& aOther) |
|
187 { |
|
188 LocalSimpleRef temp; |
|
189 temp.SimpleRef::operator=(*this); |
|
190 SimpleRef::operator=(aOther); |
|
191 aOther.SimpleRef::operator=(temp); |
|
192 } |
|
193 |
|
194 // Release the reference now. |
|
195 void reset() |
|
196 { |
|
197 this->SafeRelease(); |
|
198 LocalSimpleRef empty; |
|
199 SimpleRef::operator=(empty); |
|
200 } |
|
201 |
|
202 // Pass out the reference for a function return values. |
|
203 nsReturnRef<T> out() |
|
204 { |
|
205 return nsReturnRef<T>(this->disown()); |
|
206 } |
|
207 |
|
208 // operator->() and disown() are provided by nsAutoRefBase<T>. |
|
209 // The default nsSimpleRef<T> provides get(). |
|
210 |
|
211 private: |
|
212 // No copy constructor |
|
213 explicit nsAutoRef(ThisClass& aRefToSteal); |
|
214 }; |
|
215 |
|
216 /** |
|
217 * template <class T> class nsCountedRef |
|
218 * |
|
219 * A class that creates (adds) a new reference to a resource on construction |
|
220 * or assignment and releases on destruction. |
|
221 * |
|
222 * This class is similar to nsAutoRef<T> and inherits its methods, but also |
|
223 * provides copy construction and assignment operators that enable more than |
|
224 * one concurrent reference to the same resource. |
|
225 * |
|
226 * Specialize |nsAutoRefTraits<T>| or |nsSimpleRef<T>| to use this. This |
|
227 * class assumes that the resource itself counts references and so can only be |
|
228 * used when |T| represents a reference-counting resource. |
|
229 */ |
|
230 |
|
231 template <class T> |
|
232 class nsCountedRef : public nsAutoRef<T> |
|
233 { |
|
234 protected: |
|
235 typedef nsCountedRef<T> ThisClass; |
|
236 typedef nsAutoRef<T> BaseClass; |
|
237 typedef nsSimpleRef<T> SimpleRef; |
|
238 typedef typename BaseClass::RawRef RawRef; |
|
239 |
|
240 public: |
|
241 nsCountedRef() |
|
242 { |
|
243 } |
|
244 |
|
245 // Construction and assignment from a another nsCountedRef |
|
246 // or a raw ref copies and increments the ref count. |
|
247 nsCountedRef(const ThisClass& aRefToCopy) |
|
248 { |
|
249 SimpleRef::operator=(aRefToCopy); |
|
250 SafeAddRef(); |
|
251 } |
|
252 ThisClass& operator=(const ThisClass& aRefToCopy) |
|
253 { |
|
254 if (this == &aRefToCopy) |
|
255 return *this; |
|
256 |
|
257 this->SafeRelease(); |
|
258 SimpleRef::operator=(aRefToCopy); |
|
259 SafeAddRef(); |
|
260 return *this; |
|
261 } |
|
262 |
|
263 // Implicit conversion from another smart ref argument (to a raw ref) is |
|
264 // accepted here because construction and assignment safely creates a new |
|
265 // reference without interfering with the reference to copy. |
|
266 explicit nsCountedRef(RawRef aRefToCopy) |
|
267 : BaseClass(aRefToCopy) |
|
268 { |
|
269 SafeAddRef(); |
|
270 } |
|
271 ThisClass& operator=(RawRef aRefToCopy) |
|
272 { |
|
273 this->own(aRefToCopy); |
|
274 SafeAddRef(); |
|
275 return *this; |
|
276 } |
|
277 |
|
278 // Construction and assignment from an nsReturnRef function return value, |
|
279 // which expects to give up ownership, transfers ownership. |
|
280 explicit nsCountedRef(const nsReturningRef<T>& aReturning) |
|
281 : BaseClass(aReturning) |
|
282 { |
|
283 } |
|
284 ThisClass& operator=(const nsReturningRef<T>& aReturning) |
|
285 { |
|
286 BaseClass::operator=(aReturning); |
|
287 return *this; |
|
288 } |
|
289 |
|
290 protected: |
|
291 // Increase the reference count if there is a resource. |
|
292 void SafeAddRef() |
|
293 { |
|
294 if (this->HaveResource()) |
|
295 this->AddRef(this->get()); |
|
296 } |
|
297 }; |
|
298 |
|
299 /** |
|
300 * template <class T> class nsReturnRef |
|
301 * |
|
302 * A type for function return values that hold a reference to a resource that |
|
303 * must be released. See also |nsAutoRef<T>::out()|. |
|
304 */ |
|
305 |
|
306 template <class T> |
|
307 class nsReturnRef : public nsAutoRefBase<T> |
|
308 { |
|
309 protected: |
|
310 typedef nsAutoRefBase<T> BaseClass; |
|
311 typedef typename BaseClass::RawRefOnly RawRefOnly; |
|
312 |
|
313 public: |
|
314 // For constructing a return value with no resource |
|
315 nsReturnRef() |
|
316 { |
|
317 } |
|
318 |
|
319 // For returning a smart reference from a raw reference that must be |
|
320 // released. Explicit construction is required so as not to risk |
|
321 // unintentionally releasing the resource associated with a raw ref. |
|
322 explicit nsReturnRef(RawRefOnly aRefToRelease) |
|
323 : BaseClass(aRefToRelease) |
|
324 { |
|
325 } |
|
326 |
|
327 // Copy construction transfers ownership |
|
328 nsReturnRef(nsReturnRef<T>& aRefToSteal) |
|
329 : BaseClass(aRefToSteal) |
|
330 { |
|
331 } |
|
332 |
|
333 nsReturnRef(const nsReturningRef<T>& aReturning) |
|
334 : BaseClass(aReturning) |
|
335 { |
|
336 } |
|
337 |
|
338 // Conversion to a temporary (const) object referring to this object so |
|
339 // that the reference may be passed from a function return value |
|
340 // (temporary) to another smart reference. There is no need to use this |
|
341 // explicitly. Simply assign a nsReturnRef<T> function return value to a |
|
342 // smart reference. |
|
343 operator nsReturningRef<T>() |
|
344 { |
|
345 return nsReturningRef<T>(*this); |
|
346 } |
|
347 |
|
348 // No conversion to RawRef operator is provided on nsReturnRef, to ensure |
|
349 // that the return value is not carelessly assigned to a raw ptr (and the |
|
350 // resource then released). If passing to a function that takes a raw |
|
351 // ptr, use get or disown as appropriate. |
|
352 }; |
|
353 |
|
354 /** |
|
355 * template <class T> class nsReturningRef |
|
356 * |
|
357 * A class to allow ownership to be transferred from nsReturnRef function |
|
358 * return values. |
|
359 * |
|
360 * It should not be necessary for clients to reference this |
|
361 * class directly. Simply pass an nsReturnRef<T> to a parameter taking an |
|
362 * |nsReturningRef<T>|. |
|
363 * |
|
364 * The conversion operator on nsReturnRef constructs a temporary wrapper of |
|
365 * class nsReturningRef<T> around a non-const reference to the nsReturnRef. |
|
366 * The wrapper can then be passed as an rvalue parameter. |
|
367 */ |
|
368 |
|
369 template <class T> |
|
370 class nsReturningRef |
|
371 { |
|
372 private: |
|
373 friend class nsReturnRef<T>; |
|
374 |
|
375 explicit nsReturningRef(nsReturnRef<T>& aReturnRef) |
|
376 : mReturnRef(aReturnRef) |
|
377 { |
|
378 } |
|
379 public: |
|
380 nsReturnRef<T>& mReturnRef; |
|
381 }; |
|
382 |
|
383 /** |
|
384 * template <class T> class nsAutoRefTraits |
|
385 * |
|
386 * A class describing traits of references managed by the default |
|
387 * |nsSimpleRef<T>| implementation and thus |nsAutoRef<T>| and |nsCountedRef|. |
|
388 * The default |nsSimpleRef<T> is suitable for resources with handles that |
|
389 * have a void value. (If there is no such void value for a handle, |
|
390 * specialize |nsSimpleRef<T>|.) |
|
391 * |
|
392 * Specializations must be provided for each class |T| according to the |
|
393 * following pattern: |
|
394 * |
|
395 * // The template parameter |T| should be a class such that the set of fields |
|
396 * // in class nsAutoRefTraits<T> is unique for class |T|. Usually the |
|
397 * // resource object class is sufficient. For handles that are simple |
|
398 * // integral typedefs, a new unique possibly-incomplete class may need to be |
|
399 * // declared. |
|
400 * |
|
401 * template <> |
|
402 * class nsAutoRefTraits<T> |
|
403 * { |
|
404 * // Specializations must provide a typedef for RawRef, describing the |
|
405 * // type of the handle to the resource. |
|
406 * typedef <handle-type> RawRef; |
|
407 * |
|
408 * // Specializations should define Void(), a function returning a value |
|
409 * // suitable for a handle that does not have an associated resource. |
|
410 * // |
|
411 * // The return type must be a suitable as the parameter to a RawRef |
|
412 * // constructor and operator==. |
|
413 * // |
|
414 * // If this method is not accessible then some limited nsAutoRef |
|
415 * // functionality will still be available, but the default constructor, |
|
416 * // |reset|, and most transfer of ownership methods will not be available. |
|
417 * static <return-type> Void(); |
|
418 * |
|
419 * // Specializations must define Release() to properly finalize the |
|
420 * // handle to a non-void custom-deleted or reference-counted resource. |
|
421 * static void Release(RawRef aRawRef); |
|
422 * |
|
423 * // For reference-counted resources, if |nsCountedRef<T>| is to be used, |
|
424 * // specializations must define AddRef to increment the reference count |
|
425 * // held by a non-void handle. |
|
426 * // (AddRef() is not necessary for |nsAutoRef<T>|.) |
|
427 * static void AddRef(RawRef aRawRef); |
|
428 * }; |
|
429 * |
|
430 * See nsPointerRefTraits for example specializations for simple pointer |
|
431 * references. See nsAutoRef for an example specialization for a non-pointer |
|
432 * reference. |
|
433 */ |
|
434 |
|
435 template <class T> class nsAutoRefTraits; |
|
436 |
|
437 /** |
|
438 * template <class T> class nsPointerRefTraits |
|
439 * |
|
440 * A convenience class useful as a base class for specializations of |
|
441 * |nsAutoRefTraits<T>| where the handle to the resource is a pointer to |T|. |
|
442 * By inheriting from this class, definitions of only Release(RawRef) and |
|
443 * possibly AddRef(RawRef) need to be added. |
|
444 * |
|
445 * Examples of use: |
|
446 * |
|
447 * template <> |
|
448 * class nsAutoRefTraits<PRFileDesc> : public nsPointerRefTraits<PRFileDesc> |
|
449 * { |
|
450 * public: |
|
451 * static void Release(PRFileDesc *ptr) { PR_Close(ptr); } |
|
452 * }; |
|
453 * |
|
454 * template <> |
|
455 * class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern> |
|
456 * { |
|
457 * public: |
|
458 * static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); } |
|
459 * static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); } |
|
460 * }; |
|
461 */ |
|
462 |
|
463 template <class T> |
|
464 class nsPointerRefTraits |
|
465 { |
|
466 public: |
|
467 // The handle is a pointer to T. |
|
468 typedef T* RawRef; |
|
469 // A nullptr does not have a resource. |
|
470 static RawRef Void() { return nullptr; } |
|
471 }; |
|
472 |
|
473 /** |
|
474 * template <class T> class nsSimpleRef |
|
475 * |
|
476 * Constructs a non-smart reference, and provides methods to test whether |
|
477 * there is an associated resource and (if so) get its raw handle. |
|
478 * |
|
479 * A default implementation is suitable for resources with handles that have a |
|
480 * void value. This is not intended for direct use but used by |nsAutoRef<T>| |
|
481 * and thus |nsCountedRef<T>|. |
|
482 * |
|
483 * Specialize this class if there is no particular void value for the resource |
|
484 * handle. A specialized implementation must also provide Release(RawRef), |
|
485 * and, if |nsCountedRef<T>| is required, AddRef(RawRef), as described in |
|
486 * nsAutoRefTraits<T>. |
|
487 */ |
|
488 |
|
489 template <class T> |
|
490 class nsSimpleRef : protected nsAutoRefTraits<T> |
|
491 { |
|
492 protected: |
|
493 // The default implementation uses nsAutoRefTrait<T>. |
|
494 // Specializations need not define this typedef. |
|
495 typedef nsAutoRefTraits<T> Traits; |
|
496 // The type of the handle to the resource. |
|
497 // A specialization must provide a typedef for RawRef. |
|
498 typedef typename Traits::RawRef RawRef; |
|
499 |
|
500 // Construct with no resource. |
|
501 // |
|
502 // If this constructor is not accessible then some limited nsAutoRef |
|
503 // functionality will still be available, but the default constructor, |
|
504 // |reset|, and most transfer of ownership methods will not be available. |
|
505 nsSimpleRef() |
|
506 : mRawRef(Traits::Void()) |
|
507 { |
|
508 } |
|
509 // Construct with a handle to a resource. |
|
510 // A specialization must provide this. |
|
511 nsSimpleRef(RawRef aRawRef) |
|
512 : mRawRef(aRawRef) |
|
513 { |
|
514 } |
|
515 |
|
516 // Test whether there is an associated resource. A specialization must |
|
517 // provide this. The function is permitted to always return true if the |
|
518 // default constructor is not accessible, or if Release (and AddRef) can |
|
519 // deal with void handles. |
|
520 bool HaveResource() const |
|
521 { |
|
522 return mRawRef != Traits::Void(); |
|
523 } |
|
524 |
|
525 public: |
|
526 // A specialization must provide get() or loose some functionality. This |
|
527 // is inherited by derived classes and the specialization may choose |
|
528 // whether it is public or protected. |
|
529 RawRef get() const |
|
530 { |
|
531 return mRawRef; |
|
532 } |
|
533 |
|
534 private: |
|
535 RawRef mRawRef; |
|
536 }; |
|
537 |
|
538 |
|
539 /** |
|
540 * template <class T> class nsAutoRefBase |
|
541 * |
|
542 * Internal base class for |nsAutoRef<T>| and |nsReturnRef<T>|. |
|
543 * Adds release on destruction to a |nsSimpleRef<T>|. |
|
544 */ |
|
545 |
|
546 template <class T> |
|
547 class nsAutoRefBase : public nsSimpleRef<T> |
|
548 { |
|
549 protected: |
|
550 typedef nsAutoRefBase<T> ThisClass; |
|
551 typedef nsSimpleRef<T> SimpleRef; |
|
552 typedef typename SimpleRef::RawRef RawRef; |
|
553 |
|
554 nsAutoRefBase() |
|
555 { |
|
556 } |
|
557 |
|
558 // A type for parameters that should be passed a raw ref but should not |
|
559 // accept implicit conversions (from another smart ref). (The only |
|
560 // conversion to this type is from a raw ref so only raw refs will be |
|
561 // accepted.) |
|
562 class RawRefOnly |
|
563 { |
|
564 public: |
|
565 RawRefOnly(RawRef aRawRef) |
|
566 : mRawRef(aRawRef) |
|
567 { |
|
568 } |
|
569 operator RawRef() const |
|
570 { |
|
571 return mRawRef; |
|
572 } |
|
573 private: |
|
574 RawRef mRawRef; |
|
575 }; |
|
576 |
|
577 // Construction from a raw ref assumes ownership |
|
578 explicit nsAutoRefBase(RawRefOnly aRefToRelease) |
|
579 : SimpleRef(aRefToRelease) |
|
580 { |
|
581 } |
|
582 |
|
583 // Constructors that steal ownership |
|
584 explicit nsAutoRefBase(ThisClass& aRefToSteal) |
|
585 : SimpleRef(aRefToSteal.disown()) |
|
586 { |
|
587 } |
|
588 explicit nsAutoRefBase(const nsReturningRef<T>& aReturning) |
|
589 : SimpleRef(aReturning.mReturnRef.disown()) |
|
590 { |
|
591 } |
|
592 |
|
593 ~nsAutoRefBase() |
|
594 { |
|
595 SafeRelease(); |
|
596 } |
|
597 |
|
598 // An internal class providing access to protected nsSimpleRef<T> |
|
599 // constructors for construction of temporary simple references (that are |
|
600 // not ThisClass). |
|
601 class LocalSimpleRef : public SimpleRef |
|
602 { |
|
603 public: |
|
604 LocalSimpleRef() |
|
605 { |
|
606 } |
|
607 explicit LocalSimpleRef(RawRef aRawRef) |
|
608 : SimpleRef(aRawRef) |
|
609 { |
|
610 } |
|
611 }; |
|
612 |
|
613 private: |
|
614 ThisClass& operator=(const ThisClass& aSmartRef) MOZ_DELETE; |
|
615 |
|
616 public: |
|
617 RawRef operator->() const |
|
618 { |
|
619 return this->get(); |
|
620 } |
|
621 |
|
622 // Transfer ownership to a raw reference. |
|
623 // |
|
624 // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED. |
|
625 // |
|
626 // Is this really what you want to use? Using this removes any guarantee |
|
627 // of release. Use nsAutoRef<T>::out() for return values, or an |
|
628 // nsAutoRef<T> modifiable lvalue for an out parameter. Use disown() when |
|
629 // the reference must be stored in a POD type object, such as may be |
|
630 // preferred for a namespace-scope object with static storage duration, |
|
631 // for example. |
|
632 RawRef disown() |
|
633 { |
|
634 RawRef temp = this->get(); |
|
635 LocalSimpleRef empty; |
|
636 SimpleRef::operator=(empty); |
|
637 return temp; |
|
638 } |
|
639 |
|
640 protected: |
|
641 // steal and own are protected because they make no sense on nsReturnRef, |
|
642 // but steal is implemented on this class for access to aOtherRef.disown() |
|
643 // when aOtherRef is an nsReturnRef; |
|
644 |
|
645 // Transfer ownership from another smart reference. |
|
646 void steal(ThisClass& aOtherRef) |
|
647 { |
|
648 own(aOtherRef.disown()); |
|
649 } |
|
650 // Assume ownership of a raw ref. |
|
651 void own(RawRefOnly aRefToRelease) |
|
652 { |
|
653 SafeRelease(); |
|
654 LocalSimpleRef ref(aRefToRelease); |
|
655 SimpleRef::operator=(ref); |
|
656 } |
|
657 |
|
658 // Release a resource if there is one. |
|
659 void SafeRelease() |
|
660 { |
|
661 if (this->HaveResource()) |
|
662 this->Release(this->get()); |
|
663 } |
|
664 }; |
|
665 |
|
666 #endif // !defined(nsAutoRef_h_) |