use crate::math::expressions::d2::{FlipExpression, GetY};
#[cfg_attr(feature = "bitcode", derive(bitcode::Encode, bitcode::Decode))]
#[cfg_attr(
feature = "wincode",
derive(wincode::SchemaWrite, wincode::SchemaRead)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
#[cfg_attr(feature = "c_compatible", repr(C))]
pub struct XHolder<T, E> {
pub x: T,
pub expression: E,
}
impl<T, E: GetY<T>> GetY<T> for XHolder<T, E> {
fn get_y(&self, x: T) -> T {
self.expression.get_y(x)
}
}
impl<T: Clone, E: FlipExpression> FlipExpression for XHolder<T, E> {
fn flip_horizontally(&self) -> Self {
Self {
x: self.x.clone(),
expression: self.expression.flip_horizontally(),
}
}
fn flip_vertically(&self) -> Self {
Self {
x: self.x.clone(),
expression: self.expression.flip_vertically(),
}
}
}
impl<T, E> XHolder<T, E> {
pub const fn new(x: T, expression: E) -> Self {
Self {
x,
expression,
}
}
pub fn with_x<U>(self, x: U) -> XHolder<U, E> {
XHolder {
x,
expression: self.expression,
}
}
pub fn map_expression<F, E2>(self, f: F) -> XHolder<T, E2>
where
F: FnOnce(E) -> E2,
{
XHolder {
x: self.x,
expression: f(self.expression),
}
}
}
impl<T, E> AsRef<E> for XHolder<T, E> {
fn as_ref(&self) -> &E {
&self.expression
}
}
#[cfg(feature = "std")]
impl<T, E> std::borrow::Borrow<E> for XHolder<T, E> {
fn borrow(&self) -> &E {
&self.expression
}
}