1use crate::Limb;
7
8#[cfg_attr(not(feature = "alloc"), allow(dead_code))]
10#[inline(always)]
11pub(crate) const fn from_bytes(nbytes: usize) -> u32 {
12 mul(nbytes, 8)
13}
14
15#[inline(always)]
17pub(crate) const fn from_limbs(nlimbs: usize) -> u32 {
18 mul(nlimbs, Limb::BITS)
19}
20
21#[cfg_attr(not(feature = "alloc"), allow(dead_code))]
24#[inline(always)]
25pub(crate) const fn to_bytes(nbits: u32) -> usize {
26 u32_to_usize(nbits.div_ceil(8))
27}
28
29#[inline(always)]
32pub(crate) const fn to_limbs(nbits: u32) -> usize {
33 u32_to_usize(nbits.div_ceil(Limb::BITS))
34}
35
36#[inline(always)]
37const fn u32_to_usize(n: u32) -> usize {
38 const {
39 assert!(usize::BITS >= u32::BITS, "usize too small");
41 }
42
43 n as usize
44}
45
46#[allow(
47 clippy::cast_possible_truncation,
48 reason = "assertion ensures panic instead of truncation"
49)]
50#[inline(always)]
51const fn usize_to_u32(n: usize) -> u32 {
52 debug_assert!(n < u32_to_usize(u32::MAX), "u32 overflow");
53 n as u32
54}
55
56#[inline(always)]
57const fn mul(size: usize, n: u32) -> u32 {
58 if cfg!(debug_assertions) {
59 usize_to_u32(size).checked_mul(n).expect("u32 overflow")
60 } else {
61 usize_to_u32(size) * n
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 #[test]
68 fn from_bytes() {
69 assert_eq!(super::from_bytes(0), 0);
70 assert_eq!(super::from_bytes(1), 8);
71 assert_eq!(super::from_bytes(2), 16);
72 }
73
74 #[test]
75 fn to_bytes() {
76 assert_eq!(super::to_bytes(0), 0);
77 assert_eq!(super::to_bytes(1), 1);
78 assert_eq!(super::to_bytes(8), 1);
79 assert_eq!(super::to_bytes(9), 2);
80 assert_eq!(super::to_bytes(16), 2);
81 assert_eq!(super::to_bytes(17), 3);
82 }
83}