add unchecked downcast methods
This commit is contained in:
parent
e90c5fbbc5
commit
29403eeef0
2 changed files with 273 additions and 36 deletions
|
@ -1482,8 +1482,6 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
|
|||
}
|
||||
|
||||
impl<A: Allocator> Box<dyn Any, A> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Attempt to downcast the box to a concrete type.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -1501,21 +1499,46 @@ impl<A: Allocator> Box<dyn Any, A> {
|
|||
/// print_if_string(Box::new(my_string));
|
||||
/// print_if_string(Box::new(0i8));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self);
|
||||
Ok(Box::from_raw_in(raw as *mut T, alloc))
|
||||
}
|
||||
} else {
|
||||
Err(self)
|
||||
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
|
||||
}
|
||||
|
||||
/// Downcasts the box to a concrete type.
|
||||
///
|
||||
/// For a safe alternative see [`downcast`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(downcast_unchecked)]
|
||||
///
|
||||
/// use std::any::Any;
|
||||
///
|
||||
/// let x: Box<dyn Any> = Box::new(1_usize);
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The contained value must be of type `T`. Calling this method
|
||||
/// with the incorrect type is *undefined behavior*.
|
||||
#[inline]
|
||||
#[unstable(feature = "downcast_unchecked", issue = "none")]
|
||||
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
|
||||
debug_assert!(self.is::<T>());
|
||||
unsafe {
|
||||
let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self);
|
||||
Box::from_raw_in(raw as *mut T, alloc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Allocator> Box<dyn Any + Send, A> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Attempt to downcast the box to a concrete type.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -1533,21 +1556,46 @@ impl<A: Allocator> Box<dyn Any + Send, A> {
|
|||
/// print_if_string(Box::new(my_string));
|
||||
/// print_if_string(Box::new(0i8));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self);
|
||||
Ok(Box::from_raw_in(raw as *mut T, alloc))
|
||||
}
|
||||
} else {
|
||||
Err(self)
|
||||
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
|
||||
}
|
||||
|
||||
/// Downcasts the box to a concrete type.
|
||||
///
|
||||
/// For a safe alternative see [`downcast`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(downcast_unchecked)]
|
||||
///
|
||||
/// use std::any::Any;
|
||||
///
|
||||
/// let x: Box<dyn Any + Send> = Box::new(1_usize);
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The contained value must be of type `T`. Calling this method
|
||||
/// with the incorrect type is *undefined behavior*.
|
||||
#[inline]
|
||||
#[unstable(feature = "downcast_unchecked", issue = "none")]
|
||||
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
|
||||
debug_assert!(self.is::<T>());
|
||||
unsafe {
|
||||
let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self);
|
||||
Box::from_raw_in(raw as *mut T, alloc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
|
||||
#[inline]
|
||||
#[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
|
||||
/// Attempt to downcast the box to a concrete type.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -1565,15 +1613,42 @@ impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
|
|||
/// print_if_string(Box::new(my_string));
|
||||
/// print_if_string(Box::new(0i8));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
let (raw, alloc): (*mut (dyn Any + Send + Sync), _) =
|
||||
Box::into_raw_with_allocator(self);
|
||||
Ok(Box::from_raw_in(raw as *mut T, alloc))
|
||||
}
|
||||
} else {
|
||||
Err(self)
|
||||
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
|
||||
}
|
||||
|
||||
/// Downcasts the box to a concrete type.
|
||||
///
|
||||
/// For a safe alternative see [`downcast`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(downcast_unchecked)]
|
||||
///
|
||||
/// use std::any::Any;
|
||||
///
|
||||
/// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The contained value must be of type `T`. Calling this method
|
||||
/// with the incorrect type is *undefined behavior*.
|
||||
#[inline]
|
||||
#[unstable(feature = "downcast_unchecked", issue = "none")]
|
||||
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
|
||||
debug_assert!(self.is::<T>());
|
||||
unsafe {
|
||||
let (raw, alloc): (*mut (dyn Any + Send + Sync), _) =
|
||||
Box::into_raw_with_allocator(self);
|
||||
Box::from_raw_in(raw as *mut T, alloc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue