@@ -150,18 +150,18 @@ fn main() {
150150
151151#![ stable]
152152
153- use core:: mem:: transmute;
154153use core:: cell:: Cell ;
155154use core:: clone:: Clone ;
156155use core:: cmp:: { PartialEq , PartialOrd , Eq , Ord , Ordering } ;
157156use core:: default:: Default ;
157+ use core:: fmt;
158158use core:: kinds:: marker;
159+ use core:: mem:: { transmute, min_align_of, size_of, forget} ;
159160use core:: ops:: { Deref , Drop } ;
160161use core:: option:: { Option , Some , None } ;
161162use core:: ptr;
162163use core:: ptr:: RawPtr ;
163- use core:: mem:: { min_align_of, size_of} ;
164- use core:: fmt;
164+ use core:: result:: { Result , Ok , Err } ;
165165
166166use heap:: deallocate;
167167
@@ -218,6 +218,76 @@ impl<T> Rc<T> {
218218 }
219219}
220220
221+ /// Returns true if the `Rc` currently has unique ownership.
222+ ///
223+ /// Unique ownership means that there are no other `Rc` or `Weak` values
224+ /// that share the same contents.
225+ #[ inline]
226+ #[ experimental]
227+ pub fn is_unique < T > ( rc : & Rc < T > ) -> bool {
228+ // note that we hold both a strong and a weak reference
229+ rc. strong ( ) == 1 && rc. weak ( ) == 1
230+ }
231+
232+ /// Unwraps the contained value if the `Rc` has unique ownership.
233+ ///
234+ /// If the `Rc` does not have unique ownership, `Err` is returned with the
235+ /// same `Rc`.
236+ ///
237+ /// # Example:
238+ ///
239+ /// ```
240+ /// use std::rc::{mod, Rc};
241+ /// let x = Rc::new(3u);
242+ /// assert_eq!(rc::try_unwrap(x), Ok(3u));
243+ /// let x = Rc::new(4u);
244+ /// let _y = x.clone();
245+ /// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4u)));
246+ /// ```
247+ #[ inline]
248+ #[ experimental]
249+ pub fn try_unwrap < T > ( rc : Rc < T > ) -> Result < T , Rc < T > > {
250+ if is_unique ( & rc) {
251+ unsafe {
252+ let val = ptr:: read ( & * rc) ; // copy the contained object
253+ // destruct the box and skip our Drop
254+ // we can ignore the refcounts because we know we're unique
255+ deallocate ( rc. _ptr as * mut u8 , size_of :: < RcBox < T > > ( ) ,
256+ min_align_of :: < RcBox < T > > ( ) ) ;
257+ forget ( rc) ;
258+ Ok ( val)
259+ }
260+ } else {
261+ Err ( rc)
262+ }
263+ }
264+
265+ /// Returns a mutable reference to the contained value if the `Rc` has
266+ /// unique ownership.
267+ ///
268+ /// Returns `None` if the `Rc` does not have unique ownership.
269+ ///
270+ /// # Example:
271+ ///
272+ /// ```
273+ /// use std::rc::{mod, Rc};
274+ /// let mut x = Rc::new(3u);
275+ /// *rc::get_mut(&mut x).unwrap() = 4u;
276+ /// assert_eq!(*x, 4u);
277+ /// let _y = x.clone();
278+ /// assert!(rc::get_mut(&mut x).is_none());
279+ /// ```
280+ #[ inline]
281+ #[ experimental]
282+ pub fn get_mut < ' a , T > ( rc : & ' a mut Rc < T > ) -> Option < & ' a mut T > {
283+ if is_unique ( rc) {
284+ let inner = unsafe { & mut * rc. _ptr } ;
285+ Some ( & mut inner. value )
286+ } else {
287+ None
288+ }
289+ }
290+
221291impl < T : Clone > Rc < T > {
222292 /// Acquires a mutable pointer to the inner contents by guaranteeing that
223293 /// the reference count is one (no sharing is possible).
@@ -227,11 +297,8 @@ impl<T: Clone> Rc<T> {
227297 #[ inline]
228298 #[ experimental]
229299 pub fn make_unique ( & mut self ) -> & mut T {
230- // Note that we hold a strong reference, which also counts as
231- // a weak reference, so we only clone if there is an
232- // additional reference of either kind.
233- if self . strong ( ) != 1 || self . weak ( ) != 1 {
234- * self = Rc :: new ( self . deref ( ) . clone ( ) )
300+ if !is_unique ( self ) {
301+ * self = Rc :: new ( ( * * self ) . clone ( ) )
235302 }
236303 // This unsafety is ok because we're guaranteed that the pointer
237304 // returned is the *only* pointer that will ever be returned to T. Our
@@ -260,7 +327,7 @@ impl<T> Drop for Rc<T> {
260327 if !self . _ptr . is_null ( ) {
261328 self . dec_strong ( ) ;
262329 if self . strong ( ) == 0 {
263- ptr:: read ( self . deref ( ) ) ; // destroy the contained object
330+ ptr:: read ( & * * self ) ; // destroy the contained object
264331
265332 // remove the implicit "strong weak" pointer now
266333 // that we've destroyed the contents.
@@ -427,6 +494,7 @@ mod tests {
427494 use super :: { Rc , Weak } ;
428495 use std:: cell:: RefCell ;
429496 use std:: option:: { Option , Some , None } ;
497+ use std:: result:: { Err , Ok } ;
430498 use std:: mem:: drop;
431499 use std:: clone:: Clone ;
432500
@@ -494,6 +562,45 @@ mod tests {
494562 // hopefully we don't double-free (or leak)...
495563 }
496564
565+ #[ test]
566+ fn is_unique ( ) {
567+ let x = Rc :: new ( 3 u) ;
568+ assert ! ( super :: is_unique( & x) ) ;
569+ let y = x. clone ( ) ;
570+ assert ! ( !super :: is_unique( & x) ) ;
571+ drop ( y) ;
572+ assert ! ( super :: is_unique( & x) ) ;
573+ let w = x. downgrade ( ) ;
574+ assert ! ( !super :: is_unique( & x) ) ;
575+ drop ( w) ;
576+ assert ! ( super :: is_unique( & x) ) ;
577+ }
578+
579+ #[ test]
580+ fn try_unwrap ( ) {
581+ let x = Rc :: new ( 3 u) ;
582+ assert_eq ! ( super :: try_unwrap( x) , Ok ( 3 u) ) ;
583+ let x = Rc :: new ( 4 u) ;
584+ let _y = x. clone ( ) ;
585+ assert_eq ! ( super :: try_unwrap( x) , Err ( Rc :: new( 4 u) ) ) ;
586+ let x = Rc :: new ( 5 u) ;
587+ let _w = x. downgrade ( ) ;
588+ assert_eq ! ( super :: try_unwrap( x) , Err ( Rc :: new( 5 u) ) ) ;
589+ }
590+
591+ #[ test]
592+ fn get_mut ( ) {
593+ let mut x = Rc :: new ( 3 u) ;
594+ * super :: get_mut ( & mut x) . unwrap ( ) = 4 u;
595+ assert_eq ! ( * x, 4 u) ;
596+ let y = x. clone ( ) ;
597+ assert ! ( super :: get_mut( & mut x) . is_none( ) ) ;
598+ drop ( y) ;
599+ assert ! ( super :: get_mut( & mut x) . is_some( ) ) ;
600+ let _w = x. downgrade ( ) ;
601+ assert ! ( super :: get_mut( & mut x) . is_none( ) ) ;
602+ }
603+
497604 #[ test]
498605 fn test_cowrc_clone_make_unique ( ) {
499606 let mut cow0 = Rc :: new ( 75 u) ;
0 commit comments