[BROKEN] Broken definitions of the shift operators.
This commit is contained in:
@@ -48,3 +48,79 @@ macro_rules! derive_arithmetic_operators
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! derive_shift_operators
|
||||||
|
{
|
||||||
|
($type: ident, $asncl: ident, $cl: ident,
|
||||||
|
$asnfn: ident, $fn: ident,
|
||||||
|
$base: ident) =>
|
||||||
|
{
|
||||||
|
impl $asncl<$base> for $type {
|
||||||
|
fn $asnfn(&mut self, rhs: $base) {
|
||||||
|
self.$asnfn(rhs as u64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
derive_shifts_from_shift_assign!($type, $asncl, $cl,
|
||||||
|
$asnfn, $fn,
|
||||||
|
$base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! derive_shifts_from_shift_assign
|
||||||
|
{
|
||||||
|
($type: ident, $asncl: ident, $cl: ident,
|
||||||
|
$asnfn: ident, $fn: ident,
|
||||||
|
$base: ident) =>
|
||||||
|
{
|
||||||
|
impl $cl<$base> for $type {
|
||||||
|
type Output = $type;
|
||||||
|
|
||||||
|
fn $fn(self, rhs: $base) -> $type {
|
||||||
|
let mut copy = self.clone();
|
||||||
|
copy.$asnfn(rhs);
|
||||||
|
copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> $cl<$base> for &'a $type {
|
||||||
|
type Output = $type;
|
||||||
|
|
||||||
|
fn $fn(self, rhs: $base) -> $type {
|
||||||
|
let mut copy = self.clone();
|
||||||
|
copy.$asnfn(rhs);
|
||||||
|
copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! derive_signed_shift_operators
|
||||||
|
{
|
||||||
|
($type: ident, $base: ident, $signed_base: ident) => {
|
||||||
|
impl ShlAssign<$signed_base> for $type {
|
||||||
|
fn shl_assign(&mut self, rhs: $signed_base) {
|
||||||
|
if rhs < 0 {
|
||||||
|
self.shr_assign(-rhs);
|
||||||
|
} else {
|
||||||
|
self.shl_assign(rhs as $base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShrAssign<$signed_base> for $type {
|
||||||
|
fn shr_assign(&mut self, rhs: $signed_base) {
|
||||||
|
if rhs < 0 {
|
||||||
|
self.shl_assign(-rhs);
|
||||||
|
} else {
|
||||||
|
self.shr_assign(rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
derive_shifts_from_shift_assign!($type, ShlAssign, Shl,
|
||||||
|
shl_assign, shl, $signed_base);
|
||||||
|
derive_shifts_from_shift_assign!($type, ShrAssign, Shr,
|
||||||
|
shr_assign, shr, $signed_base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -309,6 +309,100 @@ derive_arithmetic_operators!(UCN, BitOr, bitor, BitOrAssign, bitor_assign);
|
|||||||
derive_arithmetic_operators!(UCN, BitXor, bitxor, BitXorAssign, bitxor_assign);
|
derive_arithmetic_operators!(UCN, BitXor, bitxor, BitXorAssign, bitxor_assign);
|
||||||
derive_arithmetic_operators!(UCN, BitAnd, bitand, BitAndAssign, bitand_assign);
|
derive_arithmetic_operators!(UCN, BitAnd, bitand, BitAndAssign, bitand_assign);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Shifts
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
impl ShlAssign<u64> for UCN {
|
||||||
|
fn shl_assign(&mut self, rhs: u64) {
|
||||||
|
let mut digits = rhs / 64;
|
||||||
|
let bits = rhs % 64;
|
||||||
|
let mut carry = 0;
|
||||||
|
|
||||||
|
// ripple the bit-level shift through
|
||||||
|
if bits != 0 {
|
||||||
|
for x in self.contents.iter_mut() {
|
||||||
|
let new_carry = *x >> (64 - bits);
|
||||||
|
*x = (*x << bits) | carry;
|
||||||
|
carry = new_carry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we pulled some stuff off the end, add it back
|
||||||
|
if carry != 0 {
|
||||||
|
self.contents.push(carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the appropriate digits on the low side
|
||||||
|
while digits > 0 {
|
||||||
|
self.contents.insert(0,0);
|
||||||
|
digits -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Shl<u64> for UCN {
|
||||||
|
type Output = UCN;
|
||||||
|
|
||||||
|
fn shl(self, rhs: u64) -> UCN {
|
||||||
|
let mut copy = self.clone();
|
||||||
|
copy.shl_assign(rhs);
|
||||||
|
copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
derive_shift_operators!(UCN, ShlAssign, Shl, shl_assign, shl, usize);
|
||||||
|
derive_shift_operators!(UCN, ShlAssign, Shl, shl_assign, shl, u32);
|
||||||
|
derive_shift_operators!(UCN, ShlAssign, Shl, shl_assign, shl, u16);
|
||||||
|
derive_shift_operators!(UCN, ShlAssign, Shl, shl_assign, shl, u8);
|
||||||
|
|
||||||
|
impl ShrAssign<u64> for UCN {
|
||||||
|
fn shr_assign(&mut self, rhs: u64) {
|
||||||
|
let mut digits = rhs / 64;
|
||||||
|
let bits = rhs % 64;
|
||||||
|
|
||||||
|
// remove the appropriate digits on the low side
|
||||||
|
while digits > 0 {
|
||||||
|
self.contents.remove(0);
|
||||||
|
digits -= 1;
|
||||||
|
}
|
||||||
|
// ripple the shifts over
|
||||||
|
let mut carry = 0;
|
||||||
|
let mask = !(0xFFFFFFFFFFFFFFFF << bits);
|
||||||
|
|
||||||
|
for x in self.contents.iter_mut().rev() {
|
||||||
|
let base = *x >> bits;
|
||||||
|
let (new_carry, _) = (*x & mask).overflowing_shl((64-bits) as u32);
|
||||||
|
*x = base | carry;
|
||||||
|
carry = new_carry;
|
||||||
|
}
|
||||||
|
// in this case, we just junk the extra carry bits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Shr<u64> for UCN {
|
||||||
|
type Output = UCN;
|
||||||
|
|
||||||
|
fn shr(self, rhs: u64) -> UCN {
|
||||||
|
let mut copy = self.clone();
|
||||||
|
copy.shr_assign(rhs);
|
||||||
|
copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
derive_shift_operators!(UCN, ShrAssign, Shr, shr_assign, shr, usize);
|
||||||
|
derive_shift_operators!(UCN, ShrAssign, Shr, shr_assign, shr, u32);
|
||||||
|
derive_shift_operators!(UCN, ShrAssign, Shr, shr_assign, shr, u16);
|
||||||
|
derive_shift_operators!(UCN, ShrAssign, Shr, shr_assign, shr, u8);
|
||||||
|
|
||||||
|
derive_signed_shift_operators!(UCN, usize, isize);
|
||||||
|
derive_signed_shift_operators!(UCN, u64, i64);
|
||||||
|
derive_signed_shift_operators!(UCN, u32, i32);
|
||||||
|
derive_signed_shift_operators!(UCN, u16, i16);
|
||||||
|
derive_signed_shift_operators!(UCN, u8, i8);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Tests!
|
// Tests!
|
||||||
@@ -475,6 +569,12 @@ mod test {
|
|||||||
let effs = UCN{ contents: contents };
|
let effs = UCN{ contents: contents };
|
||||||
(&a & &effs) == a
|
(&a & &effs) == a
|
||||||
}
|
}
|
||||||
|
fn shl_identity(a: UCN) -> bool {
|
||||||
|
(&a << 0) == a
|
||||||
|
}
|
||||||
|
fn shr_identity(a: UCN) -> bool {
|
||||||
|
(&a << 0) == a
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quickcheck! {
|
quickcheck! {
|
||||||
@@ -488,6 +588,9 @@ mod test {
|
|||||||
let zero = UCN{ contents: vec![] };
|
let zero = UCN{ contents: vec![] };
|
||||||
(&a & &zero) == zero
|
(&a & &zero) == zero
|
||||||
}
|
}
|
||||||
|
fn shl_shr_annihilate(a: UCN, b: u8) -> bool {
|
||||||
|
((&a << b) >> b) == a
|
||||||
|
}
|
||||||
fn xor_inverse(a: UCN, b: UCN) -> bool {
|
fn xor_inverse(a: UCN, b: UCN) -> bool {
|
||||||
((&a ^ &b) ^ &b) == a
|
((&a ^ &b) ^ &b) == a
|
||||||
}
|
}
|
||||||
@@ -521,4 +624,5 @@ mod test {
|
|||||||
(!(&a2 | &b2)) == (!a2 & !b2)
|
(!(&a2 | &b2)) == (!a2 & !b2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user