Last active
November 28, 2017 22:42
-
-
Save brendanzab/5992668 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub trait RangedNum<T>: Num { | |
pub fn min() -> Self; | |
pub fn max() -> Self; | |
pub fn new(x: T) -> Self; | |
pub fn set(&mut self, x: T); | |
pub fn get(&self) -> T; | |
pub fn normalize(&self) -> Self; | |
pub fn normalize_self(&mut self); | |
} | |
macro_rules! range_type( | |
($Type:ident ($T:ty) = $mn:expr .. $mx:expr) => ( | |
// required because macros can't expand into multiple items :( | |
pub mod wrapper { | |
use super::RangedNum; | |
pub fn $Type(x: $T) -> $Type { $Type::new(x) } | |
pub struct $Type { | |
priv _priv: $T | |
} | |
impl $Type { | |
#[inline] pub fn min() -> $Type { $Type { _priv: $mn } } | |
#[inline] pub fn max() -> $Type { $Type { _priv: $mx } } | |
#[inline] pub fn new(x: $T) -> $Type { $Type { _priv: x }.normalize() } | |
} | |
impl RangedNum<$T> for $Type { | |
#[inline] pub fn min() -> $Type { $Type::min() } | |
#[inline] pub fn max() -> $Type { $Type::max() } | |
#[inline] pub fn new(x: $T) -> $Type { $Type::new(x) } | |
#[inline] | |
pub fn set(&mut self, x: $T) { *self = $Type::new(x) } | |
#[inline] | |
pub fn get(&self) -> $T { self._priv } | |
#[inline] | |
pub fn normalize(&self) -> $Type { | |
$Type { | |
_priv: self.get().clamp(&$Type::min().get(), | |
&$Type::max().get()) | |
} | |
} | |
#[inline] | |
pub fn normalize_self(&mut self) { | |
*self = self.normalize() | |
} | |
} | |
impl Eq for $Type { | |
#[inline] | |
fn eq(&self, other: &$Type) -> bool { self.get() == other.get() } | |
#[inline] | |
fn ne(&self, other: &$Type) -> bool { self.get() != other.get() } | |
} | |
impl Ord for $Type { | |
#[inline] | |
fn lt(&self, other: &$Type) -> bool { self.get() < other.get() } | |
#[inline] | |
fn le(&self, other: &$Type) -> bool { self.get() <= other.get() } | |
#[inline] | |
fn ge(&self, other: &$Type) -> bool { self.get() >= other.get() } | |
#[inline] | |
fn gt(&self, other: &$Type) -> bool { self.get() > other.get() } | |
} | |
impl Clone for $Type { | |
#[inline] | |
fn clone(&self) -> $Type { $Type { _priv: self.get().clone() } } | |
} | |
impl Add<$Type, $Type> for $Type { | |
#[inline] | |
fn add(&self, other: &$Type) -> $Type { | |
$Type::new(self.get() + other.get()) | |
} | |
} | |
impl Sub<$Type, $Type> for $Type { | |
#[inline] | |
fn sub(&self, other: &$Type) -> $Type { | |
$Type::new(self.get() - other.get()) | |
} | |
} | |
impl Mul<$Type, $Type> for $Type { | |
#[inline] | |
fn mul(&self, other: &$Type) -> $Type { | |
$Type::new(self.get() * other.get()) | |
} | |
} | |
impl Div<$Type, $Type> for $Type { | |
#[inline] | |
fn div(&self, other: &$Type) -> $Type { | |
$Type::new(self.get() + other.get()) | |
} | |
} | |
impl Rem<$Type, $Type> for $Type { | |
#[inline] | |
fn rem(&self, other: &$Type) -> $Type { | |
$Type::new(self.get() % other.get()) | |
} | |
} | |
impl ToStr for $Type { | |
fn to_str(&self) -> ~str { | |
fmt!("%?", self.get()) | |
} | |
} | |
} | |
) | |
) | |
range_type!(Channelf64(float) = 0.0 .. 1.0) | |
fn main() { | |
use wrapper::*; | |
let x = Channelf64(-0.1); | |
let y = Channelf64(2.0); | |
let z = Channelf64(0.5); | |
println(x.to_str()); | |
println(y.to_str()); | |
println(z.to_str()); | |
println((x + y).to_str()); | |
println((x * y).to_str()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you try and get this into std? Perhaps in
std::util
? This seems useful for all sorts of stuff.