tyler569 icon

Almost IBox - need DerefMove :(

tyler569 | PRO | 06/25/20 06:46:13 PM UTC | 0 ⭐ | 9266 👁️ | Never ⏰ | []
Rust |

3.66 KB

|

None

|

0 👍

/

0 👎

#![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

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎