nalgebra/geometry/
op_macros.rs

1#![macro_use]
2
3// TODO: merge with `md_impl`.
4/// Macro for the implementation of multiplication and division.
5macro_rules! md_impl(
6    (
7    // Operator, operator method, and scalar bounds.
8     $Op: ident, $op: ident $(where T: $($ScalarBounds: ident),*)*;
9     // Storage dimensions, and dimension bounds.
10     ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
11     // Const type declaration
12     const $($D: ident),*;
13     // Other generic type declarations.
14     for $($DimsDecl: ident),*;
15     // Where clause.
16     where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
17     // Argument identifiers and types + output.
18     $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
19     // Operator actual implementation.
20     $action: expr;
21     // Lifetime.
22     $($lives: tt),*) => {
23        impl<$($lives ,)* T $(, $DimsDecl)* $(, const $D: usize)*> $Op<$Rhs> for $Lhs
24            where T: Scalar + Zero + One + ClosedAdd + ClosedMul $($(+ $ScalarBounds)*)*,
25                  $( $ConstraintType: $ConstraintBound$(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),*
26                   {
27            type Output = $Result;
28
29            #[inline]
30            fn $op($lhs, $rhs: $Rhs) -> Self::Output {
31                $action
32            }
33        }
34    }
35);
36
37/// Macro for the implementation of multiplication and division.
38/// Implements all the argument reference combinations.
39macro_rules! md_impl_all(
40    (
41     // Operator, operator method, and scalar bounds.
42     $Op: ident, $op: ident $(where T: $($ScalarBounds: ident),*)*;
43     // Storage dimensions, and dimension bounds.
44     ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
45     // Const type declaration
46     const $($D: ident),*;
47     // Other generic type declarations.
48     for $($DimsDecl: ident),*;
49     // Where clause.
50     where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
51     // Argument identifiers and types + output.
52     $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
53     // Operators actual implementations.
54     [val val] => $action_val_val: expr;
55     [ref val] => $action_ref_val: expr;
56     [val ref] => $action_val_ref: expr;
57     [ref ref] => $action_ref_ref: expr;) => {
58
59        md_impl!(
60            $Op, $op $(where T: $($ScalarBounds),*)*;
61            ($R1, $C1),($R2, $C2)
62            const $($D),*;
63            for $($DimsDecl),*;
64            where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
65            $lhs: $Lhs, $rhs: $Rhs, Output = $Result;
66            $action_val_val; );
67
68        md_impl!(
69            $Op, $op $(where T: $($ScalarBounds),*)*;
70            ($R1, $C1),($R2, $C2)
71            const $($D),*;
72            for $($DimsDecl),*;
73            where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
74            $lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result;
75            $action_ref_val; 'a);
76
77        md_impl!(
78            $Op, $op $(where T: $($ScalarBounds),*)*;
79            ($R1, $C1),($R2, $C2)
80            const $($D),*;
81            for $($DimsDecl),*;
82            where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
83            $lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result;
84            $action_val_ref; 'b);
85
86        md_impl!(
87            $Op, $op $(where T: $($ScalarBounds),*)*;
88            ($R1, $C1),($R2, $C2)
89            const $($D),*;
90            for $($DimsDecl),*;
91            where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
92            $lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result;
93            $action_ref_ref; 'a, 'b);
94    }
95);
96
97/// Macro for the implementation of assignment-multiplication and assignment-division.
98macro_rules! md_assign_impl(
99    (
100     // Operator, operator method, and scalar bounds.
101     $Op: ident, $op: ident $(where T: $($ScalarBounds: ident),*)* $(for T::Element: $($ElementBounds: ident),*)*;
102     // Storage dimensions, and dimension bounds.
103     ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
104     // Const type declaration
105     const $($D: ident),*;
106     // Other generic type declarations.
107     for $($DimsDecl: ident),*;
108     // Where clause.
109     where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
110     // Argument identifiers and types.
111     $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
112     // Actual implementation and lifetimes.
113     $action: expr; $($lives: tt),*) => {
114        impl<$($lives ,)* T $(, $DimsDecl)* $(, const $D: usize)*> $Op<$Rhs> for $Lhs
115            where T: Scalar + Zero + One + ClosedAdd + ClosedMul $($(+ $ScalarBounds)*)*,
116                  $($(T::Element: $ElementBounds,)*)*
117                  $( $ConstraintType: $ConstraintBound $(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),*
118        {
119            #[inline]
120            fn $op(&mut $lhs, $rhs: $Rhs) {
121                $action
122            }
123        }
124    }
125);
126
127/// Macro for the implementation of assignment-multiplication and assignment-division with and
128/// without reference to the right-hand-side.
129macro_rules! md_assign_impl_all(
130    (
131     // Operator, operator method, and scalar bounds.
132     $Op: ident, $op: ident $(where T: $($ScalarBounds: ident),*)* $(for T::Element: $($ElementBounds: ident),*)*;
133     // Storage dimensions, and dimension bounds.
134     ($R1: ty, $C1: ty),($R2: ty, $C2: ty)
135     // Const type declaration
136     const $($D: ident),*;
137     // Other generic type declarations.
138     for $($DimsDecl: ident),*;
139     // Where clause.
140     where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
141     // Argument identifiers and types.
142     $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
143     // Actual implementation and lifetimes.
144     [val] => $action_val: expr;
145     [ref] => $action_ref: expr;) => {
146        md_assign_impl!(
147            $Op, $op $(where T: $($ScalarBounds),*)* $(for T::Element: $($ElementBounds),*)*;
148            ($R1, $C1),($R2, $C2)
149            const $($D),*;
150            for $($DimsDecl),*;
151            where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
152            $lhs: $Lhs, $rhs: $Rhs;
153            $action_val; );
154
155        md_assign_impl!(
156            $Op, $op $(where T: $($ScalarBounds),*)* $(for T::Element: $($ElementBounds),*)*;
157            ($R1, $C1),($R2, $C2)
158            const $($D),*;
159            for $($DimsDecl),*;
160            where $($ConstraintType: $ConstraintBound$(<$($ConstraintBoundParams $( = $EqBound )*),*>)*),*;
161            $lhs: $Lhs, $rhs: &'b $Rhs;
162            $action_ref; 'b);
163    }
164);
165
166// TODO: merge with `as_impl`.
167/// Macro for the implementation of addition and subtraction.
168macro_rules! add_sub_impl(
169    ($Op: ident, $op: ident, $bound: ident;
170     ($R1: ty, $C1: ty),($R2: ty, $C2: ty) $(-> ($RRes: ty, $CRes: ty))*
171     // Const type declaration
172     const $($D: ident),*;
173     // Other generic type declarations.
174     for $($DimsDecl: ident),*;
175     // Where clause.
176     where $($ConstraintType: ty: $ConstraintBound: ident$(<$($ConstraintBoundParams: ty $( = $EqBound: ty )*),*>)*),*;
177     $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
178     $action: expr; $($lives: tt),*) => {
179        impl<$($lives ,)* T $(, $DimsDecl)* $(, const $D: usize)*> $Op<$Rhs> for $Lhs
180            where T: Scalar + $bound,
181                  ShapeConstraint: SameNumberOfRows<$R1, $R2 $(, Representative = $RRes)*> +
182                                   SameNumberOfColumns<$C1, $C2 $(, Representative = $CRes)*>,
183                  $( $ConstraintType: $ConstraintBound$(<$( $ConstraintBoundParams $( = $EqBound )*),*>)* ),* {
184            type Output = $Result;
185
186            #[inline]
187            fn $op($lhs, $rhs: $Rhs) -> Self::Output {
188                $action
189            }
190        }
191    }
192);
193
194// TODO: merge with `md_assign_impl`.
195/// Macro for the implementation of assignment-addition and assignment-subtraction.
196macro_rules! add_sub_assign_impl(
197    ($Op: ident, $op: ident, $bound: ident;
198    $(const $D: ident),*;
199     $lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty;
200     $action: expr; $($lives: tt),*) => {
201        impl<$($lives ,)* T $(, const $D: usize),*> $Op<$Rhs> for $Lhs
202            where T: Scalar + $bound {
203            #[inline]
204            fn $op(&mut $lhs, $rhs: $Rhs) {
205                $action
206            }
207        }
208    }
209);