]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
e9174d1e SL |
11 | #![allow(deprecated)] |
12 | ||
1a4d82fc JJ |
13 | //! Thread-local reference-counted boxes (the `Rc<T>` type). |
14 | //! | |
15 | //! The `Rc<T>` type provides shared ownership of an immutable value. | |
16 | //! Destruction is deterministic, and will occur as soon as the last owner is | |
17 | //! gone. It is marked as non-sendable because it avoids the overhead of atomic | |
18 | //! reference counting. | |
19 | //! | |
20 | //! The `downgrade` method can be used to create a non-owning `Weak<T>` pointer | |
21 | //! to the box. A `Weak<T>` pointer can be upgraded to an `Rc<T>` pointer, but | |
22 | //! will return `None` if the value has already been dropped. | |
23 | //! | |
24 | //! For example, a tree with parent pointers can be represented by putting the | |
25 | //! nodes behind strong `Rc<T>` pointers, and then storing the parent pointers | |
26 | //! as `Weak<T>` pointers. | |
27 | //! | |
28 | //! # Examples | |
29 | //! | |
30 | //! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. | |
31 | //! We want to have our `Gadget`s point to their `Owner`. We can't do this with | |
32 | //! unique ownership, because more than one gadget may belong to the same | |
33 | //! `Owner`. `Rc<T>` allows us to share an `Owner` between multiple `Gadget`s, | |
34 | //! and have the `Owner` remain allocated as long as any `Gadget` points at it. | |
35 | //! | |
36 | //! ```rust | |
37 | //! use std::rc::Rc; | |
38 | //! | |
39 | //! struct Owner { | |
40 | //! name: String | |
41 | //! // ...other fields | |
42 | //! } | |
43 | //! | |
44 | //! struct Gadget { | |
85aaf69f | 45 | //! id: i32, |
1a4d82fc JJ |
46 | //! owner: Rc<Owner> |
47 | //! // ...other fields | |
48 | //! } | |
49 | //! | |
50 | //! fn main() { | |
51 | //! // Create a reference counted Owner. | |
52 | //! let gadget_owner : Rc<Owner> = Rc::new( | |
e9174d1e | 53 | //! Owner { name: String::from("Gadget Man") } |
1a4d82fc JJ |
54 | //! ); |
55 | //! | |
56 | //! // Create Gadgets belonging to gadget_owner. To increment the reference | |
57 | //! // count we clone the `Rc<T>` object. | |
58 | //! let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() }; | |
59 | //! let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() }; | |
60 | //! | |
61 | //! drop(gadget_owner); | |
62 | //! | |
c34b1796 AL |
63 | //! // Despite dropping gadget_owner, we're still able to print out the name |
64 | //! // of the Owner of the Gadgets. This is because we've only dropped the | |
1a4d82fc | 65 | //! // reference count object, not the Owner it wraps. As long as there are |
c34b1796 AL |
66 | //! // other `Rc<T>` objects pointing at the same Owner, it will remain |
67 | //! // allocated. Notice that the `Rc<T>` wrapper around Gadget.owner gets | |
68 | //! // automatically dereferenced for us. | |
1a4d82fc JJ |
69 | //! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name); |
70 | //! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name); | |
71 | //! | |
72 | //! // At the end of the method, gadget1 and gadget2 get destroyed, and with | |
73 | //! // them the last counted references to our Owner. Gadget Man now gets | |
74 | //! // destroyed as well. | |
75 | //! } | |
76 | //! ``` | |
77 | //! | |
c34b1796 AL |
78 | //! If our requirements change, and we also need to be able to traverse from |
79 | //! Owner → Gadget, we will run into problems: an `Rc<T>` pointer from Owner | |
80 | //! → Gadget introduces a cycle between the objects. This means that their | |
81 | //! reference counts can never reach 0, and the objects will remain allocated: a | |
82 | //! memory leak. In order to get around this, we can use `Weak<T>` pointers. | |
83 | //! These pointers don't contribute to the total count. | |
1a4d82fc | 84 | //! |
c34b1796 AL |
85 | //! Rust actually makes it somewhat difficult to produce this loop in the first |
86 | //! place: in order to end up with two objects that point at each other, one of | |
87 | //! them needs to be mutable. This is problematic because `Rc<T>` enforces | |
88 | //! memory safety by only giving out shared references to the object it wraps, | |
89 | //! and these don't allow direct mutation. We need to wrap the part of the | |
90 | //! object we wish to mutate in a `RefCell`, which provides *interior | |
91 | //! mutability*: a method to achieve mutability through a shared reference. | |
92 | //! `RefCell` enforces Rust's borrowing rules at runtime. Read the `Cell` | |
93 | //! documentation for more details on interior mutability. | |
1a4d82fc JJ |
94 | //! |
95 | //! ```rust | |
96 | //! use std::rc::Rc; | |
97 | //! use std::rc::Weak; | |
98 | //! use std::cell::RefCell; | |
99 | //! | |
100 | //! struct Owner { | |
101 | //! name: String, | |
e9174d1e | 102 | //! gadgets: RefCell<Vec<Weak<Gadget>>>, |
1a4d82fc JJ |
103 | //! // ...other fields |
104 | //! } | |
105 | //! | |
106 | //! struct Gadget { | |
85aaf69f | 107 | //! id: i32, |
e9174d1e | 108 | //! owner: Rc<Owner>, |
1a4d82fc JJ |
109 | //! // ...other fields |
110 | //! } | |
111 | //! | |
112 | //! fn main() { | |
113 | //! // Create a reference counted Owner. Note the fact that we've put the | |
114 | //! // Owner's vector of Gadgets inside a RefCell so that we can mutate it | |
115 | //! // through a shared reference. | |
116 | //! let gadget_owner : Rc<Owner> = Rc::new( | |
e9174d1e SL |
117 | //! Owner { |
118 | //! name: "Gadget Man".to_string(), | |
119 | //! gadgets: RefCell::new(Vec::new()), | |
120 | //! } | |
1a4d82fc JJ |
121 | //! ); |
122 | //! | |
123 | //! // Create Gadgets belonging to gadget_owner as before. | |
124 | //! let gadget1 = Rc::new(Gadget{id: 1, owner: gadget_owner.clone()}); | |
125 | //! let gadget2 = Rc::new(Gadget{id: 2, owner: gadget_owner.clone()}); | |
126 | //! | |
127 | //! // Add the Gadgets to their Owner. To do this we mutably borrow from | |
128 | //! // the RefCell holding the Owner's Gadgets. | |
e9174d1e SL |
129 | //! gadget_owner.gadgets.borrow_mut().push(Rc::downgrade(&gadget1)); |
130 | //! gadget_owner.gadgets.borrow_mut().push(Rc::downgrade(&gadget2)); | |
1a4d82fc JJ |
131 | //! |
132 | //! // Iterate over our Gadgets, printing their details out | |
133 | //! for gadget_opt in gadget_owner.gadgets.borrow().iter() { | |
134 | //! | |
135 | //! // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee | |
c34b1796 AL |
136 | //! // that their object is still allocated, we need to call upgrade() |
137 | //! // on them to turn them into a strong reference. This returns an | |
138 | //! // Option, which contains a reference to our object if it still | |
139 | //! // exists. | |
1a4d82fc JJ |
140 | //! let gadget = gadget_opt.upgrade().unwrap(); |
141 | //! println!("Gadget {} owned by {}", gadget.id, gadget.owner.name); | |
142 | //! } | |
143 | //! | |
144 | //! // At the end of the method, gadget_owner, gadget1 and gadget2 get | |
145 | //! // destroyed. There are now no strong (`Rc<T>`) references to the gadgets. | |
146 | //! // Once they get destroyed, the Gadgets get destroyed. This zeroes the | |
62682a34 | 147 | //! // reference count on Gadget Man, they get destroyed as well. |
1a4d82fc JJ |
148 | //! } |
149 | //! ``` | |
150 | ||
85aaf69f | 151 | #![stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 152 | |
c34b1796 | 153 | #[cfg(not(test))] |
62682a34 | 154 | use boxed::Box; |
c34b1796 | 155 | #[cfg(test)] |
62682a34 SL |
156 | use std::boxed::Box; |
157 | ||
e9174d1e | 158 | use core::borrow; |
1a4d82fc | 159 | use core::cell::Cell; |
62682a34 | 160 | use core::cmp::Ordering; |
1a4d82fc | 161 | use core::fmt; |
85aaf69f | 162 | use core::hash::{Hasher, Hash}; |
92a42be0 SL |
163 | use core::intrinsics::{assume, abort}; |
164 | use core::marker; | |
165 | #[cfg(not(stage0))] | |
166 | use core::marker::Unsize; | |
e9174d1e | 167 | use core::mem::{self, align_of_val, size_of_val, forget}; |
92a42be0 SL |
168 | use core::ops::Deref; |
169 | #[cfg(not(stage0))] | |
170 | use core::ops::CoerceUnsized; | |
b039eaaf | 171 | use core::ptr::{self, Shared}; |
92a42be0 | 172 | use core::convert::From; |
d9579d0f | 173 | |
1a4d82fc JJ |
174 | use heap::deallocate; |
175 | ||
d9579d0f | 176 | struct RcBox<T: ?Sized> { |
85aaf69f | 177 | strong: Cell<usize>, |
d9579d0f AL |
178 | weak: Cell<usize>, |
179 | value: T, | |
1a4d82fc JJ |
180 | } |
181 | ||
d9579d0f | 182 | |
85aaf69f | 183 | /// A reference-counted pointer type over an immutable value. |
1a4d82fc | 184 | /// |
85aaf69f | 185 | /// See the [module level documentation](./index.html) for more details. |
d9579d0f AL |
186 | #[unsafe_no_drop_flag] |
187 | #[stable(feature = "rust1", since = "1.0.0")] | |
188 | pub struct Rc<T: ?Sized> { | |
189 | // FIXME #12808: strange names to try to avoid interfering with field | |
190 | // accesses of the contained type via Deref | |
b039eaaf | 191 | _ptr: Shared<RcBox<T>>, |
d9579d0f | 192 | } |
1a4d82fc | 193 | |
92a42be0 | 194 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 195 | impl<T: ?Sized> !marker::Send for Rc<T> {} |
92a42be0 | 196 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f AL |
197 | impl<T: ?Sized> !marker::Sync for Rc<T> {} |
198 | ||
92a42be0 SL |
199 | // remove cfg after new snapshot |
200 | #[cfg(not(stage0))] | |
201 | #[unstable(feature = "coerce_unsized", issue = "27732")] | |
202 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {} | |
d9579d0f | 203 | |
1a4d82fc JJ |
204 | impl<T> Rc<T> { |
205 | /// Constructs a new `Rc<T>`. | |
206 | /// | |
207 | /// # Examples | |
208 | /// | |
209 | /// ``` | |
210 | /// use std::rc::Rc; | |
211 | /// | |
85aaf69f | 212 | /// let five = Rc::new(5); |
1a4d82fc | 213 | /// ``` |
85aaf69f | 214 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
215 | pub fn new(value: T) -> Rc<T> { |
216 | unsafe { | |
217 | Rc { | |
c34b1796 AL |
218 | // there is an implicit weak pointer owned by all the strong |
219 | // pointers, which ensures that the weak destructor never frees | |
220 | // the allocation while the strong destructor is running, even | |
221 | // if the weak pointer is stored inside the strong one. | |
b039eaaf | 222 | _ptr: Shared::new(Box::into_raw(box RcBox { |
1a4d82fc | 223 | strong: Cell::new(1), |
d9579d0f | 224 | weak: Cell::new(1), |
b039eaaf | 225 | value: value, |
1a4d82fc | 226 | })), |
1a4d82fc JJ |
227 | } |
228 | } | |
229 | } | |
62682a34 | 230 | |
e9174d1e SL |
231 | /// Unwraps the contained value if the `Rc<T>` has only one strong reference. |
232 | /// This will succeed even if there are outstanding weak references. | |
62682a34 | 233 | /// |
e9174d1e | 234 | /// Otherwise, an `Err` is returned with the same `Rc<T>`. |
62682a34 SL |
235 | /// |
236 | /// # Examples | |
237 | /// | |
238 | /// ``` | |
62682a34 SL |
239 | /// use std::rc::Rc; |
240 | /// | |
241 | /// let x = Rc::new(3); | |
242 | /// assert_eq!(Rc::try_unwrap(x), Ok(3)); | |
243 | /// | |
244 | /// let x = Rc::new(4); | |
245 | /// let _y = x.clone(); | |
246 | /// assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); | |
247 | /// ``` | |
248 | #[inline] | |
e9174d1e SL |
249 | #[stable(feature = "rc_unique", since = "1.4.0")] |
250 | pub fn try_unwrap(this: Self) -> Result<T, Self> { | |
251 | if Rc::would_unwrap(&this) { | |
62682a34 | 252 | unsafe { |
e9174d1e SL |
253 | let val = ptr::read(&*this); // copy the contained object |
254 | ||
255 | // Indicate to Weaks that they can't be promoted by decrememting | |
256 | // the strong count, and then remove the implicit "strong weak" | |
257 | // pointer while also handling drop logic by just crafting a | |
258 | // fake Weak. | |
259 | this.dec_strong(); | |
260 | let _weak = Weak { _ptr: this._ptr }; | |
261 | forget(this); | |
62682a34 SL |
262 | Ok(val) |
263 | } | |
264 | } else { | |
e9174d1e | 265 | Err(this) |
62682a34 SL |
266 | } |
267 | } | |
e9174d1e SL |
268 | |
269 | /// Checks if `Rc::try_unwrap` would return `Ok`. | |
270 | #[unstable(feature = "rc_would_unwrap", | |
271 | reason = "just added for niche usecase", | |
272 | issue = "28356")] | |
273 | pub fn would_unwrap(this: &Self) -> bool { | |
274 | Rc::strong_count(&this) == 1 | |
275 | } | |
d9579d0f | 276 | } |
1a4d82fc | 277 | |
d9579d0f AL |
278 | impl<T: ?Sized> Rc<T> { |
279 | /// Downgrades the `Rc<T>` to a `Weak<T>` reference. | |
280 | /// | |
281 | /// # Examples | |
282 | /// | |
283 | /// ``` | |
d9579d0f AL |
284 | /// use std::rc::Rc; |
285 | /// | |
286 | /// let five = Rc::new(5); | |
287 | /// | |
e9174d1e | 288 | /// let weak_five = Rc::downgrade(&five); |
d9579d0f | 289 | /// ``` |
e9174d1e SL |
290 | #[stable(feature = "rc_weak", since = "1.4.0")] |
291 | pub fn downgrade(this: &Self) -> Weak<T> { | |
292 | this.inc_weak(); | |
293 | Weak { _ptr: this._ptr } | |
d9579d0f | 294 | } |
d9579d0f | 295 | |
62682a34 SL |
296 | /// Get the number of weak references to this value. |
297 | #[inline] | |
e9174d1e SL |
298 | #[unstable(feature = "rc_counts", reason = "not clearly useful", |
299 | issue = "28356")] | |
b039eaaf SL |
300 | pub fn weak_count(this: &Self) -> usize { |
301 | this.weak() - 1 | |
302 | } | |
62682a34 SL |
303 | |
304 | /// Get the number of strong references to this value. | |
305 | #[inline] | |
e9174d1e SL |
306 | #[unstable(feature = "rc_counts", reason = "not clearly useful", |
307 | issue = "28356")] | |
b039eaaf SL |
308 | pub fn strong_count(this: &Self) -> usize { |
309 | this.strong() | |
310 | } | |
62682a34 SL |
311 | |
312 | /// Returns true if there are no other `Rc` or `Weak<T>` values that share | |
313 | /// the same inner value. | |
1a4d82fc JJ |
314 | /// |
315 | /// # Examples | |
316 | /// | |
317 | /// ``` | |
e9174d1e | 318 | /// #![feature(rc_counts)] |
c1a9b12d | 319 | /// |
1a4d82fc JJ |
320 | /// use std::rc::Rc; |
321 | /// | |
85aaf69f | 322 | /// let five = Rc::new(5); |
1a4d82fc | 323 | /// |
62682a34 | 324 | /// assert!(Rc::is_unique(&five)); |
1a4d82fc | 325 | /// ``` |
62682a34 | 326 | #[inline] |
e9174d1e SL |
327 | #[unstable(feature = "rc_counts", reason = "uniqueness has unclear meaning", |
328 | issue = "28356")] | |
329 | pub fn is_unique(this: &Self) -> bool { | |
330 | Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1 | |
62682a34 SL |
331 | } |
332 | ||
e9174d1e SL |
333 | /// Returns a mutable reference to the contained value if the `Rc<T>` has |
334 | /// one strong reference and no weak references. | |
62682a34 SL |
335 | /// |
336 | /// Returns `None` if the `Rc<T>` is not unique. | |
337 | /// | |
338 | /// # Examples | |
339 | /// | |
340 | /// ``` | |
62682a34 SL |
341 | /// use std::rc::Rc; |
342 | /// | |
343 | /// let mut x = Rc::new(3); | |
344 | /// *Rc::get_mut(&mut x).unwrap() = 4; | |
345 | /// assert_eq!(*x, 4); | |
346 | /// | |
347 | /// let _y = x.clone(); | |
348 | /// assert!(Rc::get_mut(&mut x).is_none()); | |
349 | /// ``` | |
350 | #[inline] | |
e9174d1e SL |
351 | #[stable(feature = "rc_unique", since = "1.4.0")] |
352 | pub fn get_mut(this: &mut Self) -> Option<&mut T> { | |
353 | if Rc::is_unique(this) { | |
354 | let inner = unsafe { &mut **this._ptr }; | |
62682a34 SL |
355 | Some(&mut inner.value) |
356 | } else { | |
357 | None | |
358 | } | |
1a4d82fc JJ |
359 | } |
360 | } | |
361 | ||
1a4d82fc | 362 | impl<T: Clone> Rc<T> { |
e9174d1e SL |
363 | #[inline] |
364 | #[unstable(feature = "rc_make_unique", reason = "renamed to Rc::make_mut", | |
365 | issue = "27718")] | |
92a42be0 | 366 | #[rustc_deprecated(since = "1.4.0", reason = "renamed to Rc::make_mut")] |
e9174d1e SL |
367 | pub fn make_unique(&mut self) -> &mut T { |
368 | Rc::make_mut(self) | |
369 | } | |
370 | ||
371 | /// Make a mutable reference into the given `Rc<T>` by cloning the inner | |
372 | /// data if the `Rc<T>` doesn't have one strong reference and no weak | |
373 | /// references. | |
1a4d82fc | 374 | /// |
e9174d1e | 375 | /// This is also referred to as a copy-on-write. |
1a4d82fc JJ |
376 | /// |
377 | /// # Examples | |
378 | /// | |
379 | /// ``` | |
380 | /// use std::rc::Rc; | |
381 | /// | |
e9174d1e SL |
382 | /// let mut data = Rc::new(5); |
383 | /// | |
384 | /// *Rc::make_mut(&mut data) += 1; // Won't clone anything | |
385 | /// let mut other_data = data.clone(); // Won't clone inner data | |
386 | /// *Rc::make_mut(&mut data) += 1; // Clones inner data | |
387 | /// *Rc::make_mut(&mut data) += 1; // Won't clone anything | |
388 | /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything | |
389 | /// | |
390 | /// // Note: data and other_data now point to different numbers | |
391 | /// assert_eq!(*data, 8); | |
392 | /// assert_eq!(*other_data, 12); | |
1a4d82fc | 393 | /// |
1a4d82fc JJ |
394 | /// ``` |
395 | #[inline] | |
e9174d1e SL |
396 | #[stable(feature = "rc_unique", since = "1.4.0")] |
397 | pub fn make_mut(this: &mut Self) -> &mut T { | |
398 | if Rc::strong_count(this) != 1 { | |
399 | // Gotta clone the data, there are other Rcs | |
400 | *this = Rc::new((**this).clone()) | |
401 | } else if Rc::weak_count(this) != 0 { | |
402 | // Can just steal the data, all that's left is Weaks | |
403 | unsafe { | |
404 | let mut swap = Rc::new(ptr::read(&(**this._ptr).value)); | |
405 | mem::swap(this, &mut swap); | |
406 | swap.dec_strong(); | |
407 | // Remove implicit strong-weak ref (no need to craft a fake | |
408 | // Weak here -- we know other Weaks can clean up for us) | |
409 | swap.dec_weak(); | |
410 | forget(swap); | |
411 | } | |
1a4d82fc | 412 | } |
c34b1796 AL |
413 | // This unsafety is ok because we're guaranteed that the pointer |
414 | // returned is the *only* pointer that will ever be returned to T. Our | |
415 | // reference count is guaranteed to be 1 at this point, and we required | |
416 | // the `Rc<T>` itself to be `mut`, so we're returning the only possible | |
417 | // reference to the inner value. | |
e9174d1e | 418 | let inner = unsafe { &mut **this._ptr }; |
1a4d82fc JJ |
419 | &mut inner.value |
420 | } | |
421 | } | |
422 | ||
d9579d0f AL |
423 | #[stable(feature = "rust1", since = "1.0.0")] |
424 | impl<T: ?Sized> Deref for Rc<T> { | |
425 | type Target = T; | |
426 | ||
427 | #[inline(always)] | |
428 | fn deref(&self) -> &T { | |
429 | &self.inner().value | |
430 | } | |
431 | } | |
1a4d82fc | 432 | |
d9579d0f AL |
433 | #[stable(feature = "rust1", since = "1.0.0")] |
434 | impl<T: ?Sized> Drop for Rc<T> { | |
435 | /// Drops the `Rc<T>`. | |
436 | /// | |
437 | /// This will decrement the strong reference count. If the strong reference | |
438 | /// count becomes zero and the only other references are `Weak<T>` ones, | |
439 | /// `drop`s the inner value. | |
440 | /// | |
441 | /// # Examples | |
442 | /// | |
443 | /// ``` | |
d9579d0f AL |
444 | /// use std::rc::Rc; |
445 | /// | |
446 | /// { | |
447 | /// let five = Rc::new(5); | |
448 | /// | |
449 | /// // stuff | |
450 | /// | |
451 | /// drop(five); // explicit drop | |
452 | /// } | |
453 | /// { | |
454 | /// let five = Rc::new(5); | |
455 | /// | |
456 | /// // stuff | |
457 | /// | |
458 | /// } // implicit drop | |
459 | /// ``` | |
b039eaaf | 460 | #[unsafe_destructor_blind_to_params] |
d9579d0f AL |
461 | fn drop(&mut self) { |
462 | unsafe { | |
463 | let ptr = *self._ptr; | |
464 | if !(*(&ptr as *const _ as *const *const ())).is_null() && | |
b039eaaf | 465 | ptr as *const () as usize != mem::POST_DROP_USIZE { |
d9579d0f AL |
466 | self.dec_strong(); |
467 | if self.strong() == 0 { | |
468 | // destroy the contained object | |
92a42be0 | 469 | ptr::drop_in_place(&mut (*ptr).value); |
d9579d0f AL |
470 | |
471 | // remove the implicit "strong weak" pointer now that we've | |
472 | // destroyed the contents. | |
473 | self.dec_weak(); | |
474 | ||
475 | if self.weak() == 0 { | |
b039eaaf | 476 | deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr)) |
d9579d0f AL |
477 | } |
478 | } | |
479 | } | |
480 | } | |
481 | } | |
482 | } | |
483 | ||
d9579d0f AL |
484 | #[stable(feature = "rust1", since = "1.0.0")] |
485 | impl<T: ?Sized> Clone for Rc<T> { | |
d9579d0f AL |
486 | /// Makes a clone of the `Rc<T>`. |
487 | /// | |
488 | /// When you clone an `Rc<T>`, it will create another pointer to the data and | |
489 | /// increase the strong reference counter. | |
490 | /// | |
491 | /// # Examples | |
492 | /// | |
493 | /// ``` | |
d9579d0f AL |
494 | /// use std::rc::Rc; |
495 | /// | |
496 | /// let five = Rc::new(5); | |
497 | /// | |
498 | /// five.clone(); | |
499 | /// ``` | |
500 | #[inline] | |
501 | fn clone(&self) -> Rc<T> { | |
502 | self.inc_strong(); | |
503 | Rc { _ptr: self._ptr } | |
504 | } | |
505 | } | |
1a4d82fc | 506 | |
85aaf69f | 507 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
508 | impl<T: Default> Default for Rc<T> { |
509 | /// Creates a new `Rc<T>`, with the `Default` value for `T`. | |
510 | /// | |
511 | /// # Examples | |
512 | /// | |
513 | /// ``` | |
514 | /// use std::rc::Rc; | |
1a4d82fc | 515 | /// |
85aaf69f | 516 | /// let x: Rc<i32> = Default::default(); |
1a4d82fc JJ |
517 | /// ``` |
518 | #[inline] | |
1a4d82fc JJ |
519 | fn default() -> Rc<T> { |
520 | Rc::new(Default::default()) | |
521 | } | |
522 | } | |
523 | ||
85aaf69f | 524 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 525 | impl<T: ?Sized + PartialEq> PartialEq for Rc<T> { |
1a4d82fc JJ |
526 | /// Equality for two `Rc<T>`s. |
527 | /// | |
528 | /// Two `Rc<T>`s are equal if their inner value are equal. | |
529 | /// | |
530 | /// # Examples | |
531 | /// | |
532 | /// ``` | |
533 | /// use std::rc::Rc; | |
534 | /// | |
85aaf69f | 535 | /// let five = Rc::new(5); |
1a4d82fc | 536 | /// |
85aaf69f | 537 | /// five == Rc::new(5); |
1a4d82fc JJ |
538 | /// ``` |
539 | #[inline(always)] | |
b039eaaf SL |
540 | fn eq(&self, other: &Rc<T>) -> bool { |
541 | **self == **other | |
542 | } | |
1a4d82fc JJ |
543 | |
544 | /// Inequality for two `Rc<T>`s. | |
545 | /// | |
546 | /// Two `Rc<T>`s are unequal if their inner value are unequal. | |
547 | /// | |
548 | /// # Examples | |
549 | /// | |
550 | /// ``` | |
551 | /// use std::rc::Rc; | |
552 | /// | |
85aaf69f | 553 | /// let five = Rc::new(5); |
1a4d82fc | 554 | /// |
85aaf69f | 555 | /// five != Rc::new(5); |
1a4d82fc JJ |
556 | /// ``` |
557 | #[inline(always)] | |
b039eaaf SL |
558 | fn ne(&self, other: &Rc<T>) -> bool { |
559 | **self != **other | |
560 | } | |
1a4d82fc JJ |
561 | } |
562 | ||
85aaf69f | 563 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 564 | impl<T: ?Sized + Eq> Eq for Rc<T> {} |
1a4d82fc | 565 | |
85aaf69f | 566 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 567 | impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { |
1a4d82fc JJ |
568 | /// Partial comparison for two `Rc<T>`s. |
569 | /// | |
570 | /// The two are compared by calling `partial_cmp()` on their inner values. | |
571 | /// | |
572 | /// # Examples | |
573 | /// | |
574 | /// ``` | |
575 | /// use std::rc::Rc; | |
576 | /// | |
85aaf69f | 577 | /// let five = Rc::new(5); |
1a4d82fc | 578 | /// |
85aaf69f | 579 | /// five.partial_cmp(&Rc::new(5)); |
1a4d82fc JJ |
580 | /// ``` |
581 | #[inline(always)] | |
582 | fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> { | |
583 | (**self).partial_cmp(&**other) | |
584 | } | |
585 | ||
586 | /// Less-than comparison for two `Rc<T>`s. | |
587 | /// | |
588 | /// The two are compared by calling `<` on their inner values. | |
589 | /// | |
590 | /// # Examples | |
591 | /// | |
592 | /// ``` | |
593 | /// use std::rc::Rc; | |
594 | /// | |
85aaf69f | 595 | /// let five = Rc::new(5); |
1a4d82fc | 596 | /// |
85aaf69f | 597 | /// five < Rc::new(5); |
1a4d82fc JJ |
598 | /// ``` |
599 | #[inline(always)] | |
b039eaaf SL |
600 | fn lt(&self, other: &Rc<T>) -> bool { |
601 | **self < **other | |
602 | } | |
1a4d82fc JJ |
603 | |
604 | /// 'Less-than or equal to' comparison for two `Rc<T>`s. | |
605 | /// | |
606 | /// The two are compared by calling `<=` on their inner values. | |
607 | /// | |
608 | /// # Examples | |
609 | /// | |
610 | /// ``` | |
611 | /// use std::rc::Rc; | |
612 | /// | |
85aaf69f | 613 | /// let five = Rc::new(5); |
1a4d82fc | 614 | /// |
85aaf69f | 615 | /// five <= Rc::new(5); |
1a4d82fc JJ |
616 | /// ``` |
617 | #[inline(always)] | |
b039eaaf SL |
618 | fn le(&self, other: &Rc<T>) -> bool { |
619 | **self <= **other | |
620 | } | |
1a4d82fc JJ |
621 | |
622 | /// Greater-than comparison for two `Rc<T>`s. | |
623 | /// | |
624 | /// The two are compared by calling `>` on their inner values. | |
625 | /// | |
626 | /// # Examples | |
627 | /// | |
628 | /// ``` | |
629 | /// use std::rc::Rc; | |
630 | /// | |
85aaf69f | 631 | /// let five = Rc::new(5); |
1a4d82fc | 632 | /// |
85aaf69f | 633 | /// five > Rc::new(5); |
1a4d82fc JJ |
634 | /// ``` |
635 | #[inline(always)] | |
b039eaaf SL |
636 | fn gt(&self, other: &Rc<T>) -> bool { |
637 | **self > **other | |
638 | } | |
1a4d82fc JJ |
639 | |
640 | /// 'Greater-than or equal to' comparison for two `Rc<T>`s. | |
641 | /// | |
642 | /// The two are compared by calling `>=` on their inner values. | |
643 | /// | |
644 | /// # Examples | |
645 | /// | |
646 | /// ``` | |
647 | /// use std::rc::Rc; | |
648 | /// | |
85aaf69f | 649 | /// let five = Rc::new(5); |
1a4d82fc | 650 | /// |
85aaf69f | 651 | /// five >= Rc::new(5); |
1a4d82fc JJ |
652 | /// ``` |
653 | #[inline(always)] | |
b039eaaf SL |
654 | fn ge(&self, other: &Rc<T>) -> bool { |
655 | **self >= **other | |
656 | } | |
1a4d82fc JJ |
657 | } |
658 | ||
85aaf69f | 659 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 660 | impl<T: ?Sized + Ord> Ord for Rc<T> { |
1a4d82fc JJ |
661 | /// Comparison for two `Rc<T>`s. |
662 | /// | |
663 | /// The two are compared by calling `cmp()` on their inner values. | |
664 | /// | |
665 | /// # Examples | |
666 | /// | |
667 | /// ``` | |
668 | /// use std::rc::Rc; | |
669 | /// | |
85aaf69f | 670 | /// let five = Rc::new(5); |
1a4d82fc | 671 | /// |
85aaf69f | 672 | /// five.partial_cmp(&Rc::new(5)); |
1a4d82fc JJ |
673 | /// ``` |
674 | #[inline] | |
b039eaaf SL |
675 | fn cmp(&self, other: &Rc<T>) -> Ordering { |
676 | (**self).cmp(&**other) | |
677 | } | |
1a4d82fc JJ |
678 | } |
679 | ||
d9579d0f | 680 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 681 | impl<T: ?Sized + Hash> Hash for Rc<T> { |
d9579d0f AL |
682 | fn hash<H: Hasher>(&self, state: &mut H) { |
683 | (**self).hash(state); | |
684 | } | |
685 | } | |
1a4d82fc | 686 | |
d9579d0f | 687 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 688 | impl<T: ?Sized + fmt::Display> fmt::Display for Rc<T> { |
d9579d0f AL |
689 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
690 | fmt::Display::fmt(&**self, f) | |
691 | } | |
692 | } | |
1a4d82fc | 693 | |
d9579d0f | 694 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 695 | impl<T: ?Sized + fmt::Debug> fmt::Debug for Rc<T> { |
d9579d0f AL |
696 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
697 | fmt::Debug::fmt(&**self, f) | |
698 | } | |
699 | } | |
1a4d82fc | 700 | |
9346a6ac AL |
701 | #[stable(feature = "rust1", since = "1.0.0")] |
702 | impl<T> fmt::Pointer for Rc<T> { | |
703 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
704 | fmt::Pointer::fmt(&*self._ptr, f) | |
705 | } | |
706 | } | |
707 | ||
92a42be0 SL |
708 | #[stable(feature = "from_for_ptrs", since = "1.6.0")] |
709 | impl<T> From<T> for Rc<T> { | |
710 | fn from(t: T) -> Self { | |
711 | Rc::new(t) | |
712 | } | |
713 | } | |
714 | ||
1a4d82fc JJ |
715 | /// A weak version of `Rc<T>`. |
716 | /// | |
c34b1796 AL |
717 | /// Weak references do not count when determining if the inner value should be |
718 | /// dropped. | |
1a4d82fc | 719 | /// |
85aaf69f | 720 | /// See the [module level documentation](./index.html) for more. |
d9579d0f | 721 | #[unsafe_no_drop_flag] |
e9174d1e | 722 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f AL |
723 | pub struct Weak<T: ?Sized> { |
724 | // FIXME #12808: strange names to try to avoid interfering with | |
725 | // field accesses of the contained type via Deref | |
b039eaaf | 726 | _ptr: Shared<RcBox<T>>, |
d9579d0f | 727 | } |
1a4d82fc | 728 | |
92a42be0 | 729 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 730 | impl<T: ?Sized> !marker::Send for Weak<T> {} |
92a42be0 | 731 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 732 | impl<T: ?Sized> !marker::Sync for Weak<T> {} |
85aaf69f | 733 | |
92a42be0 SL |
734 | // remove cfg after new snapshot |
735 | #[cfg(not(stage0))] | |
736 | #[unstable(feature = "coerce_unsized", issue = "27732")] | |
737 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {} | |
c1a9b12d | 738 | |
d9579d0f | 739 | impl<T: ?Sized> Weak<T> { |
d9579d0f AL |
740 | /// Upgrades a weak reference to a strong reference. |
741 | /// | |
742 | /// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible. | |
743 | /// | |
744 | /// Returns `None` if there were no strong references and the data was | |
745 | /// destroyed. | |
746 | /// | |
747 | /// # Examples | |
748 | /// | |
749 | /// ``` | |
d9579d0f AL |
750 | /// use std::rc::Rc; |
751 | /// | |
752 | /// let five = Rc::new(5); | |
753 | /// | |
e9174d1e | 754 | /// let weak_five = Rc::downgrade(&five); |
d9579d0f AL |
755 | /// |
756 | /// let strong_five: Option<Rc<_>> = weak_five.upgrade(); | |
757 | /// ``` | |
e9174d1e | 758 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f AL |
759 | pub fn upgrade(&self) -> Option<Rc<T>> { |
760 | if self.strong() == 0 { | |
761 | None | |
762 | } else { | |
763 | self.inc_strong(); | |
764 | Some(Rc { _ptr: self._ptr }) | |
765 | } | |
766 | } | |
767 | } | |
768 | ||
d9579d0f AL |
769 | #[stable(feature = "rust1", since = "1.0.0")] |
770 | impl<T: ?Sized> Drop for Weak<T> { | |
771 | /// Drops the `Weak<T>`. | |
772 | /// | |
773 | /// This will decrement the weak reference count. | |
774 | /// | |
775 | /// # Examples | |
776 | /// | |
777 | /// ``` | |
d9579d0f AL |
778 | /// use std::rc::Rc; |
779 | /// | |
780 | /// { | |
781 | /// let five = Rc::new(5); | |
e9174d1e | 782 | /// let weak_five = Rc::downgrade(&five); |
d9579d0f AL |
783 | /// |
784 | /// // stuff | |
785 | /// | |
786 | /// drop(weak_five); // explicit drop | |
787 | /// } | |
788 | /// { | |
789 | /// let five = Rc::new(5); | |
e9174d1e | 790 | /// let weak_five = Rc::downgrade(&five); |
d9579d0f AL |
791 | /// |
792 | /// // stuff | |
793 | /// | |
794 | /// } // implicit drop | |
795 | /// ``` | |
796 | fn drop(&mut self) { | |
797 | unsafe { | |
798 | let ptr = *self._ptr; | |
799 | if !(*(&ptr as *const _ as *const *const ())).is_null() && | |
b039eaaf | 800 | ptr as *const () as usize != mem::POST_DROP_USIZE { |
d9579d0f AL |
801 | self.dec_weak(); |
802 | // the weak count starts at 1, and will only go to zero if all | |
803 | // the strong pointers have disappeared. | |
804 | if self.weak() == 0 { | |
b039eaaf | 805 | deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr)) |
d9579d0f AL |
806 | } |
807 | } | |
808 | } | |
809 | } | |
810 | } | |
811 | ||
e9174d1e | 812 | #[stable(feature = "rc_weak", since = "1.4.0")] |
d9579d0f | 813 | impl<T: ?Sized> Clone for Weak<T> { |
d9579d0f AL |
814 | /// Makes a clone of the `Weak<T>`. |
815 | /// | |
816 | /// This increases the weak reference count. | |
817 | /// | |
818 | /// # Examples | |
819 | /// | |
820 | /// ``` | |
d9579d0f AL |
821 | /// use std::rc::Rc; |
822 | /// | |
e9174d1e | 823 | /// let weak_five = Rc::downgrade(&Rc::new(5)); |
d9579d0f AL |
824 | /// |
825 | /// weak_five.clone(); | |
826 | /// ``` | |
827 | #[inline] | |
828 | fn clone(&self) -> Weak<T> { | |
829 | self.inc_weak(); | |
830 | Weak { _ptr: self._ptr } | |
831 | } | |
832 | } | |
1a4d82fc | 833 | |
d9579d0f | 834 | #[stable(feature = "rust1", since = "1.0.0")] |
92a42be0 | 835 | impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> { |
d9579d0f AL |
836 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
837 | write!(f, "(Weak)") | |
838 | } | |
839 | } | |
1a4d82fc | 840 | |
c1a9b12d SL |
841 | // NOTE: We checked_add here to deal with mem::forget safety. In particular |
842 | // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then | |
843 | // you can free the allocation while outstanding Rcs (or Weaks) exist. | |
844 | // We abort because this is such a degenerate scenario that we don't care about | |
845 | // what happens -- no real program should ever experience this. | |
846 | // | |
847 | // This should have negligible overhead since you don't actually need to | |
848 | // clone these much in Rust thanks to ownership and move-semantics. | |
849 | ||
d9579d0f AL |
850 | #[doc(hidden)] |
851 | trait RcBoxPtr<T: ?Sized> { | |
852 | fn inner(&self) -> &RcBox<T>; | |
853 | ||
854 | #[inline] | |
b039eaaf SL |
855 | fn strong(&self) -> usize { |
856 | self.inner().strong.get() | |
857 | } | |
d9579d0f AL |
858 | |
859 | #[inline] | |
c1a9b12d SL |
860 | fn inc_strong(&self) { |
861 | self.inner().strong.set(self.strong().checked_add(1).unwrap_or_else(|| unsafe { abort() })); | |
862 | } | |
d9579d0f AL |
863 | |
864 | #[inline] | |
b039eaaf SL |
865 | fn dec_strong(&self) { |
866 | self.inner().strong.set(self.strong() - 1); | |
867 | } | |
d9579d0f AL |
868 | |
869 | #[inline] | |
b039eaaf SL |
870 | fn weak(&self) -> usize { |
871 | self.inner().weak.get() | |
872 | } | |
d9579d0f AL |
873 | |
874 | #[inline] | |
c1a9b12d SL |
875 | fn inc_weak(&self) { |
876 | self.inner().weak.set(self.weak().checked_add(1).unwrap_or_else(|| unsafe { abort() })); | |
877 | } | |
d9579d0f AL |
878 | |
879 | #[inline] | |
b039eaaf SL |
880 | fn dec_weak(&self) { |
881 | self.inner().weak.set(self.weak() - 1); | |
882 | } | |
d9579d0f | 883 | } |
1a4d82fc | 884 | |
d9579d0f AL |
885 | impl<T: ?Sized> RcBoxPtr<T> for Rc<T> { |
886 | #[inline(always)] | |
887 | fn inner(&self) -> &RcBox<T> { | |
888 | unsafe { | |
889 | // Safe to assume this here, as if it weren't true, we'd be breaking | |
890 | // the contract anyway. | |
891 | // This allows the null check to be elided in the destructor if we | |
892 | // manipulated the reference count in the same function. | |
893 | assume(!(*(&self._ptr as *const _ as *const *const ())).is_null()); | |
85aaf69f SL |
894 | &(**self._ptr) |
895 | } | |
896 | } | |
1a4d82fc JJ |
897 | } |
898 | ||
d9579d0f AL |
899 | impl<T: ?Sized> RcBoxPtr<T> for Weak<T> { |
900 | #[inline(always)] | |
901 | fn inner(&self) -> &RcBox<T> { | |
902 | unsafe { | |
903 | // Safe to assume this here, as if it weren't true, we'd be breaking | |
904 | // the contract anyway. | |
905 | // This allows the null check to be elided in the destructor if we | |
906 | // manipulated the reference count in the same function. | |
907 | assume(!(*(&self._ptr as *const _ as *const *const ())).is_null()); | |
85aaf69f SL |
908 | &(**self._ptr) |
909 | } | |
910 | } | |
1a4d82fc JJ |
911 | } |
912 | ||
913 | #[cfg(test)] | |
1a4d82fc | 914 | mod tests { |
e9174d1e | 915 | use super::{Rc, Weak}; |
c34b1796 | 916 | use std::boxed::Box; |
1a4d82fc JJ |
917 | use std::cell::RefCell; |
918 | use std::option::Option; | |
919 | use std::option::Option::{Some, None}; | |
920 | use std::result::Result::{Err, Ok}; | |
921 | use std::mem::drop; | |
922 | use std::clone::Clone; | |
92a42be0 | 923 | use std::convert::From; |
1a4d82fc JJ |
924 | |
925 | #[test] | |
926 | fn test_clone() { | |
85aaf69f | 927 | let x = Rc::new(RefCell::new(5)); |
1a4d82fc JJ |
928 | let y = x.clone(); |
929 | *x.borrow_mut() = 20; | |
930 | assert_eq!(*y.borrow(), 20); | |
931 | } | |
932 | ||
933 | #[test] | |
934 | fn test_simple() { | |
85aaf69f | 935 | let x = Rc::new(5); |
1a4d82fc JJ |
936 | assert_eq!(*x, 5); |
937 | } | |
938 | ||
939 | #[test] | |
940 | fn test_simple_clone() { | |
85aaf69f | 941 | let x = Rc::new(5); |
1a4d82fc JJ |
942 | let y = x.clone(); |
943 | assert_eq!(*x, 5); | |
944 | assert_eq!(*y, 5); | |
945 | } | |
946 | ||
947 | #[test] | |
948 | fn test_destructor() { | |
c34b1796 | 949 | let x: Rc<Box<_>> = Rc::new(box 5); |
1a4d82fc JJ |
950 | assert_eq!(**x, 5); |
951 | } | |
952 | ||
953 | #[test] | |
954 | fn test_live() { | |
85aaf69f | 955 | let x = Rc::new(5); |
e9174d1e | 956 | let y = Rc::downgrade(&x); |
1a4d82fc JJ |
957 | assert!(y.upgrade().is_some()); |
958 | } | |
959 | ||
960 | #[test] | |
961 | fn test_dead() { | |
85aaf69f | 962 | let x = Rc::new(5); |
e9174d1e | 963 | let y = Rc::downgrade(&x); |
1a4d82fc JJ |
964 | drop(x); |
965 | assert!(y.upgrade().is_none()); | |
966 | } | |
967 | ||
968 | #[test] | |
969 | fn weak_self_cyclic() { | |
970 | struct Cycle { | |
b039eaaf | 971 | x: RefCell<Option<Weak<Cycle>>>, |
1a4d82fc JJ |
972 | } |
973 | ||
974 | let a = Rc::new(Cycle { x: RefCell::new(None) }); | |
e9174d1e | 975 | let b = Rc::downgrade(&a.clone()); |
1a4d82fc JJ |
976 | *a.x.borrow_mut() = Some(b); |
977 | ||
978 | // hopefully we don't double-free (or leak)... | |
979 | } | |
980 | ||
981 | #[test] | |
982 | fn is_unique() { | |
85aaf69f | 983 | let x = Rc::new(3); |
e9174d1e | 984 | assert!(Rc::is_unique(&x)); |
1a4d82fc | 985 | let y = x.clone(); |
e9174d1e | 986 | assert!(!Rc::is_unique(&x)); |
1a4d82fc | 987 | drop(y); |
e9174d1e SL |
988 | assert!(Rc::is_unique(&x)); |
989 | let w = Rc::downgrade(&x); | |
990 | assert!(!Rc::is_unique(&x)); | |
1a4d82fc | 991 | drop(w); |
e9174d1e | 992 | assert!(Rc::is_unique(&x)); |
1a4d82fc JJ |
993 | } |
994 | ||
995 | #[test] | |
996 | fn test_strong_count() { | |
997 | let a = Rc::new(0u32); | |
e9174d1e SL |
998 | assert!(Rc::strong_count(&a) == 1); |
999 | let w = Rc::downgrade(&a); | |
1000 | assert!(Rc::strong_count(&a) == 1); | |
1a4d82fc | 1001 | let b = w.upgrade().expect("upgrade of live rc failed"); |
e9174d1e SL |
1002 | assert!(Rc::strong_count(&b) == 2); |
1003 | assert!(Rc::strong_count(&a) == 2); | |
1a4d82fc JJ |
1004 | drop(w); |
1005 | drop(a); | |
e9174d1e | 1006 | assert!(Rc::strong_count(&b) == 1); |
1a4d82fc | 1007 | let c = b.clone(); |
e9174d1e SL |
1008 | assert!(Rc::strong_count(&b) == 2); |
1009 | assert!(Rc::strong_count(&c) == 2); | |
1a4d82fc JJ |
1010 | } |
1011 | ||
1012 | #[test] | |
1013 | fn test_weak_count() { | |
1014 | let a = Rc::new(0u32); | |
e9174d1e SL |
1015 | assert!(Rc::strong_count(&a) == 1); |
1016 | assert!(Rc::weak_count(&a) == 0); | |
1017 | let w = Rc::downgrade(&a); | |
1018 | assert!(Rc::strong_count(&a) == 1); | |
1019 | assert!(Rc::weak_count(&a) == 1); | |
1a4d82fc | 1020 | drop(w); |
e9174d1e SL |
1021 | assert!(Rc::strong_count(&a) == 1); |
1022 | assert!(Rc::weak_count(&a) == 0); | |
1a4d82fc | 1023 | let c = a.clone(); |
e9174d1e SL |
1024 | assert!(Rc::strong_count(&a) == 2); |
1025 | assert!(Rc::weak_count(&a) == 0); | |
1a4d82fc JJ |
1026 | drop(c); |
1027 | } | |
1028 | ||
1029 | #[test] | |
1030 | fn try_unwrap() { | |
85aaf69f | 1031 | let x = Rc::new(3); |
e9174d1e | 1032 | assert_eq!(Rc::try_unwrap(x), Ok(3)); |
85aaf69f | 1033 | let x = Rc::new(4); |
1a4d82fc | 1034 | let _y = x.clone(); |
e9174d1e | 1035 | assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); |
85aaf69f | 1036 | let x = Rc::new(5); |
e9174d1e SL |
1037 | let _w = Rc::downgrade(&x); |
1038 | assert_eq!(Rc::try_unwrap(x), Ok(5)); | |
1a4d82fc JJ |
1039 | } |
1040 | ||
1041 | #[test] | |
1042 | fn get_mut() { | |
85aaf69f | 1043 | let mut x = Rc::new(3); |
e9174d1e | 1044 | *Rc::get_mut(&mut x).unwrap() = 4; |
85aaf69f | 1045 | assert_eq!(*x, 4); |
1a4d82fc | 1046 | let y = x.clone(); |
e9174d1e | 1047 | assert!(Rc::get_mut(&mut x).is_none()); |
1a4d82fc | 1048 | drop(y); |
e9174d1e SL |
1049 | assert!(Rc::get_mut(&mut x).is_some()); |
1050 | let _w = Rc::downgrade(&x); | |
1051 | assert!(Rc::get_mut(&mut x).is_none()); | |
1a4d82fc JJ |
1052 | } |
1053 | ||
1054 | #[test] | |
1055 | fn test_cowrc_clone_make_unique() { | |
85aaf69f | 1056 | let mut cow0 = Rc::new(75); |
1a4d82fc JJ |
1057 | let mut cow1 = cow0.clone(); |
1058 | let mut cow2 = cow1.clone(); | |
1059 | ||
e9174d1e SL |
1060 | assert!(75 == *Rc::make_mut(&mut cow0)); |
1061 | assert!(75 == *Rc::make_mut(&mut cow1)); | |
1062 | assert!(75 == *Rc::make_mut(&mut cow2)); | |
1a4d82fc | 1063 | |
e9174d1e SL |
1064 | *Rc::make_mut(&mut cow0) += 1; |
1065 | *Rc::make_mut(&mut cow1) += 2; | |
1066 | *Rc::make_mut(&mut cow2) += 3; | |
1a4d82fc JJ |
1067 | |
1068 | assert!(76 == *cow0); | |
1069 | assert!(77 == *cow1); | |
1070 | assert!(78 == *cow2); | |
1071 | ||
1072 | // none should point to the same backing memory | |
1073 | assert!(*cow0 != *cow1); | |
1074 | assert!(*cow0 != *cow2); | |
1075 | assert!(*cow1 != *cow2); | |
1076 | } | |
1077 | ||
1078 | #[test] | |
1079 | fn test_cowrc_clone_unique2() { | |
85aaf69f | 1080 | let mut cow0 = Rc::new(75); |
1a4d82fc JJ |
1081 | let cow1 = cow0.clone(); |
1082 | let cow2 = cow1.clone(); | |
1083 | ||
1084 | assert!(75 == *cow0); | |
1085 | assert!(75 == *cow1); | |
1086 | assert!(75 == *cow2); | |
1087 | ||
e9174d1e | 1088 | *Rc::make_mut(&mut cow0) += 1; |
1a4d82fc JJ |
1089 | |
1090 | assert!(76 == *cow0); | |
1091 | assert!(75 == *cow1); | |
1092 | assert!(75 == *cow2); | |
1093 | ||
1094 | // cow1 and cow2 should share the same contents | |
1095 | // cow0 should have a unique reference | |
1096 | assert!(*cow0 != *cow1); | |
1097 | assert!(*cow0 != *cow2); | |
1098 | assert!(*cow1 == *cow2); | |
1099 | } | |
1100 | ||
1101 | #[test] | |
1102 | fn test_cowrc_clone_weak() { | |
85aaf69f | 1103 | let mut cow0 = Rc::new(75); |
e9174d1e | 1104 | let cow1_weak = Rc::downgrade(&cow0); |
1a4d82fc JJ |
1105 | |
1106 | assert!(75 == *cow0); | |
1107 | assert!(75 == *cow1_weak.upgrade().unwrap()); | |
1108 | ||
e9174d1e | 1109 | *Rc::make_mut(&mut cow0) += 1; |
1a4d82fc JJ |
1110 | |
1111 | assert!(76 == *cow0); | |
1112 | assert!(cow1_weak.upgrade().is_none()); | |
1113 | } | |
1114 | ||
1115 | #[test] | |
1116 | fn test_show() { | |
85aaf69f SL |
1117 | let foo = Rc::new(75); |
1118 | assert_eq!(format!("{:?}", foo), "75"); | |
1a4d82fc JJ |
1119 | } |
1120 | ||
62682a34 SL |
1121 | #[test] |
1122 | fn test_unsized() { | |
1123 | let foo: Rc<[i32]> = Rc::new([1, 2, 3]); | |
1124 | assert_eq!(foo, foo.clone()); | |
1125 | } | |
92a42be0 SL |
1126 | |
1127 | #[test] | |
1128 | fn test_from_owned() { | |
1129 | let foo = 123; | |
1130 | let foo_rc = Rc::from(foo); | |
1131 | assert!(123 == *foo_rc); | |
1132 | } | |
1a4d82fc | 1133 | } |
e9174d1e | 1134 | |
92a42be0 | 1135 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 1136 | impl<T: ?Sized> borrow::Borrow<T> for Rc<T> { |
b039eaaf SL |
1137 | fn borrow(&self) -> &T { |
1138 | &**self | |
1139 | } | |
1140 | } | |
1141 | ||
1142 | #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] | |
1143 | impl<T: ?Sized> AsRef<T> for Rc<T> { | |
1144 | fn as_ref(&self) -> &T { | |
1145 | &**self | |
1146 | } | |
e9174d1e | 1147 | } |