Create a gist now

Instantly share code, notes, and snippets.

@bjz /range_type.rs
Last active Dec 19, 2015

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());
}
@MarkJr94

Can you try and get this into std? Perhaps in std::util? This seems useful for all sorts of stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment