#![feature(unboxed_closures)]
#![feature(fn_traits)]
#![feature(ptr_internals)]
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]
use std::marker::PhantomData;
use std::mem::transmute;
use std::ops::{Deref, DerefMut};
struct Unique<'a, T: ?Sized> {
v: *mut T,
life: PhantomData<&'a T>,
}
unsafe impl<T: ?Sized + Send> Send for Unique<'_, T> {}
unsafe impl<T: ?Sized + Sync> Sync for Unique<'_, T> {}
impl<T: ?Sized> Unique<'_, T> {
fn new(v: &mut T) -> Self {
Unique { v, life: PhantomData }
}
fn get(&self) -> &T {
self.deref()
}
fn get_mut(&mut self) -> &mut T {
self.deref_mut()
}
}
impl<T: ?Sized> Deref for Unique<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.v }
}
}
impl<T: ?Sized> DerefMut for Unique<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.v }
}
}
#[test]
fn unique_creation() {
let mut x = 10;
let y = &mut x;
let u = Unique::new(y);
assert_eq!(*u, 10);
}
#[test]
fn unique_mutation() {
let mut x = 10;
let y = &mut x;
let mut u = Unique::new(y);
assert_eq!(*u, 10);
*u = 100;
assert_eq!(*u, 100);
}
#[allow(dead_code)]
struct IBox<'a, T: ?Sized> {
container: &'a mut [u8],
ptr: Unique<'a, T>,
}
impl<T> IBox<'_, T> {
fn new(v: T, container: &mut [u8]) -> IBox<T> {
let ptr = unsafe { transmute(container.as_mut_ptr()) };
let mut unique = Unique::new(ptr);
*unique = v;
IBox { container, ptr: unique }
}
}
impl<T: ?Sized> IBox<'_, T> {
fn move_out(self) -> T {
*self
}
}
#[test]
fn ibox_new() {
let container = &mut [0u8; 128];
IBox::new(10, container);
}
impl<T: ?Sized> Deref for IBox<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.ptr.get()
}
}
impl<T: ?Sized> DerefMut for IBox<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.ptr.get_mut()
}
}
#[test]
fn ibox_deref() {
let container = &mut [0u8; 128];
let i = IBox::new(10, container);
assert_eq!(*i, 10);
}
#[test]
fn ibox_mutate() {
let container = &mut [0u8; 128];
let mut i = IBox::new(10, container);
assert_eq!(*i, 10);
*i = 100;
assert_eq!(*i, 100);
}
/*
impl<Args, F> FnOnce<Args> for IBox<'_, F>
where
F: FnOnce<Args> + ?Sized
{
type Output = <F as FnOnce<Args>>::Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
<F as FnOnce<Args>>::call_once(*self, args)
}
}
*/
impl<A, F: FnOnce<A> + ?Sized> FnOnce<A> for IBox<'_, F> {
type Output = <F as FnOnce<A>>::Output;
extern "rust-call" fn call_once(self, args: A) -> Self::Output {
<F as FnOnce<A>>::call_once(self.move_out(), args)
}
}
// impl<Args, F> FnMut<Args> for IBox<'_, F>
// where
// F: FnMut<Args> + ?Sized,
// {
// extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
// (**self).call_mut(args)
// }
// }
//
// impl<Args, F> Fn<Args> for IBox<'_, F>
// where
// F: Fn<Args> + ?Sized,
// {
// extern "rust-call" fn call(&self, args: Args) -> Self::Output {
// (**self).call(args)
// }
// }
fn closure(x: i32, container: &mut [u8]) -> IBox<impl FnOnce(i32) -> i32> {
IBox::new(move |a| a + x, container)
}
#[test]
fn iboxed_closure() {
let mut container = [0u8; 128];
let closed_fn = closure(10, &mut container);
assert_eq!(closed_fn(100), 110);
}
Comments
0 B
|👍
/👎
0 B
|👍
/👎