use std::ops::Add; use std::ops::Div; use std::ops::Rem; use std::ops::Sub; pub fn gcd(mut a: T, mut b: T) -> T where T: Copy + Default + PartialEq, T: Rem, { let mut c = a % b; while c != T::default() { a = b; b = c; c = a % b; } b } pub fn align(val: T, a: T) -> T where T: Add, T: Copy, T: Default, T: PartialEq, T: Rem, T: Sub, { let tmp = val % a; if tmp == T::default() { val } else { val + (a - tmp) } } pub fn div_round_up(a: T, b: T) -> T where T: Copy, T: Add, T: Div, T: Sub, { #[allow(clippy::eq_op)] let one = b / b; (a + b - one) / b } pub struct SetBitIndices { val: T, } impl SetBitIndices { pub fn from_msb(val: T) -> Self { Self { val: val } } } impl Iterator for SetBitIndices { type Item = u32; fn next(&mut self) -> Option { if self.val == 0 { None } else { let pos = u32::BITS - self.val.leading_zeros() - 1; self.val ^= 1 << pos; Some(pos) } } }