Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::marker::PhantomData;
- use std::ops::Index;
- pub struct Arena<T, B>(Vec<T>, PhantomData<B>);
- pub struct Idx<B>(usize, PhantomData<B>);
- impl<T, B> Arena<T, B> {
- pub unsafe fn new(_: B) -> Self {
- Arena(vec![], PhantomData)
- }
- pub fn add(&mut self, t: T) -> Idx<B> {
- let i = self.0.len();
- self.0.push(t);
- Idx(i, self.1)
- }
- }
- impl<T, B> Index<Idx<B>> for Arena<T, B> {
- type Output = T;
- fn index(&self, i: Idx<B>) -> &T {
- debug_assert!(i.0 < self.0.len());
- unsafe { &self.0.get_unchecked(i.0) }
- }
- }
- macro_rules! in_arena {
- ($arena:ident, $e:expr) => {{
- let mut tag = ();
- let mut x = unsafe { Arena::new(&mut tag) };
- {
- let $arena = &mut x;
- $e
- }
- }};
- }
- fn recurse(i: Option<Idx<&mut ()>>) -> usize {
- in_arena!(a, {
- if let Some(i) = i {
- a[i]
- } else {
- recurse(Some(a.add(42)))
- }
- })
- }
- fn main() {
- recurse(None);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement