Skip to content

Commit c4ed08d

Browse files
committed
Move shifting to separate modules
1 parent bdbe629 commit c4ed08d

File tree

5 files changed

+288
-284
lines changed

5 files changed

+288
-284
lines changed

src/bigint.rs

Lines changed: 4 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,13 @@ use core::convert::TryFrom;
1010
use core::default::Default;
1111
use core::fmt;
1212
use core::hash;
13-
use core::ops::{
14-
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Neg, Not, Shl, ShlAssign, Shr,
15-
ShrAssign,
16-
};
13+
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Neg, Not};
1714
use core::str::{self, FromStr};
1815
use core::{i128, u128};
1916
use core::{i64, u64};
2017

2118
use num_integer::{Integer, Roots};
22-
use num_traits::{FromPrimitive, Num, One, Pow, PrimInt, Signed, ToPrimitive, Zero};
19+
use num_traits::{FromPrimitive, Num, One, Pow, Signed, ToPrimitive, Zero};
2320

2421
use self::Sign::{Minus, NoSign, Plus};
2522

@@ -36,6 +33,8 @@ mod division;
3633
mod multiplication;
3734
mod subtraction;
3835

36+
mod shift;
37+
3938
/// A Sign is a `BigInt`'s composing element.
4039
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, Hash)]
4140
pub enum Sign {
@@ -745,108 +744,6 @@ impl Num for BigInt {
745744
}
746745
}
747746

748-
macro_rules! impl_shift {
749-
(@ref $Shx:ident :: $shx:ident, $ShxAssign:ident :: $shx_assign:ident, $rhs:ty) => {
750-
impl<'b> $Shx<&'b $rhs> for BigInt {
751-
type Output = BigInt;
752-
753-
#[inline]
754-
fn $shx(self, rhs: &'b $rhs) -> BigInt {
755-
$Shx::$shx(self, *rhs)
756-
}
757-
}
758-
impl<'a, 'b> $Shx<&'b $rhs> for &'a BigInt {
759-
type Output = BigInt;
760-
761-
#[inline]
762-
fn $shx(self, rhs: &'b $rhs) -> BigInt {
763-
$Shx::$shx(self, *rhs)
764-
}
765-
}
766-
impl<'b> $ShxAssign<&'b $rhs> for BigInt {
767-
#[inline]
768-
fn $shx_assign(&mut self, rhs: &'b $rhs) {
769-
$ShxAssign::$shx_assign(self, *rhs);
770-
}
771-
}
772-
};
773-
($($rhs:ty),+) => {$(
774-
impl Shl<$rhs> for BigInt {
775-
type Output = BigInt;
776-
777-
#[inline]
778-
fn shl(self, rhs: $rhs) -> BigInt {
779-
BigInt::from_biguint(self.sign, self.data << rhs)
780-
}
781-
}
782-
impl<'a> Shl<$rhs> for &'a BigInt {
783-
type Output = BigInt;
784-
785-
#[inline]
786-
fn shl(self, rhs: $rhs) -> BigInt {
787-
BigInt::from_biguint(self.sign, &self.data << rhs)
788-
}
789-
}
790-
impl ShlAssign<$rhs> for BigInt {
791-
#[inline]
792-
fn shl_assign(&mut self, rhs: $rhs) {
793-
self.data <<= rhs
794-
}
795-
}
796-
impl_shift! { @ref Shl::shl, ShlAssign::shl_assign, $rhs }
797-
798-
impl Shr<$rhs> for BigInt {
799-
type Output = BigInt;
800-
801-
#[inline]
802-
fn shr(self, rhs: $rhs) -> BigInt {
803-
let round_down = shr_round_down(&self, rhs);
804-
let data = self.data >> rhs;
805-
let data = if round_down { data + 1u8 } else { data };
806-
BigInt::from_biguint(self.sign, data)
807-
}
808-
}
809-
impl<'a> Shr<$rhs> for &'a BigInt {
810-
type Output = BigInt;
811-
812-
#[inline]
813-
fn shr(self, rhs: $rhs) -> BigInt {
814-
let round_down = shr_round_down(self, rhs);
815-
let data = &self.data >> rhs;
816-
let data = if round_down { data + 1u8 } else { data };
817-
BigInt::from_biguint(self.sign, data)
818-
}
819-
}
820-
impl ShrAssign<$rhs> for BigInt {
821-
#[inline]
822-
fn shr_assign(&mut self, rhs: $rhs) {
823-
let round_down = shr_round_down(self, rhs);
824-
self.data >>= rhs;
825-
if round_down {
826-
self.data += 1u8;
827-
} else if self.data.is_zero() {
828-
self.sign = NoSign;
829-
}
830-
}
831-
}
832-
impl_shift! { @ref Shr::shr, ShrAssign::shr_assign, $rhs }
833-
)*};
834-
}
835-
836-
impl_shift! { u8, u16, u32, u64, u128, usize }
837-
impl_shift! { i8, i16, i32, i64, i128, isize }
838-
839-
// Negative values need a rounding adjustment if there are any ones in the
840-
// bits that are getting shifted out.
841-
fn shr_round_down<T: PrimInt>(i: &BigInt, shift: T) -> bool {
842-
if i.is_negative() {
843-
let zeros = i.trailing_zeros().expect("negative values are non-zero");
844-
shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
845-
} else {
846-
false
847-
}
848-
}
849-
850747
impl Zero for BigInt {
851748
#[inline]
852749
fn zero() -> BigInt {

src/bigint/shift.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
use super::BigInt;
2+
use super::Sign::NoSign;
3+
4+
use core::ops::{Shl, ShlAssign, Shr, ShrAssign};
5+
use num_traits::{PrimInt, Signed, Zero};
6+
7+
macro_rules! impl_shift {
8+
(@ref $Shx:ident :: $shx:ident, $ShxAssign:ident :: $shx_assign:ident, $rhs:ty) => {
9+
impl<'b> $Shx<&'b $rhs> for BigInt {
10+
type Output = BigInt;
11+
12+
#[inline]
13+
fn $shx(self, rhs: &'b $rhs) -> BigInt {
14+
$Shx::$shx(self, *rhs)
15+
}
16+
}
17+
impl<'a, 'b> $Shx<&'b $rhs> for &'a BigInt {
18+
type Output = BigInt;
19+
20+
#[inline]
21+
fn $shx(self, rhs: &'b $rhs) -> BigInt {
22+
$Shx::$shx(self, *rhs)
23+
}
24+
}
25+
impl<'b> $ShxAssign<&'b $rhs> for BigInt {
26+
#[inline]
27+
fn $shx_assign(&mut self, rhs: &'b $rhs) {
28+
$ShxAssign::$shx_assign(self, *rhs);
29+
}
30+
}
31+
};
32+
($($rhs:ty),+) => {$(
33+
impl Shl<$rhs> for BigInt {
34+
type Output = BigInt;
35+
36+
#[inline]
37+
fn shl(self, rhs: $rhs) -> BigInt {
38+
BigInt::from_biguint(self.sign, self.data << rhs)
39+
}
40+
}
41+
impl<'a> Shl<$rhs> for &'a BigInt {
42+
type Output = BigInt;
43+
44+
#[inline]
45+
fn shl(self, rhs: $rhs) -> BigInt {
46+
BigInt::from_biguint(self.sign, &self.data << rhs)
47+
}
48+
}
49+
impl ShlAssign<$rhs> for BigInt {
50+
#[inline]
51+
fn shl_assign(&mut self, rhs: $rhs) {
52+
self.data <<= rhs
53+
}
54+
}
55+
impl_shift! { @ref Shl::shl, ShlAssign::shl_assign, $rhs }
56+
57+
impl Shr<$rhs> for BigInt {
58+
type Output = BigInt;
59+
60+
#[inline]
61+
fn shr(self, rhs: $rhs) -> BigInt {
62+
let round_down = shr_round_down(&self, rhs);
63+
let data = self.data >> rhs;
64+
let data = if round_down { data + 1u8 } else { data };
65+
BigInt::from_biguint(self.sign, data)
66+
}
67+
}
68+
impl<'a> Shr<$rhs> for &'a BigInt {
69+
type Output = BigInt;
70+
71+
#[inline]
72+
fn shr(self, rhs: $rhs) -> BigInt {
73+
let round_down = shr_round_down(self, rhs);
74+
let data = &self.data >> rhs;
75+
let data = if round_down { data + 1u8 } else { data };
76+
BigInt::from_biguint(self.sign, data)
77+
}
78+
}
79+
impl ShrAssign<$rhs> for BigInt {
80+
#[inline]
81+
fn shr_assign(&mut self, rhs: $rhs) {
82+
let round_down = shr_round_down(self, rhs);
83+
self.data >>= rhs;
84+
if round_down {
85+
self.data += 1u8;
86+
} else if self.data.is_zero() {
87+
self.sign = NoSign;
88+
}
89+
}
90+
}
91+
impl_shift! { @ref Shr::shr, ShrAssign::shr_assign, $rhs }
92+
)*};
93+
}
94+
95+
impl_shift! { u8, u16, u32, u64, u128, usize }
96+
impl_shift! { i8, i16, i32, i64, i128, isize }
97+
98+
// Negative values need a rounding adjustment if there are any ones in the
99+
// bits that are getting shifted out.
100+
fn shr_round_down<T: PrimInt>(i: &BigInt, shift: T) -> bool {
101+
if i.is_negative() {
102+
let zeros = i.trailing_zeros().expect("negative values are non-zero");
103+
shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
104+
} else {
105+
false
106+
}
107+
}

src/biguint.rs

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(any(feature = "quickcheck", feature = "arbitrary"))]
22
use crate::std_alloc::Box;
3-
use crate::std_alloc::{Cow, String, Vec};
3+
use crate::std_alloc::{String, Vec};
44
use core::cmp;
55
use core::cmp::Ordering::{self, Equal, Greater, Less};
66
#[cfg(has_try_from)]
@@ -10,10 +10,7 @@ use core::fmt;
1010
use core::hash;
1111
use core::iter::FusedIterator;
1212
use core::mem;
13-
use core::ops::{
14-
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign,
15-
Shl, ShlAssign, Shr, ShrAssign,
16-
};
13+
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
1714
use core::str::{self, FromStr};
1815
use core::{f32, f64};
1916
use core::{u32, u64, u8};
@@ -31,8 +28,8 @@ mod subtraction;
3128

3229
mod algorithms;
3330
mod monty;
31+
mod shift;
3432

35-
use self::algorithms::{biguint_shl, biguint_shr};
3633
use self::algorithms::{cmp_slice, fls, ilog2};
3734
use self::monty::monty_modpow;
3835

@@ -436,87 +433,6 @@ impl<'a> BitXorAssign<&'a BigUint> for BigUint {
436433
}
437434
}
438435

439-
macro_rules! impl_shift {
440-
(@ref $Shx:ident :: $shx:ident, $ShxAssign:ident :: $shx_assign:ident, $rhs:ty) => {
441-
impl<'b> $Shx<&'b $rhs> for BigUint {
442-
type Output = BigUint;
443-
444-
#[inline]
445-
fn $shx(self, rhs: &'b $rhs) -> BigUint {
446-
$Shx::$shx(self, *rhs)
447-
}
448-
}
449-
impl<'a, 'b> $Shx<&'b $rhs> for &'a BigUint {
450-
type Output = BigUint;
451-
452-
#[inline]
453-
fn $shx(self, rhs: &'b $rhs) -> BigUint {
454-
$Shx::$shx(self, *rhs)
455-
}
456-
}
457-
impl<'b> $ShxAssign<&'b $rhs> for BigUint {
458-
#[inline]
459-
fn $shx_assign(&mut self, rhs: &'b $rhs) {
460-
$ShxAssign::$shx_assign(self, *rhs);
461-
}
462-
}
463-
};
464-
($($rhs:ty),+) => {$(
465-
impl Shl<$rhs> for BigUint {
466-
type Output = BigUint;
467-
468-
#[inline]
469-
fn shl(self, rhs: $rhs) -> BigUint {
470-
biguint_shl(Cow::Owned(self), rhs)
471-
}
472-
}
473-
impl<'a> Shl<$rhs> for &'a BigUint {
474-
type Output = BigUint;
475-
476-
#[inline]
477-
fn shl(self, rhs: $rhs) -> BigUint {
478-
biguint_shl(Cow::Borrowed(self), rhs)
479-
}
480-
}
481-
impl ShlAssign<$rhs> for BigUint {
482-
#[inline]
483-
fn shl_assign(&mut self, rhs: $rhs) {
484-
let n = mem::replace(self, BigUint::zero());
485-
*self = n << rhs;
486-
}
487-
}
488-
impl_shift! { @ref Shl::shl, ShlAssign::shl_assign, $rhs }
489-
490-
impl Shr<$rhs> for BigUint {
491-
type Output = BigUint;
492-
493-
#[inline]
494-
fn shr(self, rhs: $rhs) -> BigUint {
495-
biguint_shr(Cow::Owned(self), rhs)
496-
}
497-
}
498-
impl<'a> Shr<$rhs> for &'a BigUint {
499-
type Output = BigUint;
500-
501-
#[inline]
502-
fn shr(self, rhs: $rhs) -> BigUint {
503-
biguint_shr(Cow::Borrowed(self), rhs)
504-
}
505-
}
506-
impl ShrAssign<$rhs> for BigUint {
507-
#[inline]
508-
fn shr_assign(&mut self, rhs: $rhs) {
509-
let n = mem::replace(self, BigUint::zero());
510-
*self = n >> rhs;
511-
}
512-
}
513-
impl_shift! { @ref Shr::shr, ShrAssign::shr_assign, $rhs }
514-
)*};
515-
}
516-
517-
impl_shift! { u8, u16, u32, u64, u128, usize }
518-
impl_shift! { i8, i16, i32, i64, i128, isize }
519-
520436
impl Zero for BigUint {
521437
#[inline]
522438
fn zero() -> BigUint {

0 commit comments

Comments
 (0)