// Copyright © 2024 Mikhail Hogrefe // // This file is part of Malachite. // // Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License (LGPL) as published by the Free Software Foundation; either version // 3 of the License, or (at your option) any later version. See . use malachite_base::num::arithmetic::traits::{ArithmeticCheckedShl, ModShl, ModShlAssign, ModShr}; use malachite_base::num::basic::integers::PrimitiveInt; use malachite_base::num::basic::signeds::PrimitiveSigned; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::WrappingFrom; use malachite_base::test_util::generators::{ signed_gen_var_5, signed_unsigned_pair_gen_var_13, unsigned_gen_var_5, unsigned_pair_gen_var_16, unsigned_pair_gen_var_2, unsigned_pair_gen_var_25, unsigned_signed_pair_gen_var_1, unsigned_signed_unsigned_triple_gen_var_2, unsigned_triple_gen_var_18, }; use std::panic::catch_unwind; #[test] fn test_mod_shl() { fn test< T: ModShl + ModShlAssign + PrimitiveUnsigned, U: PrimitiveInt, >( t: T, u: U, m: T, out: T, ) { assert_eq!(t.mod_shl(u, m), out); let mut t = t; t.mod_shl_assign(u, m); assert_eq!(t, out); } test::(0, 0, 1, 0); test::(0, 0, 5, 0); test::(8, 2, 10, 2); test::(10, 100, 17, 7); test::(10, -2, 15, 2); test::(10, -100, 19, 0); test::(10, -100, 19, 0); } fn mod_shl_fail_helper, U: PrimitiveInt>() { assert_panic!(T::ZERO.mod_shl(U::TWO, T::ZERO)); assert_panic!(T::from(123u8).mod_shl(U::TWO, T::from(123u8))); } #[test] fn mod_shl_fail() { apply_fn_to_unsigneds_and_primitive_ints!(mod_shl_fail_helper); } fn mod_shl_assign_fail_helper, U: PrimitiveInt>() { assert_panic!({ let mut x = T::ZERO; x.mod_shl_assign(U::TWO, T::ZERO); }); assert_panic!({ let mut x = T::from(123u8); x.mod_shl_assign(U::TWO, T::from(123u8)); }); } #[test] fn mod_shl_assign_fail() { apply_fn_to_unsigneds_and_primitive_ints!(mod_shl_assign_fail_helper); } fn mod_shl_properties_unsigned_unsigned_helper< T: ArithmeticCheckedShl + ModShl + ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned, >() { unsigned_triple_gen_var_18::().test_properties(|(n, u, m)| { assert!(n.mod_is_reduced(&m)); let shifted = n.mod_shl(u, m); assert!(shifted.mod_is_reduced(&m)); let mut shifted_alt = n; shifted_alt.mod_shl_assign(u, m); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shl(u) { assert_eq!(shifted_alt % m, shifted); } }); unsigned_pair_gen_var_16::().test_properties(|(n, m)| { assert_eq!(n.mod_shl(U::ZERO, m), n); }); unsigned_pair_gen_var_25::().test_properties(|(u, m)| { assert_eq!(T::ZERO.mod_shl(u, m), T::ZERO); }); unsigned_pair_gen_var_2::().test_properties(|(n, u)| { assert_panic!(n.mod_shl(u, T::ZERO)); assert_panic!({ let mut n = n; n.mod_shl_assign(u, T::ZERO); }); }); unsigned_gen_var_5::().test_properties(|u| { assert_eq!(T::ZERO.mod_shl(u, T::ONE), T::ZERO); }); } fn mod_shl_properties_unsigned_signed_helper< T: ArithmeticCheckedShl + ModShl + ModShr + ModShlAssign + PrimitiveUnsigned, U: PrimitiveUnsigned + WrappingFrom, S: PrimitiveSigned + WrappingFrom, >() { unsigned_signed_unsigned_triple_gen_var_2::().test_properties(|(n, i, m)| { assert!(n.mod_is_reduced(&m)); let shifted = n.mod_shl(i, m); assert!(shifted.mod_is_reduced(&m)); let mut shifted_alt = n; shifted_alt.mod_shl_assign(i, m); assert_eq!(shifted_alt, shifted); if let Some(shifted_alt) = n.arithmetic_checked_shl(i) { assert_eq!(shifted_alt % m, shifted); } if i != S::MIN { assert_eq!(n.mod_shr(-i, m), shifted); } }); unsigned_pair_gen_var_16::().test_properties(|(n, m)| { assert_eq!(n.mod_shl(S::ZERO, m), n); }); signed_unsigned_pair_gen_var_13::().test_properties(|(i, m)| { assert_eq!(T::ZERO.mod_shl(i, m), T::ZERO); }); unsigned_signed_pair_gen_var_1::().test_properties(|(n, i)| { assert_panic!(n.mod_shl(i, T::ZERO)); assert_panic!({ let mut n = n; n.mod_shl_assign(i, T::ZERO); }); }); signed_gen_var_5::().test_properties(|i| { assert_eq!(T::ZERO.mod_shl(i, T::ONE), T::ZERO); }); } #[test] fn mod_shl_properties() { apply_fn_to_unsigneds_and_unsigneds!(mod_shl_properties_unsigned_unsigned_helper); apply_fn_to_unsigneds_and_unsigned_signed_pairs!(mod_shl_properties_unsigned_signed_helper); }