#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::{String, Vec};
#[cfg(feature = "std")]
use std::rc::Rc;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::rc::Rc;
#[cfg(feature = "std")]
use std::sync::Arc;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::arc::Arc;
use core::{slice, str};
pub trait FromUnchecked<T>: Sized {
unsafe fn from_unchecked(T) -> Self;
}
pub trait IntoUnchecked<T>: Sized {
unsafe fn into_unchecked(self) -> T;
}
impl<T, U: FromUnchecked<T>> IntoUnchecked<U> for T {
#[inline]
unsafe fn into_unchecked(self) -> U {
U::from_unchecked(self)
}
}
impl<'a, T, U> FromUnchecked<&'a U> for &'a T {
#[inline]
unsafe fn from_unchecked(other: &U) -> &T {
&*(other as *const U as *const T)
}
}
impl<'a, T, U> FromUnchecked<&'a mut U> for &'a mut T {
#[inline]
unsafe fn from_unchecked(other: &mut U) -> &mut T {
&mut *(other as *mut U as *mut T)
}
}
impl<'a, T: ?Sized> FromUnchecked<*const T> for &'a T {
#[inline]
unsafe fn from_unchecked(ptr: *const T) -> &'a T {
&*ptr
}
}
impl<'a, T: ?Sized> FromUnchecked<*mut T> for &'a mut T {
#[inline]
unsafe fn from_unchecked(ptr: *mut T) -> &'a mut T {
&mut *ptr
}
}
impl<'a, T, U> FromUnchecked<&'a [U]> for &'a [T] {
#[inline]
unsafe fn from_unchecked(slice: &[U]) -> &[T] {
slice::from_raw_parts(slice.as_ptr() as _, slice.len())
}
}
impl<'a, T, U> FromUnchecked<&'a mut [U]> for &'a mut [T] {
#[inline]
unsafe fn from_unchecked(slice: &mut [U]) -> &mut [T] {
slice::from_raw_parts_mut(slice.as_mut_ptr() as _, slice.len())
}
}
impl<'a> FromUnchecked<&'a [u8]> for &'a str {
#[inline]
unsafe fn from_unchecked(utf8: &[u8]) -> &str {
str::from_utf8_unchecked(utf8)
}
}
impl<'a> FromUnchecked<&'a mut [u8]> for &'a mut str {
#[inline]
unsafe fn from_unchecked(utf8: &mut [u8]) -> &mut str {
str::from_utf8_unchecked_mut(utf8)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T, U> FromUnchecked<Vec<U>> for Vec<T> {
#[inline]
unsafe fn from_unchecked(mut vec: Vec<U>) -> Vec<T> {
use core::mem::forget;
let new = Vec::from_raw_parts(
vec.as_mut_ptr() as _,
vec.len(),
vec.capacity()
);
forget(vec);
new
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl FromUnchecked<Vec<u8>> for String {
#[inline]
unsafe fn from_unchecked(utf8: Vec<u8>) -> Self {
Self::from_utf8_unchecked(utf8)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl FromUnchecked<Box<[u8]>> for String {
#[inline]
unsafe fn from_unchecked(utf8: Box<[u8]>) -> Self {
utf8.into_vec().into_unchecked()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T, U> FromUnchecked<Box<U>> for Box<T> {
#[inline]
unsafe fn from_unchecked(b: Box<U>) -> Self {
Box::from_raw(Box::into_raw(b) as _)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T, U> FromUnchecked<Box<[U]>> for Box<[T]> {
#[inline]
unsafe fn from_unchecked(b: Box<[U]>) -> Self {
Box::from_raw(Box::into_raw(b) as _)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: ?Sized> FromUnchecked<*mut T> for Box<T> {
#[inline]
unsafe fn from_unchecked(ptr: *mut T) -> Self {
Self::from_raw(ptr)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> FromUnchecked<*const T> for Arc<T> {
#[inline]
unsafe fn from_unchecked(ptr: *const T) -> Self {
Self::from_raw(ptr)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T, U> FromUnchecked<Arc<U>> for Arc<T> {
#[inline]
unsafe fn from_unchecked(arc: Arc<U>) -> Self {
Arc::from_raw(Arc::into_raw(arc) as _)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> FromUnchecked<*const T> for Rc<T> {
#[inline]
unsafe fn from_unchecked(ptr: *const T) -> Self {
Self::from_raw(ptr)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T, U> FromUnchecked<Rc<U>> for Rc<T> {
#[inline]
unsafe fn from_unchecked(rc: Rc<U>) -> Self {
Rc::from_raw(Rc::into_raw(rc) as _)
}
}