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