В настоящее время я работаю над оптимизацией корзины jpeg декодера ржавчины с использованием SIMD. Чтобы избежать длинных повторений в коде, я хотел бы написать макрос, который генерирует следующий код транспонирования матрицы:
s = [
i32x8::new(s[0].extract(0),s[1].extract(0),s[2].extract(0),s[3].extract(0),s[4].extract(0),s[5].extract(0),s[6].extract(0),s[7].extract(0), ),
i32x8::new(s[0].extract(1),s[1].extract(1),s[2].extract(1),s[3].extract(1),s[4].extract(1),s[5].extract(1),s[6].extract(1),s[7].extract(1), ),
i32x8::new(s[0].extract(2),s[1].extract(2),s[2].extract(2),s[3].extract(2),s[4].extract(2),s[5].extract(2),s[6].extract(2),s[7].extract(2), ),
i32x8::new(s[0].extract(3),s[1].extract(3),s[2].extract(3),s[3].extract(3),s[4].extract(3),s[5].extract(3),s[6].extract(3),s[7].extract(3), ),
i32x8::new(s[0].extract(4),s[1].extract(4),s[2].extract(4),s[3].extract(4),s[4].extract(4),s[5].extract(4),s[6].extract(4),s[7].extract(4), ),
i32x8::new(s[0].extract(5),s[1].extract(5),s[2].extract(5),s[3].extract(5),s[4].extract(5),s[5].extract(5),s[6].extract(5),s[7].extract(5), ),
i32x8::new(s[0].extract(6),s[1].extract(6),s[2].extract(6),s[3].extract(6),s[4].extract(6),s[5].extract(6),s[6].extract(6),s[7].extract(6), ),
i32x8::new(s[0].extract(7),s[1].extract(7),s[2].extract(7),s[3].extract(7),s[4].extract(7),s[5].extract(7),s[6].extract(7),s[7].extract(7), ),
];
Макрос должен иметь возможность генерировать код для матрицы разных размеров (4 или 8).
Я пробовал несколько разных подходов, но мне так и не удалось заставить макрос повторить n раз шаблон из n элементов.
Самым логичным для меня было бы:
macro_rules! square {
(($($x:tt),*), ($($y:tt),*)) => {
[
$([
$( s[$x].extract($y) ),*
]),*
]
};
($($x:expr),*) => { square!( ($($x),*) , ($($x),*) ) };
}
, но с ошибкой
error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth