1use crate::stdlib;
4use crate::stdlib::fmt;
5use crate::stdlib::Vec;
6
7#[cfg(not(rustc_1_75))]
8use stdlib::Box;
9
10use num_traits::{Zero, PrimInt};
11
12use super::radix::RadixType;
13
14#[allow(dead_code)]
16pub(crate) trait Endianness: Copy + Clone + Default + fmt::Debug {
17 const NAME: &'static str;
19
20 #[cfg(rustc_1_75)]
22 fn into_iter<'a, D: 'a>(digits: Vec<D>) -> impl LeBigDigitIterator<'a, D>;
23
24 #[cfg(rustc_1_75)]
26 fn iter_slice<D>(digits: &[D]) -> impl LeBigDigitIterator<'_, &D>;
27
28 #[cfg(rustc_1_75)]
30 fn iter_slice_mut<D>(digits: &mut [D]) -> impl LeBigDigitIterator<'_, &mut D>;
31
32 #[cfg(not(rustc_1_75))]
33 fn into_iter<'a, D: 'a>(digits: Vec<D>) -> LittleEndianBigDigitIter<'a, D>;
34
35 #[cfg(not(rustc_1_75))]
36 fn iter_slice<D>(digits: &[D]) -> LittleEndianBigDigitIter<'_, &D>;
37
38 #[cfg(not(rustc_1_75))]
39 fn iter_slice_mut<D>(digits: &mut [D]) -> LittleEndianBigDigitIter<'_, &mut D>;
40
41 #[cfg(rustc_1_75)]
42 fn addassign_carry_into_slice_at<R: RadixType>(
43 digits: &mut [R::Base],
44 carry: &mut R::Base,
45 idx: usize,
46 ) {
47 for dest in Self::iter_slice_mut(digits).skip(idx) {
48 R::addassign_carry(dest, carry);
49 if carry.is_zero() {
50 return;
51 }
52 }
53 }
54
55 #[cfg(not(rustc_1_75))]
56 fn addassign_carry_into_slice_at<R: RadixType>(
57 digits: &mut [R::Base],
58 carry: &mut R::Base,
59 idx: usize,
60 );
61
62 fn push_significant_digit<D>(digits: &mut Vec<D>, d: D);
64
65 fn split_most_significant_digit<D: Zero + PrimInt>(digits: &[D]) -> (D, &[D]);
69
70 fn split_significant_zeros<D: Zero>(digits: &[D]) -> (&[D], &[D]);
72
73 fn split_least_significant<D>(digits: &[D], count: usize) -> (&[D], &[D]);
76
77 fn split_least_significant_mut<D>(digits: &mut [D], count: usize) -> (&mut [D], &mut [D]);
80
81 fn strip_significant_zeros<D: Copy + Zero>(digits: &mut Vec<D>);
84
85 fn count_significant_zeros<D: Zero>(digits: &[D]) -> usize {
87 Self::iter_slice(digits).rev().position(|d| !d.is_zero()).unwrap_or(digits.len())
88 }
89
90 fn remove_insignificant_digits<D: Zero + Copy>(digits: &mut Vec<D>, n: usize);
92
93 fn reorder_le_digits<D: Copy>(digits: &mut [D]);
97
98 fn reorder_be_vec<D: Zero + Copy>(digits: &mut Vec<D>);
102
103 fn rotate_trailing_le_digits_at<D: Copy>(digits: &mut [D], idx: usize);
110
111 fn bigint_to_digits(n: &num_bigint::BigUint) -> Vec<u8>;
113
114 fn biguint_from_digits(n: &[u8]) -> Option<num_bigint::BigUint>;
116}
117
118
119)]
121pub(crate) struct BigEndian {}
122
123)]
125pub(crate) struct LittleEndian {}
126
127impl Endianness for BigEndian {
128 const NAME: &'static str = "BE";
129
130 #[cfg(rustc_1_75)]
131 fn into_iter<'a, D: 'a>(digits: Vec<D>) -> impl LeBigDigitIterator<'a, D> {
132 digits.into_iter().rev()
133 }
134
135 #[cfg(rustc_1_75)]
136 fn iter_slice<D>(digits: &[D]) -> impl LeBigDigitIterator<'_, &D> {
137 digits.iter().rev()
138 }
139
140 #[cfg(rustc_1_75)]
141 fn iter_slice_mut<D>(digits: &mut [D]) -> impl LeBigDigitIterator<'_, &mut D> {
142 digits.iter_mut().rev()
143 }
144
145 #[cfg(not(rustc_1_75))]
146 fn into_iter<'a, D: 'a>(digits: Vec<D>) -> LittleEndianBigDigitIter<'a, D> {
147 LittleEndianBigDigitIter {
148 digits: Box::new(digits.into_iter().rev()),
149 }
150 }
151
152 #[cfg(not(rustc_1_75))]
153 fn iter_slice<D>(digits: &[D]) -> LittleEndianBigDigitIter<'_, &D> {
154 LittleEndianBigDigitIter {
155 digits: Box::new(digits.iter().rev()),
156 }
157 }
158
159 #[cfg(not(rustc_1_75))]
160 fn iter_slice_mut<D>(digits: &mut [D]) -> LittleEndianBigDigitIter<'_, &mut D> {
161 LittleEndianBigDigitIter {
162 digits: Box::new(digits.iter_mut().rev()),
163 }
164 }
165
166 #[cfg(not(rustc_1_75))]
167 fn addassign_carry_into_slice_at<R: RadixType>(
168 digits: &mut [R::Base],
169 carry: &mut R::Base,
170 idx: usize,
171 ) {
172 for dest in digits.iter_mut().rev().skip(idx) {
173 R::addassign_carry(dest, carry);
174 if carry.is_zero() {
175 return;
176 }
177 }
178 }
179
180 fn push_significant_digit<D>(digits: &mut Vec<D>, d: D) {
181 digits.insert(0, d);
182 }
183
184 fn split_least_significant<D>(digits: &[D], count: usize) -> (&[D], &[D]) {
185 let (hi, lo) = digits.split_at(digits.len() - count);
186 (lo, hi)
187 }
188
189 fn split_least_significant_mut<D>(digits: &mut [D], count: usize) -> (&mut [D], &mut [D]) {
190 let (hi, lo) = digits.split_at_mut(digits.len() - count);
191 (lo, hi)
192 }
193
194 fn split_most_significant_digit<D: Copy + Zero>(digits: &[D]) -> (D, &[D]) {
195 digits.split_first().map(|(&d, r)| (d, r)).unwrap_or((Zero::zero(), &[]))
196 }
197
198 fn strip_significant_zeros<D: Copy + Zero>(digits: &mut Vec<D>) {
199 if let Some(idx) = digits.iter().position(|d| !d.is_zero()) {
200 digits.copy_within(idx.., 0);
201 digits.truncate(digits.len() - idx);
202 } else {
203 digits.clear();
204 }
205 }
206
207 fn split_significant_zeros<D: Zero>(digits: &[D]) -> (&[D], &[D]) {
208 if let Some(idx) = digits.iter().position(|d| !d.is_zero()) {
209 let (sig_zeros, digits) = digits.split_at(idx);
210 (digits, sig_zeros)
211 } else {
212 (&[], digits)
213 }
214 }
215
216 fn remove_insignificant_digits<D: Zero + Copy>(digits: &mut Vec<D>, n: usize) {
217 digits.truncate(digits.len() - n);
219 }
220
221 fn reorder_le_digits<D: Copy>(digits: &mut [D]) {
222 digits.reverse()
223 }
224
225 fn reorder_be_vec<D: Zero + Copy>(digits: &mut Vec<D>) {
226 match digits.iter().position(|&d| !d.is_zero()) {
227 Some(0) => {}
228 Some(idx) => {
229 digits.copy_within(idx.., 0);
230 digits.truncate(digits.len() - idx);
231 }
232 None => digits.clear(),
233 }
234 }
235
236 fn rotate_trailing_le_digits_at<D: Copy>(digits: &mut [D], idx: usize) {
237 Self::reorder_le_digits(&mut digits[idx..]);
238 digits.rotate_left(idx);
239 }
240
241 fn bigint_to_digits(n: &num_bigint::BigUint) -> Vec<u8> {
242 n.to_radix_be(10)
243 }
244
245 fn biguint_from_digits(n: &[u8]) -> Option<num_bigint::BigUint> {
246 num_bigint::BigUint::from_radix_be(n, 10)
247 }
248}
249
250
251impl Endianness for LittleEndian {
252 const NAME: &'static str = "LE";
253
254 #[cfg(rustc_1_75)]
255 fn into_iter<'a, D: 'a>(digits: Vec<D>) -> impl LeBigDigitIterator<'a, D> {
256 digits.into_iter()
257 }
258
259 #[cfg(rustc_1_75)]
260 fn iter_slice<D>(digits: &[D]) -> impl LeBigDigitIterator<'_, &D> {
261 digits.iter()
262 }
263
264 #[cfg(rustc_1_75)]
265 fn iter_slice_mut<D>(digits: &mut [D]) -> impl LeBigDigitIterator<'_, &mut D> {
266 digits.iter_mut()
267 }
268
269 #[cfg(not(rustc_1_75))]
270 fn into_iter<'a, D: 'a>(digits: Vec<D>) -> LittleEndianBigDigitIter<'a, D> {
271 LittleEndianBigDigitIter {
272 digits: Box::new(digits.into_iter()),
273 }
274 }
275
276 #[cfg(not(rustc_1_75))]
277 fn iter_slice<D>(digits: &[D]) -> LittleEndianBigDigitIter<'_, &D> {
278 LittleEndianBigDigitIter {
279 digits: Box::new(digits.iter()),
280 }
281 }
282
283 #[cfg(not(rustc_1_75))]
284 fn iter_slice_mut<D>(digits: &mut [D]) -> LittleEndianBigDigitIter<'_, &mut D> {
285 LittleEndianBigDigitIter {
286 digits: Box::new(digits.into_iter()),
287 }
288 }
289
290 #[cfg(not(rustc_1_75))]
291 fn addassign_carry_into_slice_at<R: RadixType>(
292 digits: &mut [R::Base],
293 carry: &mut R::Base,
294 idx: usize,
295 ) {
296 for dest in digits.iter_mut().skip(idx) {
297 R::addassign_carry(dest, carry);
298 if carry.is_zero() {
299 return;
300 }
301 }
302 }
303
304 fn push_significant_digit<D>(digits: &mut Vec<D>, d: D) {
305 digits.push(d);
306 }
307
308 fn split_least_significant<D>(digits: &[D], count: usize) -> (&[D], &[D]) {
309 digits.split_at(count)
310 }
311
312 fn split_least_significant_mut<D>(digits: &mut [D], count: usize) -> (&mut [D], &mut [D]) {
313 digits.split_at_mut(count)
314 }
315
316 fn split_most_significant_digit<D: Copy + Zero>(digits: &[D]) -> (D, &[D]) {
317 digits.split_last().map(|(&d, r)| (d, r)).unwrap_or((Zero::zero(), &[]))
318 }
319
320 fn strip_significant_zeros<D: Zero>(digits: &mut Vec<D>) {
321 if let Some(idx) = digits.iter().rposition(|d| !d.is_zero()) {
322 digits.truncate(idx + 1);
323 } else {
324 digits.clear();
325 }
326 }
327
328 fn split_significant_zeros<D: Zero>(digits: &[D]) -> (&[D], &[D]) {
329 if let Some(idx) = digits.iter().rposition(|d| !d.is_zero()) {
330 let (digits, sig_zeros) = digits.split_at(idx);
331 (digits, sig_zeros)
332 } else {
333 (&[], digits)
334 }
335 }
336
337 fn remove_insignificant_digits<D: Zero + Copy>(digits: &mut Vec<D>, n: usize) {
338 let last_nonzero_idx = digits.iter().rposition(|&d| !d.is_zero());
339
340 match (last_nonzero_idx, n > digits.len()) {
341 (Some(idx), false) => {
342 digits.copy_within(n..=idx, 0);
343 digits.truncate(idx - n + 1);
344 }
345 _ => {
346 digits.clear();
347 }
348 }
349 }
350
351 fn reorder_be_vec<D: Zero + Copy>(digits: &mut Vec<D>) {
352 match digits.iter().position(|&d| !d.is_zero()) {
353 None => digits.clear(),
354 Some(idx) => {
355 digits.copy_within(idx.., 0);
356 digits.truncate(digits.len() - idx);
357 digits.reverse();
358 }
359 }
360 }
361
362 #[allow(unused_variables)]
363 fn reorder_le_digits<D: Copy>(digits: &mut [D]) {
364 }
366
367 #[allow(unused_variables)]
368 fn rotate_trailing_le_digits_at<D: Copy>(digits: &mut [D], idx: usize) {
369 }
371
372 fn bigint_to_digits(n: &num_bigint::BigUint) -> Vec<u8> {
373 n.to_radix_le(10)
374 }
375
376 fn biguint_from_digits(n: &[u8]) -> Option<num_bigint::BigUint> {
377 num_bigint::BigUint::from_radix_le(n, 10)
378 }
379}
380
381pub(crate) trait LeBigDigitIterator<'a, D>
386 : Iterator<Item = D>
387 + ExactSizeIterator
388 + DoubleEndedIterator
389{
390}
391
392#[cfg(not(rustc_1_75))]
398pub(crate) struct LittleEndianBigDigitIter<'a, D> {
399 digits: Box<dyn LeBigDigitIterator<'a, D> + 'a>,
400}
401
402#[cfg(not(rustc_1_75))]
403impl<D> Iterator for LittleEndianBigDigitIter<'_, D> {
404 type Item = D;
405
406 fn next(&mut self) -> Option<Self::Item> {
407 self.digits.next()
408 }
409
410 fn size_hint(&self) -> (usize, Option<usize>) {
411 self.digits.size_hint()
412 }
413}
414
415#[cfg(not(rustc_1_75))]
416impl<D> DoubleEndedIterator for LittleEndianBigDigitIter<'_, D> {
417 fn next_back(&mut self) -> Option<Self::Item> {
418 self.digits.next_back()
419 }
420}
421
422#[cfg(not(rustc_1_75))]
423impl<D> ExactSizeIterator for LittleEndianBigDigitIter<'_, D> {
424 fn len(&self) -> usize {
425 self.digits.len()
426 }
427}
428
429
430impl<'a> LeBigDigitIterator<'a, u64> for num_bigint::U64Digits<'a> {}
431impl<'a> LeBigDigitIterator<'a, u32> for num_bigint::U32Digits<'a> {}
432
433impl<'a, D> LeBigDigitIterator<'a, &'a D> for stdlib::slice::Iter<'a, D> {}
434impl<'a, D> LeBigDigitIterator<'a, &'a D> for stdlib::iter::Rev<stdlib::slice::Iter<'a, D>> {}
435impl<'a, D> LeBigDigitIterator<'a, &'a mut D> for stdlib::slice::IterMut<'a, D> {}
436impl<'a, D> LeBigDigitIterator<'a, &'a mut D> for stdlib::iter::Rev<stdlib::slice::IterMut<'a, D>> {}
437
438impl<D> LeBigDigitIterator<'_, D> for stdlib::vec::IntoIter<D> {}
439impl<D> LeBigDigitIterator<'_, D> for stdlib::iter::Rev<stdlib::vec::IntoIter<D>> {}