macro_rules! gen_ops_comm {
($(<$($($lt:lifetime),+)? $(,)? $($($gen:ident),+)? $(| $(const $C:ident : $Ct:ty),+)?>;)? types $($rest:tt)+) => { ... };
(@step1 ($($gen:tt)*); types $lhs:ty, $($rest:tt)+) => { ... };
(@step1 ($($gen:tt)*); types &$lhs:ty, $($rest:tt)+) => { ... };
(@step1 ($($gen:tt)*); types &mut $lhs:ty, $($rest:tt)+) => { ... };
(@step2 ($($gen:tt)*); types $lref:ident: $lhs:ty, $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
(@step2 ($($gen:tt)*); types $lref:ident: $lhs:ty, &$rhs:ty => $out:ty; $($rest:tt)+) => { ... };
(@step2 ($($gen:tt)*); types $lref:ident: $lhs:ty, &mut $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
}
Expand description
Implements commutative operations.
§Example
#[derive(Debug, Copy, Clone, PartialEq)]
struct Pair<T>(pub T, pub T);
gen_ops_comm!(
<T>;
types Pair<T>, i32 => Pair<T>;
for * call |a: &Pair<T>, b:&i32| Pair(a.0 * *b, a.1 * *b);
(where T: Mul<i32, Output=T>)
for & call |a: &Pair<T>, b:&i32| Pair(a.0 & *b, a.1 & *b);
(where T: BitAnd<i32, Output=T>)
where T: Copy
);
let a = Pair(12, 3);
println!("a * 5 = {:?}", a * 5); //a * 5 = Pair(60, 15)
println!("5 * a = {:?}", 5 * a); //5 * a = Pair(60, 15)
println!("a & 2 = {:?}", a & 2); //a & 2 = Pair(0, 2)
println!("2 & a = {:?}", 2 & a); //2 & a = Pair(0, 2)
§Note
The only type signature supported for gen_ops_comm!
is types Lhs, Rhs => Out;
It implements both types Lhs, Rhs => Out;
and types Rhs, Lhs => Out;
.
Lhs
and Rhs
can be borrowed types except for assignment operators where Lhs
cannot be
immutably borrowed.
Also make sure that Lhs
and Rhs
are of different types.
Callable expressions must take immutable borrowed types as arguments
and return the result of the Out
type