#![feature(allocator_api)]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(transmute_prefix)]
#![feature(const_destruct)]
#![feature(const_trait_impl)]
#![feature(const_convert)]
#![feature(arbitrary_self_types)]
#![feature(unsize)]
#![feature(coerce_unsized)]
#![feature(maybe_dangling)]
#![feature(deref_pure_trait)]
#![feature(negative_impls)]
#![feature(super_let)]
#![feature(const_drop_in_place)]
#![feature(const_heap)]
#![feature(const_iter)]
#![feature(temporary_niche_types)]
#![no_std]
#![feature(const_manually_drop_take)]
#![feature(decl_macro)]
#![feature(const_slice_make_iter)]
#![feature(sized_type_properties)]
pub mod iter;
extern crate alloc;
use alloc::alloc::{Global, handle_alloc_error};
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::alloc::{Allocator, Layout};
use core::marker::{Destruct, PhantomData, Unsize};
use core::mem::{ManuallyDrop, MaybeDangling, MaybeUninit, forget, transmute_prefix as transmute, transmute_prefix};
use core::num::niche_types::UsizeNoHighBit;
use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure};
use core::panic::{RefUnwindSafe, UnwindSafe};
use core::ptr::{NonNull, metadata};
use core::ptr;
use core::slice::{Iter, IterMut};
#[macro_export]
macro_rules! own {
($e:expr) => {
{
super let mut _TEMP = ::core::mem::ManuallyDrop::new($e);
unsafe { $crate::OwnRef::new(&mut _TEMP) }
}
};
}
pub macro deref_own {
($e:expr) => {
{
super let mut __FORGET = $crate::ForgetContents::new($e);
__FORGET.make_own_ref()
}
},
}
pub struct OwnRef<'a, T: ?Sized + 'a> {
inner: &'a mut ManuallyDrop<T>
}
const impl<'a, T: ?Sized+ 'a> Deref for OwnRef<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&**self.inner
}
}
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<OwnRef<'a, U>> for OwnRef<'b, T> {}
const impl<'a, T: ?Sized> OwnRef<'a, T> {
#[inline(always)]
pub unsafe fn new(inner: &'a mut ManuallyDrop<T>) -> Self {
Self {
inner
}
}
}
const impl<'a, T: ?Sized> Drop for OwnRef<'a, T> where T: [const] Destruct {
fn drop(&mut self) {
unsafe { ManuallyDrop::drop(self.inner) }
}
}
pub const trait DerefMove: DerefMut<Target: Sized> {
fn deref_move(self) -> Self::Target;
}
pub const unsafe trait DerefOwn: DerefMut {
unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> OwnRef<'_, Self::Target>;
fn forget_contents(this: MaybeDangling<Self>);
unsafe fn forget_contents_in_place(this: &mut ManuallyDrop<Self>) where Self: Sized {
unsafe {
Self::forget_contents(transmute_prefix(ManuallyDrop::take(this)))
}
}
}
impl<'a, T: ?Sized> !UnwindSafe for OwnRef<'a, T> {}
const impl<T> DerefMove for OwnRef<'_, T> {
fn deref_move(self) -> Self::Target {
let mut slot = ManuallyDrop::new(self);
unsafe { ManuallyDrop::into_inner(NonNull::from_mut(slot.inner).read()) }
}
}
const unsafe impl<T: ?Sized> DerefOwn for OwnRef<'_, T> {
unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> OwnRef<'_, Self::Target> {
unsafe { (&raw const **self).read() }
}
fn forget_contents(this: MaybeDangling<Self>) {
forget(this)
}
}
const impl<'a, T: ?Sized> DerefMut for OwnRef<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut **self.inner
}
}
unsafe impl<T: ?Sized> DerefPure for OwnRef<'_, T> {}
impl<T: ?Sized> !Copy for OwnRef<'_, T> {}
const unsafe impl<T: ?Sized, A: [const] Allocator> DerefOwn for Box<T, A> where Box<ManuallyDrop<T>, A>: [const] Destruct {
unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> OwnRef<'_, Self::Target> {
unsafe { OwnRef::new(transmute_prefix(&mut ***self)) }
}
fn forget_contents(this: MaybeDangling<Self>) {
drop(unsafe { transmute_prefix::<_, Box<ManuallyDrop<T>, A>>(this) })
}
}
const impl<T> DerefMove for Box<T> where Box<T>: [const] Destruct {
fn deref_move(self) -> Self::Target {
*self
}
}
const unsafe impl<T, A: [const] Allocator> DerefOwn for Vec<T, A> where Vec<ManuallyDrop<T>, A>: [const] Destruct {
unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> OwnRef<'_, Self::Target> {
unsafe { OwnRef::new(transmute_prefix(&mut ***self)) }
}
fn forget_contents(this: MaybeDangling<Self>) {
drop(unsafe { transmute_prefix::<_, Vec<ManuallyDrop<T>, A>>(this) });
}
}
unsafe impl DerefOwn for String {
unsafe fn deref_own(self: &mut ManuallyDrop<Self>) -> OwnRef<'_, Self::Target> {
unsafe { OwnRef::new(transmute_prefix(&mut ***self)) }
}
fn forget_contents(this: MaybeDangling<Self>) {
drop(unsafe { transmute_prefix::<_, Vec<ManuallyDrop<u8>>>(this.into_inner().into_bytes()) });
}
}
pub trait Take<T: ?Sized> {
fn take(val: OwnRef<T>) -> Self;
}
pub trait TakeIn<T: ?Sized, A: Allocator> {
fn take_in(val: OwnRef<T>, alloc: A) -> Self;
}
impl<T: Sized> Take<T> for T {
#[inline(always)]
fn take(val: OwnRef<T>) -> Self {
val.deref_move()
}
}
impl<T: ?Sized> Take<T> for Box<T> {
#[inline(always)]
fn take(val: OwnRef<T>) -> Self {
Self::take_in(val, Global)
}
}
impl<T: ?Sized, A: Allocator> TakeIn<T, A> for Box<T, A> {
#[inline(always)]
fn take_in(val: OwnRef<T>, alloc: A) -> Self {
let val = MaybeDangling::new(val);
let borrow = &**val.as_ref();
let meta = metadata(borrow);
let layout = Layout::for_value(borrow);
let this_ptr = match alloc.allocate(layout) {
Ok(m) => NonNull::<T>::from_raw_parts(m.as_non_null_ptr(), meta),
Err(_) => handle_alloc_error(layout),
};
unsafe { ptr::copy_nonoverlapping((borrow as *const T).cast::<u8>(), this_ptr.cast().as_ptr(), layout.size()); }
DerefOwn::forget_contents(val);
unsafe { Box::from_raw_in(this_ptr.as_ptr(), alloc) }
}
}
impl<T: Sized> Take<[T]> for Vec<T> {
#[inline(always)]
fn take(val: OwnRef<[T]>) -> Self {
let val = MaybeDangling::new(val);
let borrow = &**val.as_ref();
let len = borrow.len();
let mut this: Vec<MaybeUninit<T>> = Box::new_uninit_slice(len).into_vec();
let this_ptr = this[0].as_mut_ptr();
unsafe { ptr::copy_nonoverlapping(&raw const borrow[0], this_ptr, len); }
DerefOwn::forget_contents(val);
unsafe { transmute(this) }
}
}
impl<T: Sized, A: Allocator> TakeIn<[T], A> for Vec<T, A> {
#[inline(always)]
fn take_in(val: OwnRef<[T]>, alloc: A) -> Self {
let val = MaybeDangling::new(val);
let borrow = &**val.as_ref();
let len = borrow.len();
let mut this: Vec<MaybeUninit<T>, A> = Box::new_uninit_slice_in(len, alloc).into_vec();
let this_ptr = this[0].as_mut_ptr();
unsafe { ptr::copy_nonoverlapping(&raw const borrow[0], this_ptr, len); }
DerefOwn::forget_contents(val);
unsafe { transmute(this) }
}
}
pub struct ForgetContents<T: DerefOwn>(ManuallyDrop<T>);
const impl<T: [const] DerefOwn> ForgetContents<T> {
pub fn new(inner: T) -> Self {
Self(ManuallyDrop::new(inner))
}
pub fn make_own_ref(&mut self) -> OwnRef<'_, <T as Deref>::Target> {
unsafe { self.0.deref_own() }
}
}
const impl<T: [const] DerefOwn> Drop for ForgetContents<T> {
fn drop(&mut self) {
unsafe { DerefOwn::forget_contents_in_place(&mut self.0) }
}
}
impl Take<str> for String {
#[inline(always)]
fn take(val: OwnRef<str>) -> Self {
let val = MaybeDangling::new(val);
let borrow = &**val.as_ref();
let len = borrow.len();
let mut this: Vec<MaybeUninit<u8>> = Box::new_uninit_slice(len).into_vec();
let this_ptr = this[0].as_mut_ptr();
unsafe { ptr::copy_nonoverlapping(&raw const borrow.as_bytes()[0], this_ptr, len); }
DerefOwn::forget_contents(val);
unsafe { String::from_utf8_unchecked(transmute(this)) }
}
}