From d0b41eca0a12681a8982fb669ba678a4bd814aaf Mon Sep 17 00:00:00 2001 From: Artur Sinila Date: Sun, 24 Jul 2022 20:44:10 +0300 Subject: [PATCH] feat: use `(U, Const)` as default generic types in `type_array!` * feat: use `i8` instead of `i32` for exponents --- src/base_unit.rs | 100 +++++++++++++++++++++++++++++++++++++++++---- src/isq.rs | 39 ++++++++++-------- src/name.rs | 2 +- src/typenum/mod.rs | 10 ++--- src/util.rs | 16 ++++---- 5 files changed, 129 insertions(+), 38 deletions(-) diff --git a/src/base_unit.rs b/src/base_unit.rs index 6d0faae..0c3b398 100644 --- a/src/base_unit.rs +++ b/src/base_unit.rs @@ -1,7 +1,9 @@ use crate::{ ops::{Div as UnitDiv, Inv, Mul as UnitMul}, - Name, Prefix, Root, + typenum::{Constant, ToConst, ToTypenum, Typenum}, + Const, Name, Prefix, Root, }; +use const_default::ConstDefault; use core::{ i32, marker::PhantomData, @@ -13,21 +15,27 @@ use typenum::{Diff, Negate, Sum}; pub struct Pre(PhantomData<(P, R)>); pub trait Exponent { - const EXP: i32; + const EXP: i8; } impl Exponent for () { - const EXP: i32 = 0; + const EXP: i8 = 0; } impl Exponent for R { - const EXP: i32 = 1; + const EXP: i8 = 1; } impl Exponent for Pre { - const EXP: i32 = 1; + const EXP: i8 = 1; } +impl Exponent for Exp { + const EXP: i8 = E; +} + +pub struct Exp(PhantomData); + /// Base unit for system of units pub trait BaseUnit {} @@ -59,11 +67,23 @@ impl crate::name::Debug for (U, E) { } } -impl, Er> UnitMul<(U, Er)> for (U, El) { +impl crate::name::Display for Exp { + fn display() -> String { + U::display() + } +} + +impl crate::name::Debug for Exp { + fn debug() -> String { + U::debug() + } +} + +impl, Er> UnitMul<(U, Er)> for (U, El) { type Output = (U, Sum); } -impl, Er> UnitDiv<(U, Er)> for (U, El) { +impl, Er> UnitDiv<(U, Er)> for (U, El) { type Output = (U, Diff); } @@ -99,6 +119,72 @@ impl Inv for () { type Output = (); } +// ----------------------------------------- + +pub trait ToExp { + type Output; +} + +impl ToExp for Const { + type Output = Exp; +} + +type ToExponent = >::Output; + +impl UnitMul> for Exp +where + Const: ToTypenum, + Const: ToTypenum, + Typenum>: Add>>, + Sum>, Typenum>>: ToConst, + Constant>, Typenum>>>: ToExp + ConstDefault, +{ + type Output = ToExponent, Const>>; +} + +impl UnitDiv> for Exp +where + Const: ToTypenum, + Const: ToTypenum, + Typenum>: Sub>>, + Diff>, Typenum>>: ToConst, + Constant>, Typenum>>>: ToExp + ConstDefault, +{ + type Output = ToExponent, Const>>; +} + +impl Inv for Exp +where + Const: ToTypenum, + Typenum>: Neg, + Negate>>: ToConst, + Constant>>>: ToExp + ConstDefault, +{ + type Output = ToExponent>>; +} + +impl UnitMul> for () { + type Output = Exp; +} + +impl UnitMul<()> for Exp { + type Output = Exp; +} + +impl UnitDiv<()> for Exp { + type Output = Exp; +} + +impl UnitDiv> for () +where + Const: ToTypenum, + Typenum>: Neg, + Negate>>: ToConst, + Constant>>>: ToExp + ConstDefault, +{ + type Output = ToExponent>>; +} + pub trait ConvertFrom { fn convert_from(value: V) -> V; } diff --git a/src/isq.rs b/src/isq.rs index 7a01b0d..58f9d93 100644 --- a/src/isq.rs +++ b/src/isq.rs @@ -1,5 +1,5 @@ use crate::{ - base_unit::Exponent, + base_unit::{Exponent, Pre}, name::superscript, ops::{Div as UnitDiv, Inv as UnitInv, Mul as UnitMul}, util::{impl_binary_op_for_type_array, impl_unary_op_for_type_array, type_array}, @@ -13,6 +13,11 @@ use core::{ }; use std::ops::Neg; +use self::{ + prefix::kilo, + root::{ampere, candela, gram, meter, mole, second, Kelvin}, +}; + /// Metric prefixes pub mod prefix { use crate::prefix::prefixes; @@ -99,7 +104,9 @@ pub mod root { impl kind::LuminousIntensity for Pre {} } -type_array!(Unit); +type Kg = Pre; + +type_array!(Unit); impl_binary_op_for_type_array!(Unit, Mul, UnitMul); impl_binary_op_for_type_array!(Unit, Div, UnitDiv); impl_unary_op_for_type_array!(Unit, UnitInv, UnitInv); @@ -111,11 +118,11 @@ impl ConstDefault for Unit { #[derive(Clone, Debug)] struct ExpUnit { pub name: String, - pub exp: i32, + pub exp: i8, } impl ExpUnit { - fn new(name: String, exp: i32) -> Self { + fn new(name: String, exp: i8) -> Self { Self { name, exp } } } @@ -131,7 +138,7 @@ impl Neg for ExpUnit { impl Display for ExpUnit { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name)?; - if self.exp.abs() != 1 { + if self.exp != 1 { write!(f, "{}", superscript(self.exp))?; } Ok(()) @@ -200,7 +207,10 @@ pub mod unit { root::{cd, g, gram, m, meter, mol, s, second, A, K}, Unit, }; - use crate::{base_unit::Pre, typenum::Const}; + use crate::{ + base_unit::{Exp, Pre}, + typenum::Const, + }; macro_rules! unit_aliases { ($(($m:literal, $kg:literal, $s:literal, $A:literal, $K:literal, $mol:literal, $cd:literal) -> $alias:ident,)+) => { @@ -211,9 +221,9 @@ pub mod unit { unit_aliases! { (0, 0, 0, 0, 0, 0, 0) -> Dimensionless, - (1, 0, 0, 0, 0, 0, 0) -> Meter, + // (1, 0, 0, 0, 0, 0, 0) -> Meter, (0, 1, 0, 0, 0, 0, 0) -> Kilogram, - (0, 0, 1, 0, 0, 0, 0) -> Second, + // (0, 0, 1, 0, 0, 0, 0) -> Second, (0, 0, 0, 1, 0, 0, 0) -> Ampere, (0, 0, 0, 0, 1, 0, 0) -> Kelvin, (0, 0, 0, 0, 0, 1, 0) -> Mole, @@ -221,10 +231,10 @@ pub mod unit { (1, 0,-1, 0, 0, 0, 0) -> MeterPerSecond, (2, 0, 0, 0, 0, 0, 0) -> MeterSquared, } - // pub type Meter = Unit<(meter, Const<1>)>; + pub type Meter = Unit<(meter, Const<1>)>; // pub type Kilometer = Unit<(Pre, Const<1>)>; // pub type MeterSquared = Unit<(meter, Const<2>)>; - // pub type Second = Unit<(), (), (second, Const<1>)>; + pub type Second = Unit<(), (), (second, Const<1>)>; // pub type Kilogram = Unit<(), (Pre, Const<1>)>; } @@ -336,16 +346,13 @@ mod tests { isq::{consts::kg, unit::Meter}, Quantity, }; - use nalgebra::{RowVector3, Vector3}; + // use nalgebra::{RowVector3, Vector3}; #[test] fn nalgebra_vec() { let l1 = 12_f32 * m; - let l2 = 1_f32 * (m / s); + let l2 = 1_f32 * m; let l3 = l1 + l2; - let v1 = Quantity::::new(RowVector3::new(1, 2, -1)); - let v2 = Quantity::::new(RowVector3::new(-1, -2, 1)); - println!("{}\n{}\n{}", v1.clone(), v2.clone(), v1 + v2); - println!("{}", RowVector3::::default()) + println!("{l1}\n{l2}\n{l3}"); } } diff --git a/src/name.rs b/src/name.rs index 53c4866..6136b4e 100644 --- a/src/name.rs +++ b/src/name.rs @@ -32,7 +32,7 @@ impl Debug for N { } } -pub fn superscript(num: i32) -> String { +pub fn superscript(num: i8) -> String { let s = num.to_string(); s.bytes() .map(|c| match c { diff --git a/src/typenum/mod.rs b/src/typenum/mod.rs index dd62afd..42f43c6 100644 --- a/src/typenum/mod.rs +++ b/src/typenum/mod.rs @@ -43,9 +43,9 @@ pub trait ToConst { pub type Constant = ::Const; #[derive(Clone, Copy)] -pub struct Const; +pub struct Const; -impl ConstDefault for Const { +impl ConstDefault for Const { const DEFAULT: Self = Self; } @@ -60,7 +60,7 @@ macro_rules! num_to_typenum_and_back { } impl Exponent for (U, Const<$const>) { - const EXP: i32 = $const; + const EXP: i8 = $const; })+ }; } @@ -87,7 +87,7 @@ num_to_typenum_and_back! { macro_rules! impl_binary_ops_for_num { ($(($op:ident, $fun:ident, $out:ident),)+) => { - $(impl $op> for Const + $(impl $op> for Const where Const: ToTypenum, Const: ToTypenum, @@ -111,7 +111,7 @@ impl_binary_ops_for_num! { (Div, div, Quot), } -impl Neg for Const +impl Neg for Const where Const: ToTypenum, Typenum>: Neg, diff --git a/src/util.rs b/src/util.rs index 84893e1..668cee8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -14,8 +14,8 @@ macro_rules! count_idents { pub(crate) use count_idents; macro_rules! type_array { - ($name:ident<$($param:ident),+>) => { - pub struct $name<$($param = ()),+>(::core::marker::PhantomData<($($param),+)>); + ($name:ident<$($param:ident = $default:ident),+>) => { + pub struct $name<$($param = ($default, crate::typenum::Const<0>)),+>(::core::marker::PhantomData<($($param),+)>); impl<$($param),+> $name<$($param),+> { const LEN: usize = $crate::util::count_idents!($($param),+); @@ -103,17 +103,15 @@ macro_rules! trait_alias { pub(crate) use trait_alias; +use crate::{ + base_unit::Pre, + isq::{prefix::kilo, root::gram}, +}; + #[cfg(test)] mod tests { #[test] fn count_idents() { assert_eq!(count_idents!(A, B, C, D), 4); } - - #[test] - fn type_array_len() { - type_array!(Test); - const LEN: usize = ::len(); - assert_eq!(LEN, 6); - } }