Advertisement
NLinker

Poor man's HKT

Aug 31st, 2017
470
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.97 KB | None | 0 0
  1. // https://play.rust-lang.org/?gist=e29150c80d38074be5642f4bc451830e&version=stable
  2.  
  3. trait ContainerFamily<T: 'static> {
  4.    type Container: for<'a> Container<'a, Item = T>;
  5.    fn new() -> Self::Container;
  6. }
  7.  
  8. trait Container<'a> {
  9.     type Item: 'a;
  10.    type IterMut: Iterator<Item = &'a mut Self::Item>;
  11.     fn push(&mut self, item: Self::Item);
  12.     fn iter_mut(&'a mut self) -> Self::IterMut;
  13. }
  14.  
  15. #[derive(Copy, Clone)]
  16. struct VecFamily;
  17.  
  18. impl<T: 'static> ContainerFamily<T> for VecFamily {
  19.     type Container = Vec<T>;
  20.     fn new() -> Self::Container {
  21.         Vec::new()
  22.     }
  23. }
  24.  
  25. impl<'a, T: 'a> Container<'a> for Vec<T> {
  26.    type Item = T;
  27.    type IterMut = ::std::slice::IterMut<'a, T>;
  28.     fn push(&mut self, item: Self::Item) {
  29.         self.push(item);
  30.     }
  31.     fn iter_mut(&'a mut self) -> Self::IterMut {
  32.        self.as_mut_slice().iter_mut()
  33.    }
  34. }
  35.  
  36. use std::collections::{linked_list, LinkedList};
  37.  
  38. #[derive(Copy, Clone)]
  39. struct LinkedListFamily;
  40.  
  41. impl<T: 'static> ContainerFamily<T> for LinkedListFamily {
  42.     type Container = LinkedList<T>;
  43.     fn new() -> Self::Container {
  44.         LinkedList::new()
  45.     }
  46. }
  47.  
  48. impl<'a, T: 'a> Container<'a> for LinkedList<T> {
  49.    type Item = T;
  50.    type IterMut = linked_list::IterMut<'a, T>;
  51.     fn push(&mut self, item: Self::Item) {
  52.         self.push_back(item);
  53.     }
  54.     fn iter_mut(&'a mut self) -> Self::IterMut {
  55.        self.iter_mut()
  56.    }
  57. }
  58.  
  59. struct SomeSlab<T, CF>
  60. where
  61.    T: 'static,
  62.     CF: ContainerFamily<Option<T>> + ContainerFamily<usize>,
  63. {
  64.     container: <CF as ContainerFamily<Option<T>>>::Container,
  65.     slot_alloc_count: <CF as ContainerFamily<usize>>::Container,
  66. }
  67.  
  68. impl<T: 'static> SomeSlab<T, VecFamily> {
  69.    pub fn new() -> Self {
  70.        SomeSlab::with_container_family(VecFamily)
  71.    }
  72. }
  73.  
  74. impl<T, CF> SomeSlab<T, CF>
  75. where
  76.    T: 'static,
  77.     CF: ContainerFamily<Option<T>> + ContainerFamily<usize>,
  78. {
  79.     pub fn with_container_family(_: CF) -> Self {
  80.         Self {
  81.             container: <CF as ContainerFamily<Option<T>>>::new(),
  82.             slot_alloc_count: <CF as ContainerFamily<usize>>::new(),
  83.         }
  84.     }
  85.  
  86.     pub fn put(&mut self, item: T) -> usize {
  87.         let mut index = 0;
  88.         for (element, alloc_count) in self.container
  89.             .iter_mut()
  90.             .zip(self.slot_alloc_count.iter_mut())
  91.         {
  92.             if element.is_none() {
  93.                 *element = Some(item);
  94.                 *alloc_count += 1;
  95.                 return index;
  96.             }
  97.             index += 1;
  98.         }
  99.         self.container.push(Some(item));
  100.         self.slot_alloc_count.push(1);
  101.         index
  102.     }
  103.  
  104.     pub fn take(&mut self, id: usize) -> Option<T> {
  105.         for (index, element) in self.container.iter_mut().enumerate() {
  106.             if index == id {
  107.                 return element.take();
  108.             }
  109.         }
  110.         None
  111.     }
  112.  
  113.     pub fn print_slots(&mut self)
  114.     where
  115.         T: ::std::fmt::Debug,
  116.     {
  117.         print!("[");
  118.         for (index, element) in self.container.iter_mut().enumerate() {
  119.             if index != 0 {
  120.                 print!(", ");
  121.             }
  122.             print!("{:?}", element);
  123.         }
  124.         println!("]");
  125.     }
  126. }
  127.  
  128. fn main() {
  129.     let mut slab = SomeSlab::new();
  130.  
  131.     let five = slab.put(5);
  132.     let ten = slab.put(10);
  133.     slab.put(3);
  134.  
  135.     println!("{:?}", slab.take(five));
  136.     println!("{:?}", slab.take(ten));
  137.  
  138.     slab.put(12);
  139.     let fifteen = slab.put(15);
  140.     slab.put(20);
  141.  
  142.     slab.take(fifteen);
  143.  
  144.     slab.print_slots();
  145.  
  146.     // ===================================================
  147.  
  148.     let mut slab = SomeSlab::with_container_family(LinkedListFamily);
  149.  
  150.     let five = slab.put("5");
  151.     let ten = slab.put("10");
  152.     slab.put("3");
  153.  
  154.     println!("{:?}", slab.take(five));
  155.     println!("{:?}", slab.take(ten));
  156.  
  157.     slab.put("12");
  158.     let fifteen = slab.put("15");
  159.     slab.put("20");
  160.  
  161.     slab.take(fifteen);
  162.  
  163.     slab.print_slots();
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement