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}