Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created September 21, 2018 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rust-play/a299202f13737d663efe16c9c87a4002 to your computer and use it in GitHub Desktop.
Save rust-play/a299202f13737d663efe16c9c87a4002 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#![feature(unsize)]
use std::ptr;
use std::mem::{self, ManuallyDrop};
use std::marker::{PhantomData, Unsize};
struct PartialArray<T, A>
where
A: Unsize<[T]>
{
array: ManuallyDrop<A>,
idx: usize,
marker: PhantomData<T>
}
impl <T, A> PartialArray<T, A>
where
A: Unsize<[T]>
{
unsafe fn new() -> Self {
Self {
array: ManuallyDrop::new(mem::uninitialized()),
idx: 0,
marker: PhantomData,
}
}
unsafe fn into_inner(mut self) -> A {
unsafe {
let ret = ManuallyDrop::into_inner(ptr::read(&mut self.array));
mem::forget(self);
ret
}
}
fn from_iter<I: Iterator<Item = T>>(mut self, iter: I) -> A {
unsafe {
{
let arr: &mut A = &mut self.array;
let slice: &mut [T] = arr;
for (dst, src) in slice.iter_mut().zip(iter) {
ptr::write(dst, src);
}
}
self.into_inner()
}
}
}
impl <T, A> Drop for PartialArray<T, A>
where
A: Unsize<[T]>
{
fn drop(&mut self) {
unsafe {
let s = ptr::read(self);
let mut array = s.into_inner();
// we need a slice to index, but Unsize makes sure we can do this.
let mut slice: &mut [T] = &mut array;
ptr::drop_in_place::<[T]>(&mut slice[..self.idx]);
}
}
}
fn main() {
unsafe {
let array: [usize; 100] = PartialArray::new().from_iter(0..100);
println!("{:?}", array.as_ref());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment