use crate::read::Readable; use crate::rt::CopyValue; use crate::signal::Signal; use crate::write::Writable; use crate::{GlobalMemo, GlobalSignal, ReadOnlySignal, SignalData}; use generational_box::Storage; use std::{ fmt::{Debug, Display}, ops::{Add, Div, Mul, Sub}, }; macro_rules! read_impls { ($ty:ident $(: $extra_bounds:path)? $(, $bound_ty:ident : $bound:path, $vec_bound_ty:ident : $vec_bound:path)?) => { $( impl Default for $ty { #[track_caller] fn default() -> Self { Self::new_maybe_sync(Default::default()) } } )? impl Display for $ty { #[track_caller] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Display::fmt(v, f)) } } impl Debug for $ty { #[track_caller] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Debug::fmt(v, f)) } } impl PartialEq for $ty { #[track_caller] fn eq(&self, other: &T) -> bool { self.with(|v| *v == *other) } } }; } macro_rules! write_impls { ($ty:ident, $bound:path, $vec_bound:path) => { impl + Copy + 'static, S: $bound> std::ops::Add for $ty { type Output = T; #[track_caller] fn add(self, rhs: T) -> Self::Output { self.with(|v| *v + rhs) } } impl + Copy + 'static, S: $bound> std::ops::AddAssign for $ty { #[track_caller] fn add_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v + rhs) } } impl + Copy + 'static, S: $bound> std::ops::SubAssign for $ty { #[track_caller] fn sub_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v - rhs) } } impl + Copy + 'static, S: $bound> std::ops::Sub for $ty { type Output = T; #[track_caller] fn sub(self, rhs: T) -> Self::Output { self.with(|v| *v - rhs) } } impl + Copy + 'static, S: $bound> std::ops::MulAssign for $ty { #[track_caller] fn mul_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v * rhs) } } impl + Copy + 'static, S: $bound> std::ops::Mul for $ty { type Output = T; #[track_caller] fn mul(self, rhs: T) -> Self::Output { self.with(|v| *v * rhs) } } impl + Copy + 'static, S: $bound> std::ops::DivAssign for $ty { #[track_caller] fn div_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v / rhs) } } impl + Copy + 'static, S: $bound> std::ops::Div for $ty { type Output = T; #[track_caller] fn div(self, rhs: T) -> Self::Output { self.with(|v| *v / rhs) } } }; } read_impls!(CopyValue, S: Storage, S: Storage>); write_impls!(CopyValue, Storage, Storage>); impl> Clone for CopyValue { fn clone(&self) -> Self { *self } } impl> Copy for CopyValue {} read_impls!(Signal, S: Storage>, S: Storage>>); write_impls!(Signal, Storage>, Storage>>); impl>> Clone for Signal { fn clone(&self) -> Self { *self } } impl>> Copy for Signal {} read_impls!( ReadOnlySignal, S: Storage>, S: Storage>> ); impl>> Clone for ReadOnlySignal { fn clone(&self) -> Self { *self } } impl>> Copy for ReadOnlySignal {} read_impls!(GlobalSignal); read_impls!(GlobalMemo: PartialEq);