1use crate::builder::common::default_aligned_alignment;
3use crate::layout::Annotation;
4use crate::result::{err, ErrorType, Result};
5use crate::target::Target;
6
7pub const BITS_PER_BYTE: u64 = 8;
9
10pub(crate) trait MinAssign<T> {
11 fn assign_min(&mut self, other: T);
12}
13
14impl MinAssign<u64> for u64 {
15 fn assign_min(&mut self, other: u64) {
16 *self = (*self).min(other);
17 }
18}
19
20impl MinAssign<Option<u64>> for u64 {
21 fn assign_min(&mut self, other: Option<u64>) {
22 *self = (*self).min2(other)
23 }
24}
25
26pub(crate) trait MaxAssign<T> {
27 fn assign_max(&mut self, other: T);
28}
29
30impl MaxAssign<Option<u64>> for Option<u64> {
31 fn assign_max(&mut self, other: Option<u64>) {
32 *self = (*self).max2(other);
33 }
34}
35
36impl MaxAssign<u64> for Option<u64> {
37 fn assign_max(&mut self, other: u64) {
38 *self = Some((*self).max2(other));
39 }
40}
41
42impl MaxAssign<Option<u64>> for u64 {
43 fn assign_max(&mut self, other: Option<u64>) {
44 *self = (*self).max2(other);
45 }
46}
47
48impl MaxAssign<u64> for u64 {
49 fn assign_max(&mut self, other: u64) {
50 *self = (*self).max(other);
51 }
52}
53
54pub(crate) trait MinExt<T> {
55 type Output;
56
57 fn min2(self, other: T) -> Self::Output;
58}
59
60impl MinExt<Option<u64>> for Option<u64> {
61 type Output = Option<u64>;
62
63 fn min2(self, other: Option<u64>) -> Option<u64> {
64 match (self, other) {
65 (Some(a), Some(b)) => Some(a.min(b)),
66 (None, _) => other,
67 _ => self,
68 }
69 }
70}
71
72impl MinExt<Option<u64>> for u64 {
73 type Output = u64;
74
75 fn min2(self, other: Option<u64>) -> u64 {
76 match other {
77 Some(b) => self.min(b),
78 _ => self,
79 }
80 }
81}
82
83impl MinExt<u64> for Option<u64> {
84 type Output = u64;
85
86 fn min2(self, other: u64) -> u64 {
87 match self {
88 Some(b) => other.min(b),
89 _ => other,
90 }
91 }
92}
93
94pub(crate) trait MaxExt<T> {
95 type Output;
96
97 fn max2(self, other: T) -> Self::Output;
98}
99
100impl MaxExt<Option<u64>> for Option<u64> {
101 type Output = Option<u64>;
102
103 fn max2(self, other: Option<u64>) -> Option<u64> {
104 match (self, other) {
105 (Some(a), Some(b)) => Some(a.max(b)),
106 (None, _) => other,
107 _ => self,
108 }
109 }
110}
111
112impl MaxExt<Option<u64>> for u64 {
113 type Output = u64;
114
115 fn max2(self, other: Option<u64>) -> u64 {
116 match other {
117 Some(b) => self.max(b),
118 _ => self,
119 }
120 }
121}
122
123impl MaxExt<u64> for Option<u64> {
124 type Output = u64;
125
126 fn max2(self, other: u64) -> u64 {
127 match self {
128 Some(b) => other.max(b),
129 _ => other,
130 }
131 }
132}
133
134pub(crate) fn align_to(n: u64, m: u64) -> Result<u64> {
135 assert!(m.is_power_of_two());
136 let mask = m - 1;
137 match n.checked_add(mask) {
138 Some(n) => Ok(n & !mask),
139 _ => Err(err(ErrorType::SizeOverflow)),
140 }
141}
142
143pub(crate) fn is_attr_packed(a: &[Annotation]) -> bool {
144 a.iter().any(|a| matches!(a, Annotation::AttrPacked))
145}
146
147pub(crate) fn annotation_alignment(target: Target, annotations: &[Annotation]) -> Option<u64> {
148 let mut max = None;
149 for a in annotations {
150 if let Annotation::Align(n) = a {
151 max.assign_max(n.unwrap_or_else(|| default_aligned_alignment(target)));
152 }
153 }
154 max
155}
156
157pub(crate) fn pragma_pack_value(a: &[Annotation]) -> Option<u64> {
158 for a in a {
159 if let Annotation::PragmaPack(n) = a {
160 return Some(*n);
161 }
162 }
163 None
164}
165
166pub(crate) fn size_mul(a: u64, b: u64) -> Result<u64> {
167 match a.checked_mul(b) {
168 Some(v) => Ok(v),
169 None => Err(err(ErrorType::SizeOverflow)),
170 }
171}
172
173pub(crate) fn size_add(a: u64, b: u64) -> Result<u64> {
174 match a.checked_add(b) {
175 Some(v) => Ok(v),
176 None => Err(err(ErrorType::SizeOverflow)),
177 }
178}