Skip to main content

tract_data/
exotic.rs

1#![allow(clippy::derived_hash_with_manual_eq)]
2use crate::datum::DatumType;
3use crate::dim::TDim;
4use crate::internal::TVec;
5use std::fmt::Debug;
6
7use downcast_rs::{Downcast, impl_downcast};
8use dyn_eq::DynEq;
9use dyn_hash::DynHash;
10
11pub trait ExoticFact:
12    DynHash + dyn_eq::DynEq + Send + Sync + Debug + dyn_clone::DynClone + Downcast
13{
14    /// Whether or not it is acceptable for a Patch to substitute `self` by `other`.
15    ///
16    /// In other terms, all operators consuming `self` MUST accept also accept `other` without being altered.
17    fn compatible_with(&self, other: &dyn ExoticFact) -> bool {
18        self.dyn_eq(other)
19    }
20
21    fn clarify_dt_shape(&self) -> Option<(DatumType, TVec<TDim>)> {
22        None
23    }
24
25    fn buffer_sizes(&self) -> TVec<TDim>;
26
27    fn mem_size(&self) -> TDim {
28        self.buffer_sizes().iter().sum::<TDim>()
29    }
30}
31
32impl_downcast!(ExoticFact);
33dyn_hash::hash_trait_object!(ExoticFact);
34dyn_clone::clone_trait_object!(ExoticFact);
35dyn_eq::eq_trait_object!(ExoticFact);
36
37impl<T: ExoticFact> From<T> for Box<dyn ExoticFact> {
38    fn from(v: T) -> Self {
39        Box::new(v)
40    }
41}
42
43impl ExoticFact for TVec<Box<dyn ExoticFact>> {
44    fn buffer_sizes(&self) -> TVec<TDim> {
45        self.iter().flat_map(|it| it.buffer_sizes()).collect()
46    }
47}
48impl ExoticFact for TVec<Option<Box<dyn ExoticFact>>> {
49    fn buffer_sizes(&self) -> TVec<TDim> {
50        self.iter().flatten().flat_map(|it| it.buffer_sizes()).collect()
51    }
52}