use std::marker::PhantomData;
use super::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<'a, S> Residue<'a, 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<'a>>,
) {
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<'a>>,
) {
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
}
}
#[derive(Clone, Copy, Debug)]
pub struct VecReducerFactory;
impl VecReducerFactory {
pub const fn new() -> Self {
VecReducerFactory
}
}
impl Default for VecReducerFactory {
fn default() -> Self {
VecReducerFactory::new()
}
}
pub const VEC: VecReducerFactory = VecReducerFactory;
impl<A> super::ReducerFactoryForState<A> for VecReducerFactory
where
A: crate::analysis::cpa::ConfigurableProgramAnalysis,
A::State: AbstractState,
{
type Reducer<'op> = VecReducer<A::State>;
fn make<'op>(&self) -> Self::Reducer<'op> {
VecReducer::default()
}
}