Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 0.99 KB | None | 0 0
  1. use std::marker::PhantomData;
  2. use std::ops::Index;
  3.  
  4. pub struct Arena<T, B>(Vec<T>, PhantomData<B>);
  5.  
  6. pub struct Idx<B>(usize, PhantomData<B>);
  7.  
  8. impl<T, B> Arena<T, B> {
  9. pub unsafe fn new(_: B) -> Self {
  10. Arena(vec![], PhantomData)
  11. }
  12.  
  13. pub fn add(&mut self, t: T) -> Idx<B> {
  14. let i = self.0.len();
  15. self.0.push(t);
  16. Idx(i, self.1)
  17. }
  18. }
  19.  
  20. impl<T, B> Index<Idx<B>> for Arena<T, B> {
  21. type Output = T;
  22.  
  23. fn index(&self, i: Idx<B>) -> &T {
  24. debug_assert!(i.0 < self.0.len());
  25. unsafe { &self.0.get_unchecked(i.0) }
  26. }
  27. }
  28.  
  29. macro_rules! in_arena {
  30. ($arena:ident, $e:expr) => {{
  31. let mut tag = ();
  32. let mut x = unsafe { Arena::new(&mut tag) };
  33. {
  34. let $arena = &mut x;
  35. $e
  36. }
  37. }};
  38. }
  39.  
  40. fn recurse(i: Option<Idx<&mut ()>>) -> usize {
  41. in_arena!(a, {
  42. if let Some(i) = i {
  43. a[i]
  44. } else {
  45. recurse(Some(a.add(42)))
  46. }
  47. })
  48. }
  49.  
  50. fn main() {
  51. recurse(None);
  52. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement