use crate::{
DBWeight,
algebra::{AddAssignByRef, AddByRef, HasZero},
declare_trait_object, declare_typed_trait_object,
dynamic::data::DataTyped,
};
use super::{Data, DataTrait, DataTraitTyped};
pub trait Weight: Data {
fn set_zero(&mut self);
fn is_zero(&self) -> bool;
unsafe fn raw_add(&self, rhs: *const u8, result: *mut u8);
unsafe fn raw_add_assign(&mut self, rhs: *const u8);
}
impl<T: DBWeight> Weight for T {
fn set_zero(&mut self) {
*self = HasZero::zero();
}
fn is_zero(&self) -> bool {
HasZero::is_zero(self)
}
unsafe fn raw_add(&self, rhs: *const u8, result: *mut u8) {
unsafe { *(result as *mut Self) = AddByRef::add_by_ref(self, &*(rhs as *const Self)) }
}
unsafe fn raw_add_assign(&mut self, rhs: *const u8) {
unsafe { AddAssignByRef::add_assign_by_ref(self, &*(rhs as *const Self)) }
}
}
pub trait WeightTyped: Weight + DataTyped {}
impl<T> WeightTyped for T where T: Weight + DataTyped {}
pub trait WeightTrait: DataTrait + Weight {
fn add(&self, rhs: &Self, result: &mut Self) {
debug_assert_eq!(self.as_any().type_id(), rhs.as_any().type_id());
debug_assert_eq!(self.as_any().type_id(), result.as_any().type_id());
unsafe {
Weight::raw_add(
self,
rhs as *const Self as *const u8,
result as *mut Self as *mut u8,
)
}
}
fn add_assign(&mut self, rhs: &Self) {
debug_assert_eq!(self.as_any().type_id(), rhs.as_any().type_id());
unsafe { Weight::raw_add_assign(self, rhs as *const Self as *const u8) }
}
}
impl<Trait: ?Sized> WeightTrait for Trait where Trait: DataTrait + Weight {}
pub trait WeightTraitTyped: WeightTrait + DataTraitTyped {}
impl<Trait: ?Sized> WeightTraitTyped for Trait where Trait: WeightTrait + DataTraitTyped {}
declare_trait_object!(DynWeight<> = dyn Weight<>
where
);
declare_typed_trait_object!(DynWeightTyped<T> = dyn WeightTyped<Type = T>
[T]
where
T: DBWeight,
);