@@ -150,18 +150,18 @@ fn main() {
150
150
151
151
#![ stable]
152
152
153
- use core:: mem:: transmute;
154
153
use core:: cell:: Cell ;
155
154
use core:: clone:: Clone ;
156
155
use core:: cmp:: { PartialEq , PartialOrd , Eq , Ord , Ordering } ;
157
156
use core:: default:: Default ;
157
+ use core:: fmt;
158
158
use core:: kinds:: marker;
159
+ use core:: mem:: { transmute, min_align_of, size_of, forget} ;
159
160
use core:: ops:: { Deref , Drop } ;
160
161
use core:: option:: { Option , Some , None } ;
161
162
use core:: ptr;
162
163
use core:: ptr:: RawPtr ;
163
- use core:: mem:: { min_align_of, size_of} ;
164
- use core:: fmt;
164
+ use core:: result:: { Result , Ok , Err } ;
165
165
166
166
use heap:: deallocate;
167
167
@@ -218,6 +218,76 @@ impl<T> Rc<T> {
218
218
}
219
219
}
220
220
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
+
221
291
impl < T : Clone > Rc < T > {
222
292
/// Acquires a mutable pointer to the inner contents by guaranteeing that
223
293
/// the reference count is one (no sharing is possible).
@@ -227,11 +297,8 @@ impl<T: Clone> Rc<T> {
227
297
#[ inline]
228
298
#[ experimental]
229
299
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 ( ) )
235
302
}
236
303
// This unsafety is ok because we're guaranteed that the pointer
237
304
// returned is the *only* pointer that will ever be returned to T. Our
@@ -260,7 +327,7 @@ impl<T> Drop for Rc<T> {
260
327
if !self . _ptr . is_null ( ) {
261
328
self . dec_strong ( ) ;
262
329
if self . strong ( ) == 0 {
263
- ptr:: read ( self . deref ( ) ) ; // destroy the contained object
330
+ ptr:: read ( & * * self ) ; // destroy the contained object
264
331
265
332
// remove the implicit "strong weak" pointer now
266
333
// that we've destroyed the contents.
@@ -427,6 +494,7 @@ mod tests {
427
494
use super :: { Rc , Weak } ;
428
495
use std:: cell:: RefCell ;
429
496
use std:: option:: { Option , Some , None } ;
497
+ use std:: result:: { Err , Ok } ;
430
498
use std:: mem:: drop;
431
499
use std:: clone:: Clone ;
432
500
@@ -494,6 +562,45 @@ mod tests {
494
562
// hopefully we don't double-free (or leak)...
495
563
}
496
564
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
+
497
604
#[ test]
498
605
fn test_cowrc_clone_make_unique ( ) {
499
606
let mut cow0 = Rc :: new ( 75 u) ;
0 commit comments