1 //! Compatibility constraints between matrix shapes, e.g., for addition or multiplication. 2 3 use crate::base::dimension::{Dim, DimName, Dynamic}; 4 5 /// A type used in `where` clauses for enforcing constraints. 6 pub struct ShapeConstraint; 7 8 /// Constraints `C1` and `R2` to be equivalent. 9 pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {} 10 11 impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where ShapeConstraint: DimEq<C1, R2> 12 {} 13 14 /// Constraints `D1` and `D2` to be equivalent. 15 pub trait DimEq<D1: Dim, D2: Dim> { 16 /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level 17 /// constant. 18 type Representative: Dim; 19 } 20 21 impl<D: Dim> DimEq<D, D> for ShapeConstraint { 22 type Representative = D; 23 } 24 25 impl<D: DimName> DimEq<D, Dynamic> for ShapeConstraint { 26 type Representative = D; 27 } 28 29 impl<D: DimName> DimEq<Dynamic, D> for ShapeConstraint { 30 type Representative = D; 31 } 32 33 macro_rules! equality_trait_decl( 34 ($($doc: expr, $Trait: ident),* $(,)*) => {$( 35 // XXX: we can't do something like `DimEq<D1> for D2` because we would require a blancket impl… 36 #[doc = $doc] 37 pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> { 38 /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level 39 /// constant. 40 type Representative: Dim; 41 } 42 43 impl<D: Dim> $Trait<D, D> for ShapeConstraint { 44 type Representative = D; 45 } 46 47 impl<D: DimName> $Trait<D, Dynamic> for ShapeConstraint { 48 type Representative = D; 49 } 50 51 impl<D: DimName> $Trait<Dynamic, D> for ShapeConstraint { 52 type Representative = D; 53 } 54 )*} 55 ); 56 57 equality_trait_decl!( 58 "Constraints `D1` and `D2` to be equivalent. \ 59 They are both assumed to be the number of \ 60 rows of a matrix.", 61 SameNumberOfRows, 62 "Constraints `D1` and `D2` to be equivalent. \ 63 They are both assumed to be the number of \ 64 columns of a matrix.", 65 SameNumberOfColumns 66 ); 67 68 /// Constraints D1 and D2 to be equivalent, where they both designate dimensions of algebraic 69 /// entities (e.g. square matrices). 70 pub trait SameDimension<D1: Dim, D2: Dim>: 71 SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2> 72 { 73 /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level 74 /// constant. 75 type Representative: Dim; 76 } 77 78 impl<D: Dim> SameDimension<D, D> for ShapeConstraint { 79 type Representative = D; 80 } 81 82 impl<D: DimName> SameDimension<D, Dynamic> for ShapeConstraint { 83 type Representative = D; 84 } 85 86 impl<D: DimName> SameDimension<Dynamic, D> for ShapeConstraint { 87 type Representative = D; 88 } 89