nalgebra/base/
constraint.rs

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