use core::ops::{Shl, ShlAssign, Shr, ShrAssign};
use crate::UUID;
use super::shift_amount::ShiftAmount;
impl<T: ShiftAmount> Shl<T> for UUID {
type Output = Self;
#[inline]
fn shl(self, rhs: T) -> Self::Output {
Self::from_u128(self.to_u128().wrapping_shl(rhs.as_u32()))
}
}
impl<T: ShiftAmount> Shl<T> for &UUID {
type Output = UUID;
#[inline]
fn shl(self, rhs: T) -> Self::Output {
UUID::from_u128(self.to_u128().wrapping_shl(rhs.as_u32()))
}
}
impl<T: ShiftAmount> ShlAssign<T> for UUID {
#[inline]
fn shl_assign(&mut self, rhs: T) {
*self = *self << rhs;
}
}
impl<T: ShiftAmount> Shr<T> for UUID {
type Output = Self;
#[inline]
fn shr(self, rhs: T) -> Self::Output {
Self::from_u128(self.to_u128().wrapping_shr(rhs.as_u32()))
}
}
impl<T: ShiftAmount> Shr<T> for &UUID {
type Output = UUID;
#[inline]
fn shr(self, rhs: T) -> Self::Output {
UUID::from_u128(self.to_u128().wrapping_shr(rhs.as_u32()))
}
}
impl<T: ShiftAmount> ShrAssign<T> for UUID {
#[inline]
fn shr_assign(&mut self, rhs: T) {
*self = *self >> rhs;
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::op_ref)]
use super::*;
#[test]
fn shl_by_zero() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!(uuid << 0u32, uuid);
}
#[test]
fn shl_by_one() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 1u32), 2);
}
#[test]
fn shl_by_four() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4u32), 16);
}
#[test]
fn shl_by_eight() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 8u32), 256);
}
#[test]
fn shl_pattern() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!(u128::from(uuid << 4u32), 0b1010_1010_0000);
}
#[test]
fn shr_by_zero() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!(uuid >> 0u32, uuid);
}
#[test]
fn shr_by_one() {
let uuid = UUID::from(2u128);
assert_eq!(u128::from(uuid >> 1u32), 1);
}
#[test]
fn shr_by_four() {
let uuid = UUID::from(256u128);
assert_eq!(u128::from(uuid >> 4u32), 16);
}
#[test]
fn shr_by_eight() {
let uuid = UUID::from(256u128);
assert_eq!(u128::from(uuid >> 8u32), 1);
}
#[test]
fn shr_pattern() {
let uuid = UUID::from(0b1010_1010_0000u128);
assert_eq!(u128::from(uuid >> 4u32), 0b1010_1010);
}
#[test]
fn shl_with_u8() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4u8), 16);
}
#[test]
fn shl_with_u16() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4u16), 16);
}
#[test]
fn shl_with_u32() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4u32), 16);
}
#[test]
fn shl_with_u64() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4u64), 16);
}
#[test]
fn shl_with_u128() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4u128), 16);
}
#[test]
fn shl_with_usize() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4usize), 16);
}
#[test]
fn shl_with_i8() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4i8), 16);
}
#[test]
fn shl_with_i16() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4i16), 16);
}
#[test]
fn shl_with_i32() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4i32), 16);
}
#[test]
fn shl_with_i64() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4i64), 16);
}
#[test]
fn shl_with_i128() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4i128), 16);
}
#[test]
fn shl_with_isize() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 4isize), 16);
}
#[test]
fn shl_ref_uuid() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(&uuid << 4u32), 16);
}
#[test]
fn shr_ref_uuid() {
let uuid = UUID::from(16u128);
assert_eq!(u128::from(&uuid >> 4u32), 1);
}
#[test]
fn shl_with_ref_amount() {
let uuid = UUID::from(1u128);
let shift = 4u32;
assert_eq!(u128::from(uuid << &shift), 16);
}
#[test]
fn shl_ref_uuid_ref_amount() {
let uuid = UUID::from(1u128);
let shift = 4u32;
assert_eq!(u128::from(&uuid << &shift), 16);
}
#[test]
fn shl_assign() {
let mut uuid = UUID::from(1u128);
uuid <<= 4u32;
assert_eq!(u128::from(uuid), 16);
}
#[test]
fn shl_assign_ref_amount() {
let mut uuid = UUID::from(1u128);
let shift = 4u32;
uuid <<= &shift;
assert_eq!(u128::from(uuid), 16);
}
#[test]
fn shr_assign() {
let mut uuid = UUID::from(16u128);
uuid >>= 4u32;
assert_eq!(u128::from(uuid), 1);
}
#[test]
fn shr_assign_ref_amount() {
let mut uuid = UUID::from(16u128);
let shift = 4u32;
uuid >>= &shift;
assert_eq!(u128::from(uuid), 1);
}
#[test]
fn shl_by_128_wraps() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!(uuid << 128u32, uuid);
}
#[test]
fn shl_by_127() {
let uuid = UUID::from(1u128);
assert_eq!(u128::from(uuid << 127u32), 1u128 << 127);
}
#[test]
fn shr_by_128_wraps() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!(uuid >> 128u32, uuid);
}
#[test]
fn shr_by_127() {
let uuid = UUID::from(1u128 << 127);
assert_eq!(u128::from(uuid >> 127u32), 1);
}
#[test]
fn shl_shifts_out_high_bits() {
let uuid = UUID::max();
assert_eq!(u128::from(uuid << 1u32), u128::MAX << 1);
}
#[test]
fn shr_shifts_in_zeros() {
let uuid = UUID::max();
assert_eq!(u128::from(uuid >> 1u32), u128::MAX >> 1);
}
#[test]
fn shl_shr_roundtrip_when_no_loss() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!((uuid << 4u32) >> 4u32, uuid);
}
#[test]
fn shr_shl_not_roundtrip_when_bits_lost() {
let uuid = UUID::from(0b1010_1010u128);
assert_eq!((uuid >> 4u32) << 4u32, UUID::from(0b1010_0000u128));
}
#[test]
fn shl_nil() {
assert_eq!(UUID::nil() << 64u32, UUID::nil());
}
#[test]
fn shr_nil() {
assert_eq!(UUID::nil() >> 64u32, UUID::nil());
}
#[test]
fn shl_max_by_any_nonzero() {
let uuid = UUID::max();
assert_ne!(uuid << 1u32, uuid);
}
#[test]
fn shr_max_by_any_nonzero() {
let uuid = UUID::max();
assert_ne!(uuid >> 1u32, uuid);
}
#[test]
fn shl_negative_amount() {
let uuid = UUID::from(1u128);
let result = uuid << (-1i32);
let _ = u128::from(result);
}
}