1#![no_std]
2
3use core::{iter::once, ops::Index};
4
5extern crate alloc;
6use alloc::boxed::Box;
7use alloc::vec;
8use alloc::vec::Vec;
9
10use arena_traits::Arena;
11use either::Either;
12pub trait Func {
14 type Block;
16 type Blocks: Arena<Self::Block, Output: Block<Self>>;
18 fn blocks(&self) -> &Self::Blocks;
20 fn blocks_mut(&mut self) -> &mut Self::Blocks;
22 fn entry(&self) -> Self::Block;
23}
24pub type BlockI<F> = <<F as Func>::Blocks as Index<<F as Func>::Block>>::Output;
26pub type TermI<F> = <BlockI<F> as Block<F>>::Terminator;
27pub type TargetI<F> = <TermI<F> as Term<F>>::Target;
28
29
30pub trait Block<F: Func<Blocks: Arena<F::Block, Output = Self>> + ?Sized> {
31 type Terminator: Term<F>;
32 fn term(&self) -> &Self::Terminator;
33 fn term_mut(&mut self) -> &mut Self::Terminator;
34}
35
36
37
38pub trait Target<F: Func + ?Sized>: Term<F, Target = Self> {
39 fn block(&self) -> F::Block;
40 fn block_mut(&mut self) -> &mut F::Block;
41}
42pub trait Term<F: Func + ?Sized> {
43 type Target: Target<F>;
44 fn targets<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::Target> + 'a>
45 where
46 F: 'a;
47 fn targets_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut Self::Target> + 'a>
48 where
49 F: 'a;
50}
51
52impl<F: Func + ?Sized, T: Target<F>, A: Term<F, Target = T>, B: Term<F, Target = T>> Term<F>
53 for Either<A, B>
54{
55 type Target = T;
56
57 fn targets<'a>(&'a self) -> Box<(dyn Iterator<Item = &'a T> + 'a)>
58 where
59 F: 'a,
60 {
61 match self {
62 Either::Left(a) => a.targets(),
63 Either::Right(b) => b.targets(),
64 }
65 }
66
67 fn targets_mut<'a>(&'a mut self) -> Box<(dyn Iterator<Item = &'a mut T> + 'a)>
68 where
69 F: 'a,
70 {
71 match self {
72 Either::Left(a) => a.targets_mut(),
73 Either::Right(b) => b.targets_mut(),
74 }
75 }
76}