Advertisement
tyler569

Almost IBox - need DerefMove :(

Jun 25th, 2020
2,249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.66 KB | None | 0 0
  1. #![feature(unboxed_closures)]
  2. #![feature(fn_traits)]
  3. #![feature(ptr_internals)]
  4.  
  5. #![allow(dead_code)]
  6. #![allow(unused_imports)]
  7. #![allow(unused_variables)]
  8.  
  9. use std::marker::PhantomData;
  10. use std::mem::transmute;
  11. use std::ops::{Deref, DerefMut};
  12.  
  13. struct Unique<'a, T: ?Sized> {
  14.    v: *mut T,
  15.    life: PhantomData<&'a T>,
  16. }
  17.  
  18. unsafe impl<T: ?Sized + Send> Send for Unique<'_, T> {}
  19. unsafe impl<T: ?Sized + Sync> Sync for Unique<'_, T> {}
  20.  
  21. impl<T: ?Sized> Unique<'_, T> {
  22.    fn new(v: &mut T) -> Self {
  23.        Unique { v, life: PhantomData }
  24.    }
  25.    
  26.    fn get(&self) -> &T {
  27.        self.deref()
  28.    }
  29.    
  30.    fn get_mut(&mut self) -> &mut T {
  31.        self.deref_mut()
  32.    }
  33. }
  34.  
  35. impl<T: ?Sized> Deref for Unique<'_, T> {
  36.     type Target = T;
  37.    
  38.     fn deref(&self) -> &Self::Target {
  39.         unsafe { &*self.v }
  40.     }
  41. }
  42.  
  43. impl<T: ?Sized> DerefMut for Unique<'_, T> {
  44.    fn deref_mut(&mut self) -> &mut Self::Target {
  45.        unsafe { &mut *self.v }
  46.    }
  47. }
  48.  
  49. #[test]
  50. fn unique_creation() {
  51.    let mut x = 10;
  52.    let y = &mut x;
  53.    let u = Unique::new(y);
  54.    assert_eq!(*u, 10);
  55. }
  56.  
  57. #[test]
  58. fn unique_mutation() {
  59.    let mut x = 10;
  60.    let y = &mut x;
  61.    let mut u = Unique::new(y);
  62.    assert_eq!(*u, 10);
  63.    
  64.    *u = 100;
  65.    assert_eq!(*u, 100);
  66. }
  67.  
  68. #[allow(dead_code)]
  69. struct IBox<'a, T: ?Sized> {
  70.     container: &'a mut [u8],
  71.    ptr: Unique<'a, T>,
  72. }
  73.  
  74. impl<T> IBox<'_, T> {
  75.    fn new(v: T, container: &mut [u8]) -> IBox<T> {
  76.        let ptr = unsafe { transmute(container.as_mut_ptr()) };
  77.        let mut unique = Unique::new(ptr);
  78.        *unique = v;
  79.        IBox { container, ptr: unique }
  80.    }
  81. }
  82.  
  83. impl<T: ?Sized> IBox<'_, T> {
  84.     fn move_out(self) -> T {
  85.         *self
  86.     }
  87. }
  88.  
  89. #[test]
  90. fn ibox_new() {
  91.     let container = &mut [0u8; 128];
  92.     IBox::new(10, container);
  93. }
  94.  
  95. impl<T: ?Sized> Deref for IBox<'_, T> {
  96.    type Target = T;
  97.    
  98.    fn deref(&self) -> &Self::Target {
  99.        self.ptr.get()
  100.    }
  101. }
  102.  
  103. impl<T: ?Sized> DerefMut for IBox<'_, T> {
  104.     fn deref_mut(&mut self) -> &mut Self::Target {
  105.         self.ptr.get_mut()
  106.     }
  107. }
  108.  
  109. #[test]
  110. fn ibox_deref() {
  111.     let container = &mut [0u8; 128];
  112.     let i = IBox::new(10, container);
  113.     assert_eq!(*i, 10);
  114. }
  115.  
  116. #[test]
  117. fn ibox_mutate() {
  118.     let container = &mut [0u8; 128];
  119.     let mut i = IBox::new(10, container);
  120.     assert_eq!(*i, 10);
  121.    
  122.     *i = 100;
  123.     assert_eq!(*i, 100);
  124. }
  125.  
  126. /*
  127. impl<Args, F> FnOnce<Args> for IBox<'_, F>
  128. where
  129.     F: FnOnce<Args> + ?Sized
  130. {
  131.     type Output = <F as FnOnce<Args>>::Output;
  132.  
  133.     extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
  134.         <F as FnOnce<Args>>::call_once(*self, args)
  135.     }
  136. }
  137. */
  138.  
  139. impl<A, F: FnOnce<A> + ?Sized> FnOnce<A> for IBox<'_, F> {
  140.    type Output = <F as FnOnce<A>>::Output;
  141.  
  142.    extern "rust-call" fn call_once(self, args: A) -> Self::Output {
  143.        <F as FnOnce<A>>::call_once(self.move_out(), args)
  144.    }
  145. }
  146.  
  147. // impl<Args, F> FnMut<Args> for IBox<'_, F>
  148. // where
  149. //     F: FnMut<Args> + ?Sized,
  150. // {
  151. //     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
  152. //         (**self).call_mut(args)
  153. //     }
  154. // }
  155. //
  156. // impl<Args, F> Fn<Args> for IBox<'_, F>
  157. // where
  158. //     F: Fn<Args> + ?Sized,
  159. // {
  160. //     extern "rust-call" fn call(&self, args: Args) -> Self::Output {
  161. //         (**self).call(args)
  162. //     }
  163. // }
  164.  
  165. fn closure(x: i32, container: &mut [u8]) -> IBox<impl FnOnce(i32) -> i32> {
  166.     IBox::new(move |a| a + x, container)
  167. }
  168.  
  169. #[test]
  170. fn iboxed_closure() {
  171.     let mut container = [0u8; 128];
  172.     let closed_fn = closure(10, &mut container);
  173.     assert_eq!(closed_fn(100), 110);
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement