static_list/
lib.rs

1#![feature(unsize)]
2
3use std::marker::PhantomData;
4use std::marker::Unsize;
5
6pub trait Item<'a, T: ?Sized + 'a> {
7    type Iter: DoubleEndedIterator<Item = &'a T>;
8
9    fn iter(&'a self) -> Self::Iter;
10}
11
12pub struct Node<'a, I: ?Sized, L: Item<'a, I>, R: Item<'a, I>>(pub L, pub R, PhantomData<&'a I>);
13impl<'a, I: ?Sized + 'a, L: Item<'a, I>, R: Item<'a, I>> Node<'a, I, L, R> {
14    #[inline]
15    pub fn new(left: L, right: R) -> Self {
16        Node(left, right, Default::default())
17    }
18}
19
20impl<'a, I: ?Sized + 'a, L: Item<'a, I>, R: Item<'a, I>> Item<'a, I> for Node<'a, I, L, R> {
21    type Iter = std::iter::Chain<L::Iter, R::Iter>;
22
23    #[inline]
24    fn iter(&'a self) -> Self::Iter {
25        self.0.iter().chain(self.1.iter())
26    }
27}
28
29pub struct Leaf<'a, O: Unsize<I>, I: ?Sized>(pub O, PhantomData<&'a I>);
30impl<'a, O: Unsize<I>, I: ?Sized + 'a> Leaf<'a, O, I> {
31    #[inline]
32    pub fn new(data: O) -> Self {
33        Leaf(data, Default::default())
34    }
35}
36
37impl<'a, O: Unsize<I>, I: ?Sized + 'a> Item<'a, I> for Leaf<'a, O, I> {
38    type Iter = std::iter::Once<&'a I>;
39
40    #[inline]
41    fn iter(&'a self) -> Self::Iter {
42        std::iter::once(&self.0 as &I)
43    }
44}
45
46#[macro_export]
47macro_rules! static_list {
48    ($w:expr) => (Leaf::new($w));
49    ($w:expr,) => (Leaf::new($w));
50    ($w:expr, $($rest:tt)*) => (Node::new(Leaf::new($w), static_list!($($rest)*)));
51}
52
53#[macro_export]
54macro_rules! static_list_type {
55    (&$l:tt $o:ty; $w:ty) => (Leaf<$l, $w, $o>);
56    (&$l:tt $o:ty; $w:ty,) => (Leaf<$l, $w, $o>);
57    (&$l:tt $o:ty; $w:ty, $($rest:tt)*) => (Node<$l, $o, Leaf<$l, $w, $o>, static_list_type!(&$l $o; $($rest)*)>);
58}