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