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::range_validated::days_in_year($year).cast_signed();
123 }
124 };
125}
126
127macro_rules! ensure_ranged {
129 ($type:ty : $value:ident) => {
130 match <$type>::new($value) {
131 Some(val) => val,
132 None => {
133 $crate::hint::cold_path();
134 return Err(crate::error::ComponentRange::unconditional(stringify!($value)));
135 }
136 }
137 };
138
139 ($type:ty : $value:ident ($name:literal)) => {
140 match <$type>::new($value) {
141 Some(val) => val,
142 None => {
143 $crate::hint::cold_path();
144 return Err(crate::error::ComponentRange::unconditional($name));
145 }
146 }
147 };
148
149 ($type:ty : $value:ident $(as $as_type:ident)? * $factor:expr) => {
150 match ($value $(as $as_type)?).checked_mul($factor) {
151 Some(val) => match <$type>::new(val) {
152 Some(val) => val,
153 None => {
154 $crate::hint::cold_path();
155 return Err(crate::error::ComponentRange::unconditional(stringify!($value)));
156 }
157 },
158 None => {
159 $crate::hint::cold_path();
160 return Err(crate::error::ComponentRange::unconditional(stringify!($value)));
161 }
162 }
163 };
164}
165
166macro_rules! const_try {
171 ($e:expr) => {
172 match $e {
173 Ok(value) => value,
174 Err(error) => {
175 $crate::hint::cold_path();
176 return Err(error);
177 }
178 }
179 };
180}
181
182macro_rules! const_try_opt {
186 ($e:expr) => {
187 match $e {
188 Some(value) => value,
189 None => {
190 $crate::hint::cold_path();
191 return None;
192 }
193 }
194 };
195}
196
197#[cfg(any(feature = "formatting", feature = "parsing"))]
199macro_rules! bug {
200 () => {
201 compile_error!("provide an error message to help fix a possible bug")
202 };
203 ($descr:literal) => {
204 panic!(concat!("internal error: ", $descr))
205 };
206}
207
208#[cfg(any(feature = "formatting", feature = "parsing"))]
209pub(crate) use bug;
210pub(crate) use {carry, cascade, const_try, const_try_opt, div_floor, ensure_ranged};