#![feature(allocator_api)]
#![feature(layout_for_ptr)]
#![feature(maybe_uninit_write_slice)]
#![feature(ptr_metadata)]
#![feature(slice_index_methods)]
#![feature(slice_ptr_get)]
#![feature(specialization)]
#![cfg_attr(test, feature(new_uninit, test))]
#![allow(incomplete_features)]
#![warn(missing_docs)]
#[cfg(test)]
extern crate test;
use std::{mem::MaybeUninit, ptr::Pointee};
#[doc(no_inline)]
pub use dst_container_derive::{MaybeUninitProject, UnsizedClone};
mod smart_ptr;
pub use smart_ptr::{AssumeInit, NewUninit, SmartPtr};
mod unsized_slice;
pub use unsized_slice::UnsizedSlice;
mod unsized_str;
pub use unsized_str::UnsizedStr;
mod fixed_vec;
pub use fixed_vec::FixedVec;
pub trait MaybeUninitProject {
type Target: ?Sized + Pointee<Metadata = <Self as Pointee>::Metadata>;
}
impl<T: Sized> MaybeUninitProject for T {
type Target = MaybeUninit<T>;
}
impl<T> MaybeUninitProject for [T] {
type Target = [MaybeUninit<T>];
}
impl MaybeUninitProject for str {
type Target = [MaybeUninit<u8>];
}
pub trait UnsizedClone: MaybeUninitProject {
fn clone_to(&self, dest: &mut Self::Target);
#[allow(clippy::borrowed_box)]
fn clone(self: &Box<Self>) -> Box<Self> {
let (_, metadata) = (self.as_ref() as *const Self).to_raw_parts();
unsafe { Box::<Self>::new_unsized_with(metadata, |dest| self.as_ref().clone_to(dest)) }
}
}
impl<T: Clone> UnsizedClone for T {
fn clone_to(&self, dest: &mut Self::Target) {
dest.write(self.clone());
}
}
impl<T: UnsizedClone> UnsizedClone for [T] {
default fn clone_to(&self, _dest: &mut Self::Target) {
unreachable!()
}
}
impl<T: Clone> UnsizedClone for [T] {
default fn clone_to(&self, dest: &mut Self::Target) {
MaybeUninit::write_slice_cloned(dest, self);
}
}
impl<T: Copy> UnsizedClone for [T] {
fn clone_to(&self, dest: &mut Self::Target) {
MaybeUninit::write_slice(dest, self);
}
}
impl UnsizedClone for str {
fn clone_to(&self, dest: &mut Self::Target) {
MaybeUninit::write_slice(dest, self.as_bytes());
}
}