@@ -500,6 +500,62 @@ impl<T> Arc<T> {
500
500
Ok ( elem)
501
501
}
502
502
}
503
+
504
+ /// Returns the inner value, if the `Arc` has exactly one strong reference.
505
+ ///
506
+ /// Otherwise, [`None`] is returned and the `Arc` is dropped.
507
+ ///
508
+ /// This will succeed even if there are outstanding weak references.
509
+ ///
510
+ /// If `unwrap_or_drop` is called on every clone of this `Arc`,
511
+ /// it is guaranteed that exactly one of the calls returns the inner value.
512
+ /// The similar expression `Arc::try_unwrap(this).ok()` does not
513
+ /// offer this guarantee.
514
+ ///
515
+ /// # Examples
516
+ ///
517
+ /// ```
518
+ /// #![feature(unwrap_or_drop)]
519
+ ///
520
+ /// use std::sync::Arc;
521
+ ///
522
+ /// let x = Arc::new(3);
523
+ /// let y = Arc::clone(&x);
524
+ ///
525
+ /// let x_unwrap_thread = std::thread::spawn(|| Arc::unwrap_or_drop(x));
526
+ /// let y_unwrap_thread = std::thread::spawn(|| Arc::unwrap_or_drop(y));
527
+ ///
528
+ /// let x_unwrapped_value = x_unwrap_thread.join().unwrap();
529
+ /// let y_unwrapped_value = y_unwrap_thread.join().unwrap();
530
+ ///
531
+ /// assert!(matches!(
532
+ /// (x_unwrapped_value, y_unwrapped_value),
533
+ /// (None, Some(3)) | (Some(3), None)
534
+ /// ));
535
+ /// ```
536
+ #[ inline]
537
+ #[ unstable( feature = "unwrap_or_drop" , issue = "none" ) ] // FIXME: add issue
538
+ // FIXME: should this copy all/some of the comments from drop and drop_slow?
539
+ pub fn unwrap_or_drop ( this : Self ) -> Option < T > {
540
+ // following the implementation of `drop` (and `drop_slow`)
541
+ let mut this = core:: mem:: ManuallyDrop :: new ( this) ;
542
+
543
+ if this. inner ( ) . strong . fetch_sub ( 1 , Release ) != 1 {
544
+ return None ;
545
+ }
546
+
547
+ acquire ! ( this. inner( ) . strong) ;
548
+
549
+ // FIXME: should the part below this be moved into a seperate #[inline(never)]
550
+ // function, like it's done with drop_slow in drop?
551
+
552
+ // using `ptr::read` where `drop_slow` was using `ptr::drop_in_place`
553
+ let inner = unsafe { ptr:: read ( Self :: get_mut_unchecked ( & mut this) ) } ;
554
+
555
+ drop ( Weak { ptr : this. ptr } ) ;
556
+
557
+ Some ( inner)
558
+ }
503
559
}
504
560
505
561
impl < T > Arc < [ T ] > {
0 commit comments