1macro_rules! __impl_assign {
5 ($sym:tt $op:ident $fn:ident $target:ty : $($(#[$attr:meta])* $t:ty),+) => {$(
6 #[allow(unused_qualifications)]
7 $(#[$attr])*
8 impl core::ops::$op<$t> for $target {
9 #[inline]
10 fn $fn(&mut self, rhs: $t) {
11 *self = *self $sym rhs;
12 }
13 }
14 )+};
15}
16
17macro_rules! impl_add_assign {
19 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
20 $crate::internal_macros::__impl_assign!(
21 + AddAssign add_assign $target : $($(#[$attr])* $t),+
22 );
23 };
24}
25
26macro_rules! impl_sub_assign {
28 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
29 $crate::internal_macros::__impl_assign!(
30 - SubAssign sub_assign $target : $($(#[$attr])* $t),+
31 );
32 };
33}
34
35macro_rules! impl_mul_assign {
37 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
38 $crate::internal_macros::__impl_assign!(
39 * MulAssign mul_assign $target : $($(#[$attr])* $t),+
40 );
41 };
42}
43
44macro_rules! impl_div_assign {
46 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
47 $crate::internal_macros::__impl_assign!(
48 / DivAssign div_assign $target : $($(#[$attr])* $t),+
49 );
50 };
51}
52
53macro_rules! div_floor {
55 ($self:expr, $rhs:expr) => {
56 match ($self, $rhs) {
57 (this, rhs) => {
58 let d = this / rhs;
59 let r = this % rhs;
60
61 let correction = (this ^ rhs) >> ($crate::size_of_val(&this) * 8 - 1);
68 if r != 0 {
69 d + correction
70 } else {
71 d
72 }
73 }
74 }
75 };
76}
77
78macro_rules! carry {
81 (@most_once $value:expr, $min:literal.. $max:expr) => {
82 match ($value, $min, $max) {
83 (value, min, max) => {
84 if crate::hint::likely(value >= min) {
85 if crate::hint::likely(value < max) {
86 (value, 0)
87 } else {
88 (value - (max - min), 1)
89 }
90 } else {
91 (value + (max - min), -1)
92 }
93 }
94 }
95 };
96 (@most_twice $value:expr, $min:literal.. $max:expr) => {
97 match ($value, $min, $max) {
98 (value, min, max) => {
99 if crate::hint::likely(value >= min) {
100 if crate::hint::likely(value < max) {
101 (value, 0)
102 } else if value < 2 * max - min {
103 (value - (max - min), 1)
104 } else {
105 (value - 2 * (max - min), 2)
106 }
107 } else {
108 if value >= min - max {
109 (value + (max - min), -1)
110 } else {
111 (value + 2 * (max - min), -2)
112 }
113 }
114 }
115 }
116 };
117 (@most_thrice $value:expr, $min:literal.. $max:expr) => {
118 match ($value, $min, $max) {
119 (value, min, max) => {
120 if crate::hint::likely(value >= min) {
121 if crate::hint::likely(value < max) {
122 (value, 0)
123 } else if value < 2 * max - min {
124 (value - (max - min), 1)
125 } else if value < 3 * max - 2 * min {
126 (value - 2 * (max - min), 2)
127 } else {
128 (value - 3 * (max - min), 3)
129 }
130 } else {
131 if value >= min - max {
132 (value + (max - min), -1)
133 } else if value >= 2 * (min - max) {
134 (value + 2 * (max - min), -2)
135 } else {
136 (value + 3 * (max - min), -3)
137 }
138 }
139 }
140 }
141 };
142}
143
144macro_rules! cascade {
146 (@ordinal ordinal) => {};
147 (@year year) => {};
148
149 ($from:ident in $min:literal.. $max:expr => $to:tt) => {
151 #[allow(unused_comparisons, unused_assignments)]
152 let min = $min;
153 let max = $max;
154 if crate::hint::unlikely($from >= max) {
155 $from -= max - min;
156 $to += 1;
157 } else if crate::hint::unlikely($from < min) {
158 $from += max - min;
159 $to -= 1;
160 }
161 };
162
163 ($ordinal:ident => $year:ident) => {
165 cascade!(@ordinal $ordinal);
167 cascade!(@year $year);
168
169 let days_in_year = crate::util::days_in_year($year) as i16;
170 #[allow(unused_assignments)]
171 if crate::hint::unlikely($ordinal > days_in_year) {
172 $ordinal -= days_in_year;
173 $year += 1;
174 } else if crate::hint::unlikely($ordinal < 1) {
175 $year -= 1;
176 $ordinal += crate::util::days_in_year($year) as i16;
177 }
178 };
179}
180
181macro_rules! ensure_ranged {
183 ($type:ty : $value:ident) => {
184 match <$type>::new($value) {
185 Some(val) => val,
186 None => {
187 $crate::hint::cold_path();
188 #[allow(trivial_numeric_casts)]
189 return Err(crate::error::ComponentRange {
190 name: stringify!($value),
191 minimum: <$type>::MIN.get() as i64,
192 maximum: <$type>::MAX.get() as i64,
193 value: $value as i64,
194 conditional_message: None,
195 });
196 }
197 }
198 };
199
200 ($type:ty : $value:ident $(as $as_type:ident)? * $factor:expr) => {
201 match ($value $(as $as_type)?).checked_mul($factor) {
202 Some(val) => match <$type>::new(val) {
203 Some(val) => val,
204 None => {
205 $crate::hint::cold_path();
206 #[allow(trivial_numeric_casts)]
207 return Err(crate::error::ComponentRange {
208 name: stringify!($value),
209 minimum: <$type>::MIN.get() as i64 / $factor as i64,
210 maximum: <$type>::MAX.get() as i64 / $factor as i64,
211 value: $value as i64,
212 conditional_message: None,
213 });
214 }
215 },
216 None => {
217 $crate::hint::cold_path();
218 return Err(crate::error::ComponentRange {
219 name: stringify!($value),
220 minimum: <$type>::MIN.get() as i64 / $factor as i64,
221 maximum: <$type>::MAX.get() as i64 / $factor as i64,
222 value: $value as i64,
223 conditional_message: None,
224 });
225 }
226 }
227 };
228}
229
230macro_rules! const_try {
235 ($e:expr) => {
236 match $e {
237 Ok(value) => value,
238 Err(error) => return Err(error),
239 }
240 };
241}
242
243macro_rules! const_try_opt {
247 ($e:expr) => {
248 match $e {
249 Some(value) => value,
250 None => return None,
251 }
252 };
253}
254
255macro_rules! expect_opt {
259 ($e:expr, $message:literal) => {
260 match $e {
261 Some(value) => value,
262 None => crate::expect_failed($message),
263 }
264 };
265}
266
267#[cfg(any(feature = "formatting", feature = "parsing"))]
269macro_rules! bug {
270 () => { compile_error!("provide an error message to help fix a possible bug") };
271 ($descr:literal $($rest:tt)?) => {
272 panic!(concat!("internal error: ", $descr) $($rest)?)
273 }
274}
275
276#[cfg(any(feature = "formatting", feature = "parsing"))]
277pub(crate) use bug;
278pub(crate) use {
279 __impl_assign, carry, cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt,
280 impl_add_assign, impl_div_assign, impl_mul_assign, impl_sub_assign,
281};