use std::boxed::Box;
use std::ops::{Deref,DerefMut};
use std::convert::{AsRef,AsMut};
use std::borrow::{Borrow,BorrowMut};
#[derive(Debug)]
pub struct ZeroDropDrop<T>(Box<T>) where T: Drop+Default;
impl<T> Drop for ZeroDropDrop<T> where T: Drop+Default {
#[inline(never)]
fn drop(&mut self) {
let s: &mut T = self.0.deref_mut();
unsafe {
::std::ptr::drop_in_place::<T>(s);
::std::ptr::write::<T>(s,Default::default());
}
}
}
impl<T> ZeroDropDrop<T> where T: Drop+Default {
pub fn new_default() -> ZeroDropDrop<T> {
ZeroDropDrop(Default::default())
}
pub unsafe fn new_uninitialized() -> ZeroDropDrop<T> {
ZeroDropDrop(Box::new(::std::mem::uninitialized::<T>()))
}
pub unsafe fn zero_out(&mut self) {
let s: &mut T = self.0.deref_mut();
::std::intrinsics::volatile_set_memory::<T>(s,0,1)
}
}
impl<T> Clone for ZeroDropDrop<T> where T: Drop+Default+Clone {
fn clone(&self) -> ZeroDropDrop<T> {
ZeroDropDrop(self.0.clone())
}
fn clone_from(&mut self, source: &ZeroDropDrop<T>) {
self.0.clone_from(&source.0);
}
}
impl<T> Deref for ZeroDropDrop<T> where T: Drop+Default {
type Target = T;
fn deref(&self) -> &T {
self.0.deref()
}
}
impl<T> DerefMut for ZeroDropDrop<T> where T: Drop+Default {
fn deref_mut(&mut self) -> &mut T {
self.0.deref_mut()
}
}
impl<T,U> AsRef<U> for ZeroDropDrop<T> where T: Drop+Default+AsRef<U> {
fn as_ref(&self) -> &U {
self.0.as_ref().as_ref()
}
}
impl<T,U> AsMut<U> for ZeroDropDrop<T> where T: Drop+Default+AsMut<U> {
fn as_mut(&mut self) -> &mut U {
self.0.as_mut().as_mut()
}
}
impl<T> Borrow<T> for ZeroDropDrop<T> where T: Drop+Default {
fn borrow(&self) -> &T {
self.0.borrow()
}
}
impl<T> BorrowMut<T> for ZeroDropDrop<T> where T: Drop+Default {
fn borrow_mut(&mut self) -> &mut T {
self.0.borrow_mut()
}
}