1use core::fmt;
2#[cfg(all(target_pointer_width = "64", target_has_atomic_load_store = "128"))]
3use core::sync::atomic::AtomicU128;
4#[cfg(all(target_pointer_width = "32", target_has_atomic_load_store = "64"))]
5use core::sync::atomic::AtomicU64;
6#[cfg(any(
7 all(target_pointer_width = "64", target_has_atomic_load_store = "128"),
8 all(target_pointer_width = "32", target_has_atomic_load_store = "64"),
9))]
10use core::sync::atomic::Ordering;
11
12#[cfg(target_pointer_width = "64")]
13type UfatInner = u128;
14#[cfg(target_pointer_width = "32")]
15type UfatInner = u64;
16
17#[cfg(all(target_pointer_width = "64", target_has_atomic_load_store = "128"))]
18type AtomicUfatInner = AtomicU128;
19#[cfg(all(target_pointer_width = "32", target_has_atomic_load_store = "64"))]
20type AtomicUfatInner = AtomicU64;
21
22#[expect(non_camel_case_types, reason = "effective primitive type")]
23#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
24#[repr(transparent)]
25pub struct ufat(UfatInner);
26
27#[cfg(any(
28 all(target_pointer_width = "64", target_has_atomic_load_store = "128"),
29 all(target_pointer_width = "32", target_has_atomic_load_store = "64"),
30))]
31#[derive(Debug)]
32#[repr(transparent)]
33pub struct AtomicUfat(AtomicUfatInner);
34
35impl ufat {
36 pub const MIN: Self = Self(UfatInner::MIN);
37 pub const MAX: Self = Self(UfatInner::MAX);
38 pub const BITS: u32 = UfatInner::BITS;
39
40 pub const fn new(upper: usize, lower: usize) -> Self {
41 let upper = upper as UfatInner;
42 let lower = lower as UfatInner;
43 Self((upper << usize::BITS) | lower)
44 }
45
46 pub const fn upper(self) -> usize {
47 (self.0 >> usize::BITS) as usize
48 }
49
50 pub const fn lower(self) -> usize {
51 self.0 as usize
52 }
53
54 pub const fn truncate<T: const private::TruncateTarget<Self>>(self) -> T {
55 T::truncate_from(self)
56 }
57}
58
59impl fmt::Binary for ufat {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 <UfatInner as fmt::Binary>::fmt(&self.0, f)
62 }
63}
64
65impl fmt::Display for ufat {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 <UfatInner as fmt::Display>::fmt(&self.0, f)
68 }
69}
70
71impl fmt::LowerExp for ufat {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 <UfatInner as fmt::LowerExp>::fmt(&self.0, f)
74 }
75}
76
77impl fmt::LowerHex for ufat {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 <UfatInner as fmt::LowerHex>::fmt(&self.0, f)
80 }
81}
82
83impl fmt::Octal for ufat {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 <UfatInner as fmt::Octal>::fmt(&self.0, f)
86 }
87}
88
89impl fmt::UpperExp for ufat {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 <UfatInner as fmt::UpperExp>::fmt(&self.0, f)
92 }
93}
94
95impl fmt::UpperHex for ufat {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 <UfatInner as fmt::UpperHex>::fmt(&self.0, f)
98 }
99}
100
101#[cfg(any(
102 all(target_pointer_width = "64", target_has_atomic_load_store = "128"),
103 all(target_pointer_width = "32", target_has_atomic_load_store = "64"),
104))]
105impl AtomicUfat {
106 pub const fn new(v: ufat) -> Self { Self(AtomicUfatInner::new(v.0)) }
107 pub fn load(&self, ordering: Ordering) -> ufat { ufat(self.0.load(ordering)) }
108 pub fn store(&self, val: ufat, ordering: Ordering) { self.0.store(val.0, ordering); }
109 pub fn swap(&self, val: ufat, order: Ordering) -> ufat { ufat(self.0.swap(val.0, order)) }
110 pub fn compare_exchange(&self, current: ufat, new: ufat, success: Ordering, failure: Ordering) -> Result<ufat, ufat> {
111 self.0.compare_exchange(current.0, new.0, success, failure)
112 .map(ufat)
113 .map_err(ufat)
114 }
115 pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering, mut f: F) -> Result<ufat, ufat>
116 where
117 F: FnMut(ufat) -> Option<ufat>
118 {
119 self.0.fetch_update(set_order, fetch_order, |val| f(ufat(val)).map(|val| val.0))
120 .map(ufat)
121 .map_err(ufat)
122 }
123}
124
125mod private {
126 pub const trait TruncateTarget<T> {
127 fn truncate_from(val: T) -> Self;
128 }
129}
130
131const impl private::TruncateTarget<ufat> for usize {
132 fn truncate_from(val: ufat) -> Self { val.lower() }
133}
134
135const impl private::TruncateTarget<ufat> for u8 {
136 fn truncate_from(val: ufat) -> Self { val.0.truncate() }
137}
138
139const impl private::TruncateTarget<ufat> for u16 {
140 fn truncate_from(val: ufat) -> Self { val.0.truncate() }
141}
142
143const impl private::TruncateTarget<ufat> for u32 {
144 fn truncate_from(val: ufat) -> Self { val.0.truncate() }
145}