use crate::*;
use crate::stdlib;
use crate::stdlib::fmt;
use crate::stdlib::Vec;
#[cfg(not(rustc_1_75))]
use stdlib::Box;
use num_traits::{Zero, PrimInt};
use super::radix::RadixType;
#[allow(dead_code)]
pub(crate) trait Endianness: Copy + Clone + Default + fmt::Debug {
const NAME: &'static str;
#[cfg(rustc_1_75)]
fn into_iter<'a, D: 'a>(digits: Vec<D>) -> impl LeBigDigitIterator<'a, D>;
#[cfg(rustc_1_75)]
fn iter_slice<D>(digits: &[D]) -> impl LeBigDigitIterator<'_, &D>;
#[cfg(rustc_1_75)]
fn iter_slice_mut<D>(digits: &mut [D]) -> impl LeBigDigitIterator<'_, &mut D>;
#[cfg(not(rustc_1_75))]
fn into_iter<'a, D: 'a>(digits: Vec<D>) -> LittleEndianBigDigitIter<'a, D>;
#[cfg(not(rustc_1_75))]
fn iter_slice<D>(digits: &[D]) -> LittleEndianBigDigitIter<'_, &D>;
#[cfg(not(rustc_1_75))]
fn iter_slice_mut<D>(digits: &mut [D]) -> LittleEndianBigDigitIter<'_, &mut D>;
#[cfg(rustc_1_75)]
fn addassign_carry_into_slice_at<R: RadixType>(
digits: &mut [R::Base],
carry: &mut R::Base,
idx: usize,
) {
for dest in Self::iter_slice_mut(digits).skip(idx) {
R::addassign_carry(dest, carry);
if carry.is_zero() {
return;
}
}
}
#[cfg(not(rustc_1_75))]
fn addassign_carry_into_slice_at<R: RadixType>(
digits: &mut [R::Base],
carry: &mut R::Base,
idx: usize,
);
fn push_significant_digit<D>(digits: &mut Vec<D>, d: D);
fn split_most_significant_digit<D: Zero + PrimInt>(digits: &[D]) -> (D, &[D]);
fn split_significant_zeros<D: Zero>(digits: &[D]) -> (&[D], &[D]);
fn split_least_significant<D>(digits: &[D], count: usize) -> (&[D], &[D]);
fn split_least_significant_mut<D>(digits: &mut [D], count: usize) -> (&mut [D], &mut [D]);
fn strip_significant_zeros<D: Copy + Zero>(digits: &mut Vec<D>);
fn count_significant_zeros<D: Zero>(digits: &[D]) -> usize {
Self::iter_slice(digits).rev().position(|d| !d.is_zero()).unwrap_or(digits.len())
}
fn remove_insignificant_digits<D: Zero + Copy>(digits: &mut Vec<D>, n: usize);
fn reorder_le_digits<D: Copy>(digits: &mut [D]);
fn reorder_be_vec<D: Zero + Copy>(digits: &mut Vec<D>);
fn rotate_trailing_le_digits_at<D: Copy>(digits: &mut [D], idx: usize);
fn bigint_to_digits(n: &num_bigint::BigUint) -> Vec<u8>;
fn biguint_from_digits(n: &[u8]) -> Option<num_bigint::BigUint>;
fn fill_vec_with_u128<R: RadixType>(vec: &mut Vec<R::Base>, n: u128);
}
#[derive(Copy, Clone, Debug, Default)]
pub(crate) struct BigEndian {}
#[derive(Copy, Clone, Debug, Default)]
pub(crate) struct LittleEndian {}
impl Endianness for BigEndian {
const NAME: &'static str = "BE";
#[cfg(rustc_1_75)]
fn into_iter<'a, D: 'a>(digits: Vec<D>) -> impl LeBigDigitIterator<'a, D> {
digits.into_iter().rev()
}
#[cfg(rustc_1_75)]
fn iter_slice<D>(digits: &[D]) -> impl LeBigDigitIterator<'_, &D> {
digits.iter().rev()
}
#[cfg(rustc_1_75)]
fn iter_slice_mut<D>(digits: &mut [D]) -> impl LeBigDigitIterator<'_, &mut D> {
digits.iter_mut().rev()
}
#[cfg(not(rustc_1_75))]
fn into_iter<'a, D: 'a>(digits: Vec<D>) -> LittleEndianBigDigitIter<'a, D> {
LittleEndianBigDigitIter {
digits: Box::new(digits.into_iter().rev()),
}
}
#[cfg(not(rustc_1_75))]
fn iter_slice<D>(digits: &[D]) -> LittleEndianBigDigitIter<'_, &D> {
LittleEndianBigDigitIter {
digits: Box::new(digits.iter().rev()),
}
}
#[cfg(not(rustc_1_75))]
fn iter_slice_mut<D>(digits: &mut [D]) -> LittleEndianBigDigitIter<'_, &mut D> {
LittleEndianBigDigitIter {
digits: Box::new(digits.iter_mut().rev()),
}
}
#[cfg(not(rustc_1_75))]
fn addassign_carry_into_slice_at<R: RadixType>(
digits: &mut [R::Base],
carry: &mut R::Base,
idx: usize,
) {
for dest in digits.iter_mut().rev().skip(idx) {
R::addassign_carry(dest, carry);
if carry.is_zero() {
return;
}
}
}
fn push_significant_digit<D>(digits: &mut Vec<D>, d: D) {
digits.insert(0, d);
}
fn split_least_significant<D>(digits: &[D], count: usize) -> (&[D], &[D]) {
let (hi, lo) = digits.split_at(digits.len() - count);
(lo, hi)
}
fn split_least_significant_mut<D>(digits: &mut [D], count: usize) -> (&mut [D], &mut [D]) {
let (hi, lo) = digits.split_at_mut(digits.len() - count);
(lo, hi)
}
fn split_most_significant_digit<D: Copy + Zero>(digits: &[D]) -> (D, &[D]) {
digits.split_first().map(|(&d, r)| (d, r)).unwrap_or((Zero::zero(), &[]))
}
fn strip_significant_zeros<D: Copy + Zero>(digits: &mut Vec<D>) {
if let Some(idx) = digits.iter().position(|d| !d.is_zero()) {
digits.copy_within(idx.., 0);
digits.truncate(digits.len() - idx);
} else {
digits.clear();
}
}
fn split_significant_zeros<D: Zero>(digits: &[D]) -> (&[D], &[D]) {
if let Some(idx) = digits.iter().position(|d| !d.is_zero()) {
let (sig_zeros, digits) = digits.split_at(idx);
(digits, sig_zeros)
} else {
(&[], digits)
}
}
fn remove_insignificant_digits<D: Zero + Copy>(digits: &mut Vec<D>, n: usize) {
digits.truncate(digits.len() - n);
}
fn reorder_le_digits<D: Copy>(digits: &mut [D]) {
digits.reverse()
}
fn reorder_be_vec<D: Zero + Copy>(digits: &mut Vec<D>) {
match digits.iter().position(|&d| !d.is_zero()) {
Some(0) => {}
Some(idx) => {
digits.copy_within(idx.., 0);
digits.truncate(digits.len() - idx);
}
None => digits.clear(),
}
}
fn rotate_trailing_le_digits_at<D: Copy>(digits: &mut [D], idx: usize) {
Self::reorder_le_digits(&mut digits[idx..]);
digits.rotate_left(idx);
}
fn bigint_to_digits(n: &num_bigint::BigUint) -> Vec<u8> {
n.to_radix_be(10)
}
fn biguint_from_digits(n: &[u8]) -> Option<num_bigint::BigUint> {
num_bigint::BigUint::from_radix_be(n, 10)
}
fn fill_vec_with_u128<R: RadixType>(vec: &mut Vec<R::Base>, n: u128) {
LittleEndian::fill_vec_with_u128::<R>(vec, n);
vec.reverse();
}
}
impl Endianness for LittleEndian {
const NAME: &'static str = "LE";
#[cfg(rustc_1_75)]
fn into_iter<'a, D: 'a>(digits: Vec<D>) -> impl LeBigDigitIterator<'a, D> {
digits.into_iter()
}
#[cfg(rustc_1_75)]
fn iter_slice<D>(digits: &[D]) -> impl LeBigDigitIterator<'_, &D> {
digits.iter()
}
#[cfg(rustc_1_75)]
fn iter_slice_mut<D>(digits: &mut [D]) -> impl LeBigDigitIterator<'_, &mut D> {
digits.iter_mut()
}
#[cfg(not(rustc_1_75))]
fn into_iter<'a, D: 'a>(digits: Vec<D>) -> LittleEndianBigDigitIter<'a, D> {
LittleEndianBigDigitIter {
digits: Box::new(digits.into_iter()),
}
}
#[cfg(not(rustc_1_75))]
fn iter_slice<D>(digits: &[D]) -> LittleEndianBigDigitIter<'_, &D> {
LittleEndianBigDigitIter {
digits: Box::new(digits.iter()),
}
}
#[cfg(not(rustc_1_75))]
fn iter_slice_mut<D>(digits: &mut [D]) -> LittleEndianBigDigitIter<'_, &mut D> {
LittleEndianBigDigitIter {
digits: Box::new(digits.into_iter()),
}
}
#[cfg(not(rustc_1_75))]
fn addassign_carry_into_slice_at<R: RadixType>(
digits: &mut [R::Base],
carry: &mut R::Base,
idx: usize,
) {
for dest in digits.iter_mut().skip(idx) {
R::addassign_carry(dest, carry);
if carry.is_zero() {
return;
}
}
}
fn push_significant_digit<D>(digits: &mut Vec<D>, d: D) {
digits.push(d);
}
fn split_least_significant<D>(digits: &[D], count: usize) -> (&[D], &[D]) {
digits.split_at(count)
}
fn split_least_significant_mut<D>(digits: &mut [D], count: usize) -> (&mut [D], &mut [D]) {
digits.split_at_mut(count)
}
fn split_most_significant_digit<D: Copy + Zero>(digits: &[D]) -> (D, &[D]) {
digits.split_last().map(|(&d, r)| (d, r)).unwrap_or((Zero::zero(), &[]))
}
fn strip_significant_zeros<D: Zero>(digits: &mut Vec<D>) {
if let Some(idx) = digits.iter().rposition(|d| !d.is_zero()) {
digits.truncate(idx + 1);
} else {
digits.clear();
}
}
fn split_significant_zeros<D: Zero>(digits: &[D]) -> (&[D], &[D]) {
if let Some(idx) = digits.iter().rposition(|d| !d.is_zero()) {
let (digits, sig_zeros) = digits.split_at(idx);
(digits, sig_zeros)
} else {
(&[], digits)
}
}
fn remove_insignificant_digits<D: Zero + Copy>(digits: &mut Vec<D>, n: usize) {
let last_nonzero_idx = digits.iter().rposition(|&d| !d.is_zero());
match (last_nonzero_idx, n > digits.len()) {
(Some(idx), false) => {
digits.copy_within(n..=idx, 0);
digits.truncate(idx - n + 1);
}
_ => {
digits.clear();
}
}
}
fn reorder_be_vec<D: Zero + Copy>(digits: &mut Vec<D>) {
match digits.iter().position(|&d| !d.is_zero()) {
None => digits.clear(),
Some(idx) => {
digits.copy_within(idx.., 0);
digits.truncate(digits.len() - idx);
digits.reverse();
}
}
}
#[allow(unused_variables)]
fn reorder_le_digits<D: Copy>(digits: &mut [D]) {
}
#[allow(unused_variables)]
fn rotate_trailing_le_digits_at<D: Copy>(digits: &mut [D], idx: usize) {
}
fn bigint_to_digits(n: &num_bigint::BigUint) -> Vec<u8> {
n.to_radix_le(10)
}
fn biguint_from_digits(n: &[u8]) -> Option<num_bigint::BigUint> {
num_bigint::BigUint::from_radix_le(n, 10)
}
fn fill_vec_with_u128<R: RadixType>(vec: &mut Vec<R::Base>, mut n: u128) {
let base = R::RADIX.to_u128().unwrap();
vec.clear();
while !n.is_zero() {
let (hi, lo) = num_integer::div_rem(n, base);
let lo = R::Base::from_u128(lo).unwrap();
vec.push(lo);
n = hi;
}
}
}
pub(crate) trait LeBigDigitIterator<'a, D>
: Iterator<Item = D>
+ ExactSizeIterator
+ DoubleEndedIterator
{
}
#[cfg(not(rustc_1_75))]
pub(crate) struct LittleEndianBigDigitIter<'a, D> {
digits: Box<dyn LeBigDigitIterator<'a, D> + 'a>,
}
#[cfg(not(rustc_1_75))]
impl<D> Iterator for LittleEndianBigDigitIter<'_, D> {
type Item = D;
fn next(&mut self) -> Option<Self::Item> {
self.digits.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.digits.size_hint()
}
}
#[cfg(not(rustc_1_75))]
impl<D> DoubleEndedIterator for LittleEndianBigDigitIter<'_, D> {
fn next_back(&mut self) -> Option<Self::Item> {
self.digits.next_back()
}
}
#[cfg(not(rustc_1_75))]
impl<D> ExactSizeIterator for LittleEndianBigDigitIter<'_, D> {
fn len(&self) -> usize {
self.digits.len()
}
}
impl<'a> LeBigDigitIterator<'a, u64> for num_bigint::U64Digits<'a> {}
impl<'a> LeBigDigitIterator<'a, u32> for num_bigint::U32Digits<'a> {}
impl<'a, D> LeBigDigitIterator<'a, &'a D> for stdlib::slice::Iter<'a, D> {}
impl<'a, D> LeBigDigitIterator<'a, &'a D> for stdlib::iter::Rev<stdlib::slice::Iter<'a, D>> {}
impl<'a, D> LeBigDigitIterator<'a, &'a mut D> for stdlib::slice::IterMut<'a, D> {}
impl<'a, D> LeBigDigitIterator<'a, &'a mut D> for stdlib::iter::Rev<stdlib::slice::IterMut<'a, D>> {}
impl<D> LeBigDigitIterator<'_, D> for stdlib::vec::IntoIter<D> {}
impl<D> LeBigDigitIterator<'_, D> for stdlib::iter::Rev<stdlib::vec::IntoIter<D>> {}