59 lines
1.6 KiB
Rust
59 lines
1.6 KiB
Rust
use std::ops::*;
|
|
|
|
#[const_trait]
|
|
pub trait F32Util {
|
|
fn lerp<T: const Mul<f32, Output = T> + const Add<Output = T>>(self, from: T, to: T) -> T;
|
|
}
|
|
|
|
impl const F32Util for f32 {
|
|
fn lerp<T: const Mul<f32, Output = T> + const Add<Output = T>>(self, from: T, to: T) -> T {
|
|
from * (1.0 - self) + to * self
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_op {
|
|
($T:ident $op:ident $fn:ident $opa:ident $fna:ident; $($field:ident)*) => {
|
|
mod ${concat(op_, $fn, _impl)} {
|
|
use super::*;
|
|
#[allow(unused_imports)]
|
|
use std::ops::*;
|
|
impl const $op for $T {
|
|
type Output = Self;
|
|
|
|
fn $fn(self, rhs: Self) -> Self::Output {
|
|
Self {
|
|
$($field: self.$field.$fn(rhs.$field),)*
|
|
}
|
|
}
|
|
}
|
|
impl $opa for $T {
|
|
fn $fna(&mut self, rhs: Self) {
|
|
$(self.$field.$fna(rhs.$field);)*
|
|
}
|
|
}
|
|
impl const $op<f32> for $T {
|
|
type Output = Self;
|
|
|
|
fn $fn(self, rhs: f32) -> Self::Output {
|
|
Self {
|
|
$($field: self.$field.$fn(rhs),)*
|
|
}
|
|
}
|
|
}
|
|
impl $opa<f32> for $T {
|
|
fn $fna(&mut self, rhs: f32) {
|
|
$(self.$field.$fna(rhs);)*
|
|
}
|
|
}
|
|
}
|
|
};
|
|
($T:ident $op:ident $fn:ident; $($field:ident)*) => {
|
|
impl_op!($T $op $fn ${concat($op,Assign)} ${concat($fn,_assign)}; $($field)*);
|
|
};
|
|
(impl $op:ident for $T:ident: $fn:ident $($field:ident)*) => {
|
|
impl_op!($T $op $fn ${concat($op,Assign)} ${concat($fn,_assign)}; $($field)*);
|
|
};
|
|
}
|
|
|
|
pub(crate) use impl_op;
|