1#![allow(dead_code)]
4
5use crate::*;
6use super::radix::RadixPowerOfTen;
7use super::endian::LittleEndian;
8use crate::arithmetic::diff_usize;
9
10type BigDigitVec<R> = super::digitvec::DigitVec<R, LittleEndian>;
11
12#[derive(#[automatically_derived]
impl ::core::clone::Clone for AddAssignSliceAlignment {
#[inline]
fn clone(&self) -> AddAssignSliceAlignment {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AddAssignSliceAlignment { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for AddAssignSliceAlignment {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
AddAssignSliceAlignment::RightOverlap { count: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"RightOverlap", "count", &__self_0),
AddAssignSliceAlignment::RightDisjoint { count: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"RightDisjoint", "count", &__self_0),
AddAssignSliceAlignment::LeftOverlap { count: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"LeftOverlap", "count", &__self_0),
AddAssignSliceAlignment::LeftDisjoint { count: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"LeftDisjoint", "count", &__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for AddAssignSliceAlignment {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<usize>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for AddAssignSliceAlignment {
#[inline]
fn eq(&self, other: &AddAssignSliceAlignment) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(AddAssignSliceAlignment::RightOverlap { count: __self_0 },
AddAssignSliceAlignment::RightOverlap { count: __arg1_0 })
=> __self_0 == __arg1_0,
(AddAssignSliceAlignment::RightDisjoint { count: __self_0 },
AddAssignSliceAlignment::RightDisjoint { count: __arg1_0 })
=> __self_0 == __arg1_0,
(AddAssignSliceAlignment::LeftOverlap { count: __self_0 },
AddAssignSliceAlignment::LeftOverlap { count: __arg1_0 }) =>
__self_0 == __arg1_0,
(AddAssignSliceAlignment::LeftDisjoint { count: __self_0 },
AddAssignSliceAlignment::LeftDisjoint { count: __arg1_0 })
=> __self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
15pub(crate) enum AddAssignSliceAlignment {
16 RightOverlap {
19 count: usize,
20 },
21 RightDisjoint {
25 count: usize,
26 },
27 LeftOverlap {
31 count: usize,
32 },
33 LeftDisjoint {
38 count: usize,
39 },
40}
41
42impl AddAssignSliceAlignment {
43 pub fn from_lengths_and_scales(lhs: WithScale<usize>, rhs: WithScale<usize>) -> Self {
46 use cmp::Ordering::*;
47
48 match diff_usize(rhs.scale, lhs.scale) {
49 (Equal, _) => {
50 Self::RightOverlap {
51 count: 0,
52 }
53 }
54 (Less, count) => {
55 if count < lhs.value {
56 Self::RightOverlap {
57 count,
58 }
59 } else {
60 Self::RightDisjoint {
61 count,
62 }
63 }
64 }
65 (Greater, count) => {
66 if count < rhs.value {
67 Self::LeftOverlap {
68 count,
69 }
70 } else {
71 Self::LeftDisjoint {
72 count,
73 }
74 }
75 }
76 }
77 }
78
79 pub fn from_lengths_and_icount(lhs: WithIntCount<usize>, rhs: WithIntCount<usize>) -> Self {
82 Self::from_lengths_and_scales(
84 WithScale {
85 scale: lhs.value as i64 - lhs.count as i64,
86 value: lhs.value,
87 },
88 WithScale {
89 scale: rhs.value as i64 - rhs.count as i64,
90 value: rhs.value,
91 },
92 )
93 }
94}
95
96#[derive(#[automatically_derived]
impl<R: ::core::marker::Copy, I: ::core::marker::Copy> ::core::marker::Copy
for BigDigitSplitterIter<R, I> where R: RadixPowerOfTen,
I: Iterator<Item = R::Base> {
}Copy, #[automatically_derived]
impl<R: ::core::clone::Clone, I: ::core::clone::Clone> ::core::clone::Clone
for BigDigitSplitterIter<R, I> where R: RadixPowerOfTen,
I: Iterator<Item = R::Base> {
#[inline]
fn clone(&self) -> BigDigitSplitterIter<R, I> {
BigDigitSplitterIter {
shift: ::core::clone::Clone::clone(&self.shift),
digits: ::core::clone::Clone::clone(&self.digits),
}
}
}Clone, #[automatically_derived]
impl<R: ::core::fmt::Debug, I: ::core::fmt::Debug> ::core::fmt::Debug for
BigDigitSplitterIter<R, I> where R: RadixPowerOfTen,
I: Iterator<Item = R::Base> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"BigDigitSplitterIter", "shift", &self.shift, "digits",
&&self.digits)
}
}Debug)]
97pub(crate) struct BigDigitSplitterIter<R, I>
98where
99 R: RadixPowerOfTen,
100 I: Iterator<Item = R::Base>,
101{
102 shift: ShiftState<R>,
103 digits: I,
104}
105
106impl<R, I> BigDigitSplitterIter<R, I>
107where
108 R: RadixPowerOfTen,
109 I: Iterator<Item = R::Base>,
110{
111 pub fn new(iter: I) -> Self {
113 Self::from_shifter_and_iter(ShiftState::Zero, iter)
114 }
115
116 pub fn from_shifter_and_iter(shifter: ShiftState<R>, iter: I) -> Self {
118 Self {
119 shift: shifter,
120 digits: iter,
121 }
122 }
123
124 pub fn mask(&self) -> R::Base {
126 match self.shift {
127 ShiftState::Zero => Zero::zero(),
128 ShiftState::Shifted {
129 mask:
130 BigDigitSplitter {
131 mask,
132 ..
133 },
134 ..
135 } => mask,
136 }
137 }
138
139 pub fn shift_minus_one(&self) -> R::Base {
144 match self {
145 BigDigitSplitterIter {
146 shift: ShiftState::Zero,
147 ..
148 } => R::max(),
149 BigDigitSplitterIter {
150 shift:
151 ShiftState::Shifted {
152 mask,
153 ..
154 },
155 ..
156 } => mask.shift - One::one(),
157 }
158 }
159
160 pub fn extend_vector(self, dest: &mut BigDigitVec<R>) {
162 if let Self {
163 shift: ShiftState::Zero,
164 digits,
165 ..
166 } = self
167 {
168 dest.digits.extend(digits);
169 } else {
170 dest.digits.extend(self);
171 }
172 }
173
174 pub(crate) fn extend_vector_adding_carry(
179 mut self,
180 mut carry: R::Base,
181 dest: &mut BigDigitVec<R>,
182 ) {
183 while !carry.is_zero() {
184 if let Some(mut next_digit) = self.next() {
185 R::addassign_carry(&mut next_digit, &mut carry);
186 dest.push_significant_digit(next_digit);
187 } else {
188 dest.push_significant_digit(carry);
189 return;
190 }
191 }
192 self.extend_vector(dest)
193 }
194
195 pub(crate) fn extend_vector_with_carry_borrow(
197 mut self,
198 carry: &mut R::Base,
199 borrow: &mut R::Base,
200 dest: &mut BigDigitVec<R>,
201 ) {
202 use num_traits::WrappingSub;
203
204 if borrow.is_zero() && carry.is_zero() {
205 return self.extend_vector(dest);
206 }
207
208 if carry == borrow {
210 *borrow = Zero::zero();
211 *carry = Zero::zero();
212 return self.extend_vector(dest);
213 }
214
215 match self.next() {
216 Some(digit) => {
217 let d = R::sub_with_carry_borrow(digit, R::Base::zero(), carry, borrow);
218 dest.push_significant_digit(d);
219 self.extend_vector_with_carry_borrow(borrow, carry, dest);
221 }
222 None if carry == borrow => {}
223 None if carry > borrow => {
224 dest.push_significant_digit(carry.wrapping_sub(borrow));
225 *carry = Zero::zero();
226 *borrow = Zero::zero();
227 }
228 None => {
229 { ::core::panicking::unreachable_display(&"borrow underflow"); };unreachable!("borrow underflow");
230 }
231 }
232 }
233
234 pub fn advance_by_n(&mut self, n: usize) {
236 for _ in 0..n {
238 if self.next().is_none() {
239 break;
240 }
241 }
242 }
243
244 fn on_next_digit(&mut self, digit: R::Base) -> R::Base {
246 if let ShiftState::Shifted {
247 ref mut prev,
248 ref mask,
249 } = self.shift
250 {
251 let (hi, mut lo) = mask.split_and_shift(digit);
252 lo += *prev;
253 *prev = hi;
254 lo
255 } else {
256 digit
257 }
258 }
259
260 fn on_last_digit(&mut self) -> Option<R::Base> {
263 match self.shift {
264 ShiftState::Shifted {
265 ref mut prev,
266 ..
267 } if !prev.is_zero() => {
268 let result = *prev;
269 *prev = Zero::zero();
270 Some(result)
271 }
272 _ => None,
273 }
274 }
275}
276
277impl<R, I> Iterator for BigDigitSplitterIter<R, I>
278where
279 R: RadixPowerOfTen,
280 I: Iterator<Item = R::Base>,
281{
282 type Item = R::Base;
283
284 fn next(&mut self) -> Option<Self::Item> {
285 self.digits
286 .next()
287 .map(|digit| self.on_next_digit(digit))
288 .or_else(|| self.on_last_digit())
289 }
290}
291
292type CopiedDigitSlice<'a, R> =
293 stdlib::iter::Copied<stdlib::slice::Iter<'a, <R as super::radix::RadixType>::Base>>;
294pub(crate) type BigDigitSliceSplitterIter<'a, R> = BigDigitSplitterIter<R, CopiedDigitSlice<'a, R>>;
295
296impl<'a, R: RadixPowerOfTen> BigDigitSliceSplitterIter<'a, R> {
297 fn comp_n(n: usize) -> usize {
299 if true {
if !(n < R::DIGITS) {
::core::panicking::panic("assertion failed: n < R::DIGITS")
};
};debug_assert!(n < R::DIGITS);
300 if n == 0 {
301 0
302 } else {
303 R::DIGITS - n
304 }
305 }
306
307 pub fn from_slice(slice: &'a [R::Base]) -> Self {
309 Self {
310 shift: ShiftState::Zero,
311 digits: slice.iter().copied(),
312 }
313 }
314
315 pub(crate) fn from_slice_shifting_left(slice: &'a [R::Base], n: usize) -> Self {
322 Self::from_slice_starting_bottom(slice, Self::comp_n(n))
323 }
324
325 pub(crate) fn from_slice_shifting_right(slice: &'a [R::Base], n: usize) -> Self {
334 Self::from_slice_starting_top(slice, Self::comp_n(n))
335 }
336
337 pub(crate) fn from_slice_starting_bottom(slice: &'a [R::Base], n: usize) -> Self {
344 Self::from_shifter_and_iter(ShiftState::starting_with_bottom(n), slice.iter().copied())
345 }
346
347 pub(crate) fn from_slice_starting_top(slice: &'a [R::Base], n: usize) -> Self {
357 let mut digits = slice.iter().copied();
358 let shifter = ShiftState::starting_with_top(n, &mut digits);
359 Self::from_shifter_and_iter(shifter, digits)
360 }
361
362 pub fn is_exhausted(&self) -> bool {
364 match self.shift {
365 ShiftState::Zero => self.digits.len() == 0,
366 _ => self.peek_next().is_none(),
367 }
368 }
369
370 pub fn peek_next(&self) -> Option<R::Base> {
372 self.clone().next()
373 }
374}
375
376#[derive(#[automatically_derived]
impl<R: ::core::marker::Copy + RadixPowerOfTen> ::core::marker::Copy for
ShiftState<R> where R::Base: ::core::marker::Copy {
}Copy, #[automatically_derived]
impl<R: ::core::clone::Clone + RadixPowerOfTen> ::core::clone::Clone for
ShiftState<R> where R::Base: ::core::clone::Clone {
#[inline]
fn clone(&self) -> ShiftState<R> {
match self {
ShiftState::Zero => ShiftState::Zero,
ShiftState::Shifted { mask: __self_0, prev: __self_1 } =>
ShiftState::Shifted {
mask: ::core::clone::Clone::clone(__self_0),
prev: ::core::clone::Clone::clone(__self_1),
},
}
}
}Clone, #[automatically_derived]
impl<R: ::core::fmt::Debug + RadixPowerOfTen> ::core::fmt::Debug for
ShiftState<R> where R::Base: ::core::fmt::Debug {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ShiftState::Zero => ::core::fmt::Formatter::write_str(f, "Zero"),
ShiftState::Shifted { mask: __self_0, prev: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Shifted", "mask", __self_0, "prev", &__self_1),
}
}
}Debug)]
379pub(crate) enum ShiftState<R: RadixPowerOfTen> {
380 Zero,
381 Shifted {
382 mask: BigDigitSplitter<R>,
383 prev: R::Base,
384 },
385}
386
387impl<R: RadixPowerOfTen> ShiftState<R> {
388 fn starting_with_bottom(n: usize) -> Self {
396 if n == 0 {
397 Self::Zero
398 } else {
399 Self::Shifted {
400 mask: BigDigitSplitter::mask_low(n as u8),
401 prev: R::Base::zero(),
402 }
403 }
404 }
405
406 fn starting_with_top<I: Iterator<Item = R::Base>>(n: usize, digits: &mut I) -> Self {
413 if n == 0 {
414 Self::Zero
415 } else {
416 let mask = BigDigitSplitter::mask_high(n);
417 let first_digit = digits.next().map(|d| d / mask.mask).unwrap_or(Zero::zero());
418 Self::Shifted {
419 mask: mask,
420 prev: first_digit,
421 }
422 }
423 }
424}
425
426#[derive(#[automatically_derived]
impl<R: ::core::marker::Copy + RadixPowerOfTen> ::core::marker::Copy for
BigDigitSplitter<R> where R::Base: ::core::marker::Copy,
R::Base: ::core::marker::Copy {
}Copy, #[automatically_derived]
impl<R: ::core::clone::Clone + RadixPowerOfTen> ::core::clone::Clone for
BigDigitSplitter<R> where R::Base: ::core::clone::Clone,
R::Base: ::core::clone::Clone {
#[inline]
fn clone(&self) -> BigDigitSplitter<R> {
BigDigitSplitter {
mask: ::core::clone::Clone::clone(&self.mask),
shift: ::core::clone::Clone::clone(&self.shift),
}
}
}Clone, #[automatically_derived]
impl<R: ::core::fmt::Debug + RadixPowerOfTen> ::core::fmt::Debug for
BigDigitSplitter<R> where R::Base: ::core::fmt::Debug,
R::Base: ::core::fmt::Debug {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"BigDigitSplitter", "mask", &self.mask, "shift", &&self.shift)
}
}Debug)]
428pub(crate) struct BigDigitSplitter<R: RadixPowerOfTen> {
429 mask: R::Base,
431 shift: R::Base,
433}
434
435impl<R: RadixPowerOfTen> BigDigitSplitter<R> {
436 pub fn mask_low(n: u8) -> Self {
438 use crate::arithmetic::ten_to_the_t;
439
440 if true {
if !((n as usize) < R::DIGITS) {
::core::panicking::panic("assertion failed: (n as usize) < R::DIGITS")
};
};debug_assert!((n as usize) < R::DIGITS);
441 let mask = ten_to_the_t(n);
442 let shift = ten_to_the_t(R::DIGITS as u8 - n);
443 Self {
444 shift,
445 mask,
446 }
447 }
448
449 pub fn mask_high(n: usize) -> Self {
451 Self::mask_low((R::DIGITS - n) as u8)
452 }
453
454 pub fn split(&self, n: R::Base) -> (R::Base, R::Base) {
460 let lo = n % self.mask;
461 (n - lo, lo)
462 }
463
464 pub fn split_and_shift(&self, n: R::Base) -> (R::Base, R::Base) {
471 let (hi, lo) = self.div_rem(n);
472 (hi, lo * self.shift)
473 }
474
475 pub fn div_rem(&self, n: R::Base) -> (R::Base, R::Base) {
476 n.div_rem(&self.mask)
477 }
478
479 pub fn div(&self, n: R::Base) -> R::Base {
480 n / self.mask
481 }
482}
483
484#[derive(#[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for WithIntCount<T> {
#[inline]
fn clone(&self) -> WithIntCount<T> {
WithIntCount {
count: ::core::clone::Clone::clone(&self.count),
value: ::core::clone::Clone::clone(&self.value),
}
}
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy> ::core::marker::Copy for WithIntCount<T> { }Copy, #[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for WithIntCount<T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "WithIntCount",
"count", &self.count, "value", &&self.value)
}
}Debug, #[automatically_derived]
impl<T: ::core::default::Default> ::core::default::Default for WithIntCount<T>
{
#[inline]
fn default() -> WithIntCount<T> {
WithIntCount {
count: ::core::default::Default::default(),
value: ::core::default::Default::default(),
}
}
}Default)]
490pub(crate) struct WithIntCount<T> {
491 count: i32,
493 value: T,
495}
496
497#[cfg(test)]
498#[allow(clippy::zero_prefixed_literal)]
499mod test {
500 use super::*;
501
502 include!("alignment.tests.rs");
503}