Skip to content
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
Something went wrong with that request. Please try again.