Skip to content

Commit

Permalink
add final Mul/Div/MulAsign/DivAssign impls - fix not having a dimensi…
Browse files Browse the repository at this point in the history
…on trait bound on concrete<->concrete implementations
  • Loading branch information
Tehforsch committed Jan 7, 2024
1 parent 93b05c1 commit 5f93ed7
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 113 deletions.
34 changes: 25 additions & 9 deletions crates/diman_unit_system/src/codegen/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ impl NumericTrait {
quantity_type: &Ident,
output_type: &Option<OutputQuantity>,
) -> TokenStream {
if matches!(self.lhs.storage, StorageType::Generic)
let storage_bounds = if matches!(self.lhs.storage, StorageType::Generic)
|| matches!(self.rhs.storage, StorageType::Generic)
{
let (lhs_storage, rhs_storage) = self.storage_types();
Expand All @@ -395,25 +395,34 @@ impl NumericTrait {
} else {
quote! {}
};
let generic_const_bound = output_type
.as_ref()
.map(|output_type| output_type.generic_const_bound(&quantity_type))
.unwrap_or(quote! {});
quote! {
#lhs_storage: #trait_name :: < #rhs_storage, #output_bound >,
#lhs_copy_bound
#rhs_copy_bound
#generic_const_bound
}
} else {
quote! {}
};
let generic_const_bound = output_type
.as_ref()
.map(|output_type| output_type.generic_const_bound(&quantity_type))
.unwrap_or(quote! {});
quote! {
#storage_bounds
#generic_const_bound
}
}

fn output_quantity_storage(&self) -> TokenStream {
assert!(self.name.has_output_type());
let trait_name = self.name.name();
let (lhs, rhs) = self.storage_types();
if let StorageType::Concrete(lhs_ty) = &self.lhs.storage {
if let StorageType::Concrete(rhs_ty) = &self.rhs.storage {
assert_eq!(lhs_ty, rhs_ty);
return quote! { #lhs_ty };
}
}
quote! { < #lhs as #trait_name<#rhs> >::Output }
}

Expand Down Expand Up @@ -595,11 +604,18 @@ impl Defs {
add_trait!(traits, t, (&Quantity, Concrete(ty.clone())), (Storage, Concrete(ty.clone())));
add_trait!(traits, t, (Quantity, Concrete(ty.clone())), (&Storage, Concrete(ty.clone())));
add_trait!(traits, t, (&Quantity, Concrete(ty.clone())), (&Storage, Concrete(ty.clone())));
add_trait!(traits, t, (Storage, Concrete(ty.clone())), (Quantity, Generic));
add_trait!(traits, t, (Storage, Concrete(ty.clone())), (Quantity, Concrete(ty.clone())));
add_trait!(traits, t, (&Storage, Concrete(ty.clone())), (Quantity, Concrete(ty.clone())));
add_trait!(traits, t, (Storage, Concrete(ty.clone())), (&Quantity, Concrete(ty.clone())));
add_trait!(traits, t, (&Storage, Concrete(ty.clone())), (&Quantity, Concrete(ty.clone())));
}
for t in [MulAssign, DivAssign] {
add_trait!(traits, t, (Quantity, Generic), (Storage, Concrete(ty.clone())));
add_trait!(traits, t, (Storage, Concrete(ty.clone())), (Quantity, Generic));
add_trait!(traits, t, (Quantity, Concrete(ty.clone())), (Storage, Concrete(ty.clone())));
add_trait!(traits, t, (Quantity, Concrete(ty.clone())), (&Storage, Concrete(ty.clone())));
add_trait!(traits, t, (Storage, Concrete(ty.clone())), (Dimensionless, Concrete(ty.clone())));
add_trait!(traits, t, (Storage, Concrete(ty.clone())), (&Dimensionless, Concrete(ty.clone())));
// Primitive storage types like f32 dont implement &mut f32: MulAssign<f32>, so
// we won't either.
}
for t in [PartialEq, PartialOrd] {
add_trait!(traits, t, (Dimensionless, Generic), (Storage, Concrete(ty.clone())));
Expand Down
216 changes: 112 additions & 104 deletions tests/float/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,41 @@ macro_rules! gen_tests_for_float {
assert_is_close(&x + &y, Length::meters(11.0));
}

#[test]
fn add_quantity_type() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_type_quantity() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(y + x, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_ref_type() {
let x = &Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_quantity_reftype() {
let x = Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_ref_reftype() {
let x = &Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_assign_quantity_quantity() {
let mut x = Length::meters(1.0);
Expand Down Expand Up @@ -97,41 +132,6 @@ macro_rules! gen_tests_for_float {
assert_is_close(*x, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_quantity_type() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_type_quantity() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(y + x, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_ref_type() {
let x = &Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_quantity_reftype() {
let x = Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn add_ref_reftype() {
let x = &Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x + y, Dimensionless::dimensionless(11.0));
}

#[test]
fn sum_quantity_type() {
let items = [
Expand Down Expand Up @@ -164,6 +164,41 @@ macro_rules! gen_tests_for_float {
assert_is_close(&x - &y, Length::meters(-9.0));
}

#[test]
fn sub_quantity_type() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_type_quantity() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(y - x, Dimensionless::dimensionless(9.0));
}

#[test]
fn sub_ref_type() {
let x = &Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_quantity_reftype() {
let x = Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_ref_reftype() {
let x = &Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_assign_quantity_quantity() {
let mut x = Length::meters(1.0);
Expand Down Expand Up @@ -220,41 +255,6 @@ macro_rules! gen_tests_for_float {
assert_is_close(*x, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_quantity_type() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_type_quantity() {
let x = Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(y - x, Dimensionless::dimensionless(9.0));
}

#[test]
fn sub_ref_type() {
let x = &Dimensionless::dimensionless(1.0);
let y = 10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_quantity_reftype() {
let x = Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn sub_ref_reftype() {
let x = &Dimensionless::dimensionless(1.0);
let y = &10.0;
assert_is_close(x - y, Dimensionless::dimensionless(-9.0));
}

#[test]
fn neg_quantity() {
let x = Length::meters(5.0);
Expand Down Expand Up @@ -291,6 +291,41 @@ macro_rules! gen_tests_for_float {
assert_is_close(&x * &y, Energy::joules(6.0));
}

#[test]
fn mul_quantity_type() {
let x = Force::newtons(2.0);
let y = 3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_type_quantity() {
let x = 3.0;
let y = Force::newtons(2.0);
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_quantity_typeref() {
let x = Force::newtons(2.0);
let y = &3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_ref_type() {
let x = &Force::newtons(2.0);
let y = 3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_ref_typeref() {
let x = &Force::newtons(2.0);
let y = &3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_assign_quantity_quantity() {
let mut x = Force::newtons(2.0);
Expand Down Expand Up @@ -323,34 +358,6 @@ macro_rules! gen_tests_for_float {
assert_is_close(*x, Force::newtons(6.0));
}

#[test]
fn mul_quantity_typeref() {
let x = Force::newtons(2.0);
let y = &3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_ref_type() {
let x = &Force::newtons(2.0);
let y = 3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_ref_typeref() {
let x = &Force::newtons(2.0);
let y = &3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_quantity_type() {
let x = Force::newtons(2.0);
let y = 3.0;
assert_is_close(x * y, Force::newtons(6.0));
}

#[test]
fn mul_assign_quantity_type() {
let mut x = Force::newtons(2.0);
Expand All @@ -360,16 +367,17 @@ macro_rules! gen_tests_for_float {
}

#[test]
fn mul_type_quantity() {
let x = 3.0;
let y = Force::newtons(2.0);
assert_is_close(x * y, Force::newtons(6.0));
fn mul_assign_type_quantity() {
let mut x = 3.0;
let y = Dimensionless::dimensionless(2.0);
x *= y;
assert_is_close_float(x, 6.0);
}

#[test]
fn mul_assign_type_quantity() {
fn mul_assign_type_ref() {
let mut x = 3.0;
let y = Dimensionless::dimensionless(2.0);
let y = &Dimensionless::dimensionless(2.0);
x *= y;
assert_is_close_float(x, 6.0);
}
Expand Down

0 comments on commit 5f93ed7

Please sign in to comment.