1macro_rules! div_floor {
5 ($self:expr, $rhs:expr) => {
6 match ($self, $rhs) {
7 (this, rhs) => {
8 let d = this / rhs;
9 let r = this % rhs;
10
11 let correction = (this ^ rhs) >> (size_of_val(&this) * 8 - 1);
18 if r != 0 { d + correction } else { d }
19 }
20 }
21 };
22}
23
24macro_rules! carry {
27 (@most_once $value:expr, $min:literal.. $max:expr) => {
28 match ($value, $min, $max) {
29 (value, min, max) => {
30 if crate::hint::likely(value >= min) {
31 if crate::hint::likely(value < max) {
32 (value, 0)
33 } else {
34 (value - (max - min), 1)
35 }
36 } else {
37 (value + (max - min), -1)
38 }
39 }
40 }
41 };
42 (@most_twice $value:expr, $min:literal.. $max:expr) => {
43 match ($value, $min, $max) {
44 (value, min, max) => {
45 if crate::hint::likely(value >= min) {
46 if crate::hint::likely(value < max) {
47 (value, 0)
48 } else if value < 2 * max - min {
49 (value - (max - min), 1)
50 } else {
51 (value - 2 * (max - min), 2)
52 }
53 } else {
54 if value >= min - max {
55 (value + (max - min), -1)
56 } else {
57 (value + 2 * (max - min), -2)
58 }
59 }
60 }
61 }
62 };
63 (@most_thrice $value:expr, $min:literal.. $max:expr) => {
64 match ($value, $min, $max) {
65 (value, min, max) => {
66 if crate::hint::likely(value >= min) {
67 if crate::hint::likely(value < max) {
68 (value, 0)
69 } else if value < 2 * max - min {
70 (value - (max - min), 1)
71 } else if value < 3 * max - 2 * min {
72 (value - 2 * (max - min), 2)
73 } else {
74 (value - 3 * (max - min), 3)
75 }
76 } else {
77 if value >= min - max {
78 (value + (max - min), -1)
79 } else if value >= 2 * (min - max) {
80 (value + 2 * (max - min), -2)
81 } else {
82 (value + 3 * (max - min), -3)
83 }
84 }
85 }
86 }
87 };
88}
89
90macro_rules! cascade {
92 (@ordinal ordinal) => {};
93 (@year year) => {};
94
95 ($from:ident in $min:literal.. $max:expr => $to:tt) => {
97 #[allow(unused_comparisons, unused_assignments)]
98 let min = $min;
99 let max = $max;
100 if crate::hint::unlikely($from >= max) {
101 $from -= max - min;
102 $to += 1;
103 } else if crate::hint::unlikely($from < min) {
104 $from += max - min;
105 $to -= 1;
106 }
107 };
108
109 ($ordinal:ident => $year:ident) => {
111 cascade!(@ordinal $ordinal);
113 cascade!(@year $year);
114
115 let days_in_year = crate::util::range_validated::days_in_year($year).cast_signed();
116 #[allow(unused_assignments)]
117 if crate::hint::unlikely($ordinal > days_in_year) {
118 $ordinal -= days_in_year;
119 $year += 1;
120 } else if crate::hint::unlikely($ordinal < 1) {
121 $year -= 1;
122 $ordinal += crate::util::days_in_year($year).cast_signed();
126 }
127 };
128}
129
130macro_rules! ensure_ranged {
132 ($type:ty : $value:ident) => {
133 match <$type>::new($value) {
134 Some(val) => val,
135 None => {
136 $crate::hint::cold_path();
137 return Err(crate::error::ComponentRange::unconditional(stringify!($value)));
138 }
139 }
140 };
141
142 ($type:ty : $value:ident ($name:literal)) => {
143 match <$type>::new($value) {
144 Some(val) => val,
145 None => {
146 $crate::hint::cold_path();
147 return Err(crate::error::ComponentRange::unconditional($name));
148 }
149 }
150 };
151
152 ($type:ty : $value:ident $(as $as_type:ident)? * $factor:expr) => {
153 match ($value $(as $as_type)?).checked_mul($factor) {
154 Some(val) => match <$type>::new(val) {
155 Some(val) => val,
156 None => {
157 $crate::hint::cold_path();
158 return Err(crate::error::ComponentRange::unconditional(stringify!($value)));
159 }
160 },
161 None => {
162 $crate::hint::cold_path();
163 return Err(crate::error::ComponentRange::unconditional(stringify!($value)));
164 }
165 }
166 };
167}
168
169macro_rules! const_try {
174 ($e:expr) => {
175 match $e {
176 Ok(value) => value,
177 Err(error) => {
178 $crate::hint::cold_path();
179 return Err(error);
180 }
181 }
182 };
183}
184
185#[cfg(any(feature = "formatting", feature = "parsing", feature = "serde"))]
189macro_rules! try_likely_ok {
190 ($e:expr) => {
191 match $e {
192 Ok(value) => value,
193 Err(error) => {
194 $crate::hint::cold_path();
195 return Err(error.into());
196 }
197 }
198 };
199}
200
201macro_rules! const_try_opt {
205 ($e:expr) => {
206 match $e {
207 Some(value) => value,
208 None => {
209 $crate::hint::cold_path();
210 return None;
211 }
212 }
213 };
214}
215
216macro_rules! bug {
218 () => {
219 compile_error!("provide an error message to help fix a possible bug")
220 };
221 ($descr:literal) => {{
222 $crate::hint::cold_path();
223 panic!(concat!("internal error: ", $descr))
224 }};
225}
226
227pub(crate) use bug;
228pub(crate) use carry;
229pub(crate) use cascade;
230pub(crate) use const_try;
231pub(crate) use const_try_opt;
232pub(crate) use div_floor;
233pub(crate) use ensure_ranged;
234#[cfg(any(feature = "formatting", feature = "parsing", feature = "serde"))]
235pub(crate) use try_likely_ok;