Skip to content

Instantly share code, notes, and snippets.

@franziskuskiefer
Created April 4, 2021 08:19
Show Gist options
  • Save franziskuskiefer/920fa6fdcf3d47cdbbdbe325e8e87275 to your computer and use it in GitHub Desktop.
Save franziskuskiefer/920fa6fdcf3d47cdbbdbe325e8e87275 to your computer and use it in GitHub Desktop.
range integers
use std::ops::{Add, Div, Mul, Sub};
struct Uint8<const MIN: u8, const MAX: u8> {
val: u8,
}
impl<const MIN: u8, const MAX: u8> Uint8<MIN, MAX> {
const MIN: u8 = MIN;
const MAX: u8 = MAX;
fn check(val: u8) -> Self {
debug_assert!(
val >= Self::MIN && val <= Self::MAX,
"{} <= {} <= {}",
Self::MIN,
val,
Self::MAX
);
Self { val }
}
pub fn new(val: u8) -> Self {
Self::check(val)
}
}
impl<const MIN: u8, const MAX: u8> From<u8> for Uint8<MIN, MAX> {
fn from(val: u8) -> Self {
Self::check(val)
}
}
macro_rules! implement_op {
($op:tt, $op_name:ident, $func_op:ident) => {
impl<const MIN: u8, const MAX: u8> $op_name for Uint8<MIN, MAX> {
type Output = Self;
fn $func_op(self, rhs: Self) -> Self {
let val = self.val $op rhs.val;
Self::check(val)
}
}
}
}
implement_op!(+, Add, add);
implement_op!(-, Sub, sub);
implement_op!(*, Mul, mul);
implement_op!(/, Div, div);
macro_rules! range {
($name:ident, u8, $min:literal, $max:literal) => {
type $name = Uint8<$min, $max>;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works_macro() {
range!(Uint8_20_50, u8, 20, 50);
let _x = Uint8_20_50::new(25);
let _y = Uint8_20_50::new(30);
let _x: Uint8_20_50 = 32.into();
}
#[test]
fn it_works() {
let _x = Uint8::<5, 10>::new(5);
let _y = Uint8::<5, 10>::new(6);
}
#[test]
#[should_panic]
fn it_works_no_add() {
let x = Uint8::<5, 10>::new(5);
let y = Uint8::<5, 10>::new(6);
let _r = x + y;
}
#[test]
#[should_panic]
fn it_works_no_mul() {
let x = Uint8::<5, 10>::new(5);
let y = Uint8::<5, 10>::new(5);
let _r = x * y;
}
#[test]
#[should_panic]
fn it_works_no_sub() {
let x = Uint8::<5, 10>::new(9);
let y = Uint8::<5, 10>::new(5);
let _r = x - y;
}
#[test]
#[should_panic]
fn it_works_not() {
let _x = Uint8::<5, 10>::new(4);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment