|
16 | 16 | //!
|
17 | 17 | //! [arc]: struct.Arc.html
|
18 | 18 |
|
| 19 | +use core::any::Any; |
19 | 20 | use core::sync::atomic;
|
20 | 21 | use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
|
21 | 22 | use core::borrow;
|
@@ -971,6 +972,49 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
|
971 | 972 | }
|
972 | 973 | }
|
973 | 974 |
|
| 975 | +impl Arc<Any + Send + Sync> { |
| 976 | + #[inline] |
| 977 | + #[unstable(feature = "rc_downcast", issue = "44608")] |
| 978 | + /// Attempt to downcast the `Arc<Any + Send + Sync>` to a concrete type. |
| 979 | + /// |
| 980 | + /// # Examples |
| 981 | + /// |
| 982 | + /// ``` |
| 983 | + /// #![feature(rc_downcast)] |
| 984 | + /// use std::any::Any; |
| 985 | + /// use std::sync::Arc; |
| 986 | + /// |
| 987 | + /// fn print_if_string(value: Arc<Any + Send + Sync>) { |
| 988 | + /// if let Ok(string) = value.downcast::<String>() { |
| 989 | + /// println!("String ({}): {}", string.len(), string); |
| 990 | + /// } |
| 991 | + /// } |
| 992 | + /// |
| 993 | + /// fn main() { |
| 994 | + /// let my_string = "Hello World".to_string(); |
| 995 | + /// print_if_string(Arc::new(my_string)); |
| 996 | + /// print_if_string(Arc::new(0i8)); |
| 997 | + /// } |
| 998 | + /// ``` |
| 999 | + pub fn downcast<T>(self) -> Result<Arc<T>, Self> |
| 1000 | + where |
| 1001 | + T: Any + Send + Sync + 'static, |
| 1002 | + { |
| 1003 | + if (*self).is::<T>() { |
| 1004 | + unsafe { |
| 1005 | + let raw: *const ArcInner<Any + Send + Sync> = self.ptr.as_ptr(); |
| 1006 | + mem::forget(self); |
| 1007 | + Ok(Arc { |
| 1008 | + ptr: NonNull::new_unchecked(raw as *const ArcInner<T> as *mut _), |
| 1009 | + phantom: PhantomData, |
| 1010 | + }) |
| 1011 | + } |
| 1012 | + } else { |
| 1013 | + Err(self) |
| 1014 | + } |
| 1015 | + } |
| 1016 | +} |
| 1017 | + |
974 | 1018 | impl<T> Weak<T> {
|
975 | 1019 | /// Constructs a new `Weak<T>`, allocating memory for `T` without initializing
|
976 | 1020 | /// it. Calling [`upgrade`] on the return value always gives [`None`].
|
@@ -1844,6 +1888,26 @@ mod tests {
|
1844 | 1888 |
|
1845 | 1889 | assert_eq!(&r[..], [1, 2, 3]);
|
1846 | 1890 | }
|
| 1891 | + |
| 1892 | + #[test] |
| 1893 | + fn test_downcast() { |
| 1894 | + use std::any::Any; |
| 1895 | + |
| 1896 | + let r1: Arc<Any + Send + Sync> = Arc::new(i32::max_value()); |
| 1897 | + let r2: Arc<Any + Send + Sync> = Arc::new("abc"); |
| 1898 | + |
| 1899 | + assert!(r1.clone().downcast::<u32>().is_err()); |
| 1900 | + |
| 1901 | + let r1i32 = r1.downcast::<i32>(); |
| 1902 | + assert!(r1i32.is_ok()); |
| 1903 | + assert_eq!(r1i32.unwrap(), Arc::new(i32::max_value())); |
| 1904 | + |
| 1905 | + assert!(r2.clone().downcast::<i32>().is_err()); |
| 1906 | + |
| 1907 | + let r2str = r2.downcast::<&'static str>(); |
| 1908 | + assert!(r2str.is_ok()); |
| 1909 | + assert_eq!(r2str.unwrap(), Arc::new("abc")); |
| 1910 | + } |
1847 | 1911 | }
|
1848 | 1912 |
|
1849 | 1913 | #[stable(feature = "rust1", since = "1.0.0")]
|
|
0 commit comments