tyler569

Almost IBox - need DerefMove :(

Jun 25th, 2020
1,781
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×