From 8fe5e5f62bdb9660999449a4b5eaebcc37d7f842 Mon Sep 17 00:00:00 2001 From: Eliot Courtney Date: Mon, 10 Aug 2026 22:55:25 +0900 Subject: [PATCH] rust: num: add Bounded::shr_exact Add `shr_exact` in the vein of `try_shrink` which shifts a bounded right only if it loses no set bits. This is useful for getting a shifted down integer while simultaneously checking that it's aligned. Signed-off-by: Eliot Courtney Acked-by: Alexandre Courbot Reviewed-by: Danilo Krummrich Link: https://patch.msgid.link/20260810-pramin-split-v2-3-65a00b3c7309@nvidia.com Signed-off-by: Miguel Ojeda --- rust/kernel/num/bounded.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs index 90483d2c5374..d192610a687d 100644 --- a/rust/kernel/num/bounded.rs +++ b/rust/kernel/num/bounded.rs @@ -493,6 +493,37 @@ pub fn shr(self) -> Bounded { unsafe { Bounded::__new(self.0 >> SHIFT) } } + /// Right-shifts `self` by `SHIFT` if that loses no set bits, and returns the result as a + /// `Bounded<_, RES>`, where `RES >= N - SHIFT`. + /// + /// Returns [`None`] if any of the `SHIFT` least significant bits of `self` is set. + /// + /// # Examples + /// + /// ``` + /// use kernel::num::Bounded; + /// + /// let v = Bounded::::new::<0xff00>(); + /// let v_shifted: Option> = v.shr_exact::<8, _>(); + /// + /// assert_eq!(v_shifted.map(|v| v.get()), Some(0xff)); + /// + /// // A set bit would be shifted out. + /// let v = Bounded::::new::<0xff01>(); + /// let v_shifted: Option> = v.shr_exact::<8, _>(); + /// + /// assert!(v_shifted.is_none()); + /// ``` + #[inline] + pub fn shr_exact(self) -> Option> { + let shifted = self.shr::(); + if shifted.get() << SHIFT == self.0 { + Some(shifted) + } else { + None + } + } + /// Left-shifts `self` by `SHIFT` and returns the result as a `Bounded<_, RES>`, where `RES >= /// N + SHIFT`. ///