#![allow(clippy::should_implement_trait)]
use crate::{
Context, ControlNode, ControlNodeDef, ControlRegion, ControlRegionDef, DataInst, DataInstDef,
EntityDefs, EntityList, EntityListIter, FuncDefBody, Type, Value,
};
#[derive(Copy, Clone)]
pub struct FuncAt<'a, P: Copy> {
pub control_regions: &'a EntityDefs<ControlRegion>,
pub control_nodes: &'a EntityDefs<ControlNode>,
pub data_insts: &'a EntityDefs<DataInst>,
pub position: P,
}
impl<'a, P: Copy> FuncAt<'a, P> {
pub fn at<P2: Copy>(self, new_position: P2) -> FuncAt<'a, P2> {
FuncAt {
control_regions: self.control_regions,
control_nodes: self.control_nodes,
data_insts: self.data_insts,
position: new_position,
}
}
}
impl<'a> FuncAt<'a, ControlRegion> {
pub fn def(self) -> &'a ControlRegionDef {
&self.control_regions[self.position]
}
pub fn at_children(self) -> FuncAt<'a, EntityList<ControlNode>> {
self.at(self.def().children)
}
}
impl<'a> IntoIterator for FuncAt<'a, EntityList<ControlNode>> {
type IntoIter = FuncAt<'a, EntityListIter<ControlNode>>;
type Item = FuncAt<'a, ControlNode>;
fn into_iter(self) -> Self::IntoIter {
self.at(self.position.iter())
}
}
impl<'a> Iterator for FuncAt<'a, EntityListIter<ControlNode>> {
type Item = FuncAt<'a, ControlNode>;
fn next(&mut self) -> Option<Self::Item> {
let (next, rest) = self.position.split_first(self.control_nodes)?;
self.position = rest;
Some(self.at(next))
}
}
impl<'a> FuncAt<'a, ControlNode> {
pub fn def(self) -> &'a ControlNodeDef {
&self.control_nodes[self.position]
}
}
impl<'a> IntoIterator for FuncAt<'a, EntityList<DataInst>> {
type IntoIter = FuncAt<'a, EntityListIter<DataInst>>;
type Item = FuncAt<'a, DataInst>;
fn into_iter(self) -> Self::IntoIter {
self.at(self.position.iter())
}
}
impl<'a> Iterator for FuncAt<'a, EntityListIter<DataInst>> {
type Item = FuncAt<'a, DataInst>;
fn next(&mut self) -> Option<Self::Item> {
let (next, rest) = self.position.split_first(self.data_insts)?;
self.position = rest;
Some(self.at(next))
}
}
impl<'a> DoubleEndedIterator for FuncAt<'a, EntityListIter<DataInst>> {
fn next_back(&mut self) -> Option<Self::Item> {
let (prev, rest) = self.position.split_last(self.data_insts)?;
self.position = rest;
Some(self.at(prev))
}
}
impl<'a> FuncAt<'a, DataInst> {
pub fn def(self) -> &'a DataInstDef {
&self.data_insts[self.position]
}
}
impl FuncAt<'_, Value> {
pub fn type_of(self, cx: &Context) -> Type {
match self.position {
Value::Const(ct) => cx[ct].ty,
Value::ControlRegionInput { region, input_idx } => {
self.at(region).def().inputs[input_idx as usize].ty
}
Value::ControlNodeOutput { control_node, output_idx } => {
self.at(control_node).def().outputs[output_idx as usize].ty
}
Value::DataInstOutput(inst) => cx[self.at(inst).def().form].output_type.unwrap(),
}
}
}
pub struct FuncAtMut<'a, P: Copy> {
pub control_regions: &'a mut EntityDefs<ControlRegion>,
pub control_nodes: &'a mut EntityDefs<ControlNode>,
pub data_insts: &'a mut EntityDefs<DataInst>,
pub position: P,
}
impl<'a, P: Copy> FuncAtMut<'a, P> {
pub fn reborrow(&mut self) -> FuncAtMut<'_, P> {
FuncAtMut {
control_regions: self.control_regions,
control_nodes: self.control_nodes,
data_insts: self.data_insts,
position: self.position,
}
}
pub fn at<P2: Copy>(self, new_position: P2) -> FuncAtMut<'a, P2> {
FuncAtMut {
control_regions: self.control_regions,
control_nodes: self.control_nodes,
data_insts: self.data_insts,
position: new_position,
}
}
pub fn freeze(self) -> FuncAt<'a, P> {
let FuncAtMut { control_regions, control_nodes, data_insts, position } = self;
FuncAt { control_regions, control_nodes, data_insts, position }
}
}
impl<'a> FuncAtMut<'a, ControlRegion> {
pub fn def(self) -> &'a mut ControlRegionDef {
&mut self.control_regions[self.position]
}
pub fn at_children(mut self) -> FuncAtMut<'a, EntityList<ControlNode>> {
let children = self.reborrow().def().children;
self.at(children)
}
}
impl<'a> FuncAtMut<'a, EntityList<ControlNode>> {
pub fn into_iter(self) -> FuncAtMut<'a, EntityListIter<ControlNode>> {
let iter = self.position.iter();
self.at(iter)
}
}
impl FuncAtMut<'_, EntityListIter<ControlNode>> {
pub fn next(&mut self) -> Option<FuncAtMut<'_, ControlNode>> {
let (next, rest) = self.position.split_first(self.control_nodes)?;
self.position = rest;
Some(self.reborrow().at(next))
}
}
impl<'a> FuncAtMut<'a, ControlNode> {
pub fn def(self) -> &'a mut ControlNodeDef {
&mut self.control_nodes[self.position]
}
}
impl<'a> FuncAtMut<'a, EntityList<DataInst>> {
pub fn into_iter(self) -> FuncAtMut<'a, EntityListIter<DataInst>> {
let iter = self.position.iter();
self.at(iter)
}
}
impl FuncAtMut<'_, EntityListIter<DataInst>> {
pub fn next(&mut self) -> Option<FuncAtMut<'_, DataInst>> {
let (next, rest) = self.position.split_first(self.data_insts)?;
self.position = rest;
Some(self.reborrow().at(next))
}
}
impl<'a> FuncAtMut<'a, DataInst> {
pub fn def(self) -> &'a mut DataInstDef {
&mut self.data_insts[self.position]
}
}
impl FuncDefBody {
pub fn at<P: Copy>(&self, position: P) -> FuncAt<'_, P> {
FuncAt {
control_regions: &self.control_regions,
control_nodes: &self.control_nodes,
data_insts: &self.data_insts,
position,
}
}
pub fn at_mut<P: Copy>(&mut self, position: P) -> FuncAtMut<'_, P> {
FuncAtMut {
control_regions: &mut self.control_regions,
control_nodes: &mut self.control_nodes,
data_insts: &mut self.data_insts,
position,
}
}
pub fn at_body(&self) -> FuncAt<'_, ControlRegion> {
self.at(self.body)
}
pub fn at_mut_body(&mut self) -> FuncAtMut<'_, ControlRegion> {
self.at_mut(self.body)
}
}