use std::marker::PhantomData;
use crate::analysis::cpa::residue::Residue;
use crate::analysis::cpa::state::AbstractState;
pub struct VecReducer<S>
where
S: AbstractState,
{
pub visited: Vec<S>,
_phantom: PhantomData<S>,
}
impl<S> VecReducer<S>
where
S: AbstractState,
{
pub fn new_with_capacity(cap: usize) -> Self {
Self {
visited: Vec::with_capacity(cap),
_phantom: Default::default(),
}
}
}
impl<S> Default for VecReducer<S>
where
S: AbstractState,
{
fn default() -> Self {
Self {
visited: Vec::new(),
_phantom: Default::default(),
}
}
}
impl<S> Residue<S> for VecReducer<S>
where
S: AbstractState,
{
type Output = Vec<S>;
fn new_state(
&mut self,
_state: &S,
dest_state: &S,
_op: &Option<crate::analysis::pcode_store::PcodeOpRef<'_>>,
) {
self.visited.push(dest_state.clone());
}
fn merged_state(
&mut self,
_curr_state: &S,
dest_state: &S,
merged_state: &S,
_op: &Option<crate::analysis::pcode_store::PcodeOpRef<'_>>,
) {
for entry in &mut self.visited {
if entry == dest_state {
*entry = merged_state.clone();
}
}
}
fn new() -> Self {
Self::default()
}
fn finalize(self) -> Self::Output {
self.visited
}
}