Skip to content

Instantly share code, notes, and snippets.

@ben0x539
Last active December 17, 2015 03:19
Show Gist options
  • Save ben0x539/5542361 to your computer and use it in GitHub Desktop.
Save ben0x539/5542361 to your computer and use it in GitHub Desktop.
use core::util::replace;
#[deriving(Clone)]
struct S(int);
impl Drop for S {
fn finalize(&self) {
io::println(fmt!("~S(%?)", **self));
}
}
#[inline(always)]
fn discard<T>(_: T) {}
#[inline(always)]
unsafe fn malloc<T>() -> *mut T {
libc::malloc(sys::size_of::<T>() as libc::size_t) as *mut T
}
struct UniqueMalloc<'self, T>(&'self mut T);
impl<'self, T> UniqueMalloc<'self, T> {
fn new(obj: T) -> UniqueMalloc<T> {
unsafe {
let p = malloc::<T>();
if p.is_null() { fail!("malloc() returned NULL"); }
let m = UniqueMalloc(cast::transmute(p));
cast::forget(replace(*m, obj));
m
}
}
unsafe fn claim(ptr: *mut T) -> UniqueMalloc<T> {
if ptr.is_null() { fail!("claim() received NULL"); }
UniqueMalloc(cast::transmute(ptr))
}
unsafe fn waive(self) -> *mut T {
let p = ptr::to_mut_unsafe_ptr(*self);
cast::forget(self);
p
}
}
impl<'self, T: Clone> Clone for UniqueMalloc<'self, T> {
fn clone(&self) -> UniqueMalloc<'self, T> {
let &UniqueMalloc(ptr) = self;
UniqueMalloc::new((*ptr).clone())
}
}
#[unsafe_destructor]
impl<'self, T> Drop for UniqueMalloc<'self, T> {
fn finalize(&self) {
let &UniqueMalloc(ptr) = self;
unsafe {
let p = ptr::to_unsafe_ptr(ptr);
let q = p;
discard(*p);
libc::free(q as *libc::c_void);
}
}
}
fn main() {
let s = UniqueMalloc::new(S(42));
let f = |n| UniqueMalloc::new(S(n));
let a = UniqueMalloc::new([f(1), f(2), f(3)]);
let b = vec::from_fn(a.len(), |i| a[i].clone());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment