macro_rules! assert_equal_len {
($a:ident,$b:ident,$func:ident,$op:tt) => {
assert!(
$a.len() == $b.len(),
"{:?}: dimension mismatch: {:?} {:?} {:?}",
stringify!($func),
$a.len(),
stringify!($op),
$b.len()
)
};
}
macro_rules! op {
($func:ident,$bound:ident,$op:tt,$method:ident) => {
fn $func<T: $bound<T, Output = T> + Copy>(xs: &mut Vec<T>, ys: &Vec<T>) {
assert_equal_len!(xs, ys, $func, $op);
for (x, y) in xs.iter_mut().zip(ys.iter()) {
*x = $bound::$method(*x, *y);
}
}
};
}
op!(add_assign,Add,+=,add);
op!(mul_assign,Mul,*=,mul);
op!(sub_assign,Sub,-=,sub);
op!(div_assign,Div,-=,div);
mod test {
use std::iter;
macro_rules! test {
($func:ident,$x:expr,$y:expr,$z:expr) => {
#[test]
fn $func() {
for size in 0usize..10 {
let mut x: Vec<_> = iter::repeat($x).take(size).collect();
let y: Vec<_> = iter::repeat($y).take(size).collect();
let z: Vec<_> = iter::repeat($z).take(size).collect();
super::$func(&mut x, &y);
assert_eq!(x, z);
}
}
};
}
test!(add_assign, 1u32, 2u32, 3u32);
test!(mul_assign, 2u32, 3u32, 6u32);
test!(sub_assign, 3u32, 2u32, 1u32);
test!(div_assign, 10, 2, 5);
}
1
共 3 条评论, 1 页
评论区
写评论这段代码没什么技巧,用的都是基础的声明宏知识。
把 小宏书 理解到 2.3.2 节就能看懂这段代码。
宏处理标记的流程:捕获 → 匹配 → 展开。
cargo expand
好命令
通过cargo expand展开宏,可以得到生成的代码: