osom_lib_primitives/power_of_two/
power_of_two_32.rs1use core::convert::Infallible;
2
3use osom_lib_reprc::macros::reprc;
4use osom_lib_try_clone::TryClone;
5
6use super::PowerOfTwoError;
7
8#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
10#[reprc]
11#[repr(transparent)]
12#[must_use]
13pub struct PowerOfTwo32 {
14 value: u32,
15}
16
17impl PowerOfTwo32 {
18 pub const ZERO: Self = unsafe { Self::new_unchecked(0) };
20
21 #[inline(always)]
28 pub const unsafe fn new_unchecked(value: u32) -> Self {
29 Self { value }
30 }
31
32 #[inline(always)]
38 pub const fn new(value: u32) -> Result<Self, PowerOfTwoError> {
39 if value == 0 || value.is_power_of_two() {
40 Ok(unsafe { Self::new_unchecked(value) })
41 } else {
42 Err(PowerOfTwoError::NotAPowerOfTwo)
43 }
44 }
45
46 #[inline(always)]
53 pub fn next(self) -> Self {
54 debug_assert!(self.value < (u32::MAX >> 1));
55 let result = core::hint::select_unpredictable(self.value == 0, 1, self.value << 1);
56 Self { value: result }
57 }
58
59 #[inline(always)]
61 #[must_use]
62 pub const fn value(self) -> u32 {
63 self.value
64 }
65
66 #[inline(always)]
72 #[must_use]
73 pub const fn as_usize(self) -> usize {
74 #[allow(clippy::cast_possible_truncation)]
75 {
76 assert!(size_of::<usize>() >= size_of::<u32>(), "usize is smaller than u32");
77 self.value as usize
78 }
79 }
80}
81
82impl core::fmt::Display for PowerOfTwo32 {
83 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
84 self.value.fmt(f)
85 }
86}
87
88impl TryClone for PowerOfTwo32 {
89 type Error = Infallible;
90 fn try_clone(&self) -> Result<Self, Self::Error> {
91 Ok(*self)
92 }
93}