// 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::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::num::logic::traits::BitBlockAccess;
use malachite_base::test_util::generators::{
signed_unsigned_pair_gen_var_1, signed_unsigned_unsigned_triple_gen_var_2, unsigned_gen_var_5,
unsigned_pair_gen_var_2, unsigned_pair_gen_var_7, unsigned_triple_gen_var_5,
};
use malachite_base::test_util::num::logic::bit_block_access::get_bits_naive;
use std::panic::catch_unwind;
#[test]
pub fn test_get_bits_unsigned() {
fn test + PrimitiveUnsigned>(x: T, start: u64, end: u64, out: T) {
assert_eq!(x.get_bits(start, end), out);
assert_eq!(get_bits_naive::(&x, start, end), out);
}
test(0xabcdu16, 4, 8, 0xc);
test(0xabcdu16, 12, 100, 0xa);
test(0xabcdu16, 5, 9, 14);
test(0xabcdu16, 5, 5, 0);
test(0xabcdu16, 100, 200, 0);
test(0xabcdu64, 4, 8, 0xc);
test(0xabcdu64, 12, 100, 0xa);
test(0xabcdu64, 5, 9, 14);
test(0xabcdu64, 5, 5, 0);
test(0xabcdu64, 100, 200, 0);
}
#[test]
pub fn test_get_bits_signed() {
fn test + PrimitiveSigned, U: PrimitiveUnsigned>(
x: T,
start: u64,
end: u64,
out: U,
) {
assert_eq!(x.get_bits(start, end), out);
assert_eq!(get_bits_naive::(&x, start, end), out);
}
test(-0x5433i16, 4, 8, 0xc);
test(-0x5433i16, 5, 9, 14);
test(-0x5433i16, 5, 5, 0);
test(-0x5433i16, 100, 104, 0xf);
test(-0x5433i64, 4, 8, 0xc);
test(-0x5433i64, 5, 9, 14);
test(-0x5433i64, 5, 5, 0);
test(-0x5433i64, 100, 104, 0xf);
test(-1i8, 0, 8, 0xff);
}
fn get_bits_fail_helper() {
assert_panic!(T::exact_from(100).get_bits(10, 5));
}
fn get_bits_fail_helper_signed() {
assert_panic!(T::exact_from(-100).get_bits(100, 300));
}
#[test]
fn get_bits_fail() {
apply_fn_to_primitive_ints!(get_bits_fail_helper);
apply_fn_to_signeds!(get_bits_fail_helper_signed);
}
fn properties_helper_unsigned + PrimitiveUnsigned>() {
unsigned_triple_gen_var_5::().test_properties(|(n, start, end)| {
let bits = n.get_bits(start, end);
assert_eq!(get_bits_naive::(&n, start, end), bits);
assert!(bits <= n);
assert_eq!(n.get_bits(start + T::WIDTH, end + T::WIDTH), T::ZERO);
let mut n_alt = n;
n_alt.assign_bits(start, end, &bits);
assert_eq!(n_alt, n);
});
unsigned_pair_gen_var_2::().test_properties(|(n, start)| {
assert_eq!(n.get_bits(start, start), T::ZERO);
});
unsigned_pair_gen_var_7().test_properties(|(start, end)| {
assert_eq!(T::ZERO.get_bits(start, end), T::ZERO);
});
}
fn properties_helper_signed<
U: PrimitiveUnsigned + WrappingFrom,
S: BitBlockAccess + PrimitiveSigned + WrappingFrom,
>() {
signed_unsigned_unsigned_triple_gen_var_2::().test_properties(|(n, start, end)| {
let bits = n.get_bits(start, end);
assert_eq!(get_bits_naive::(&n, start, end), bits);
let mut n_alt = n;
n_alt.assign_bits(start, end, &bits);
assert_eq!(n_alt, n);
});
signed_unsigned_pair_gen_var_1::().test_properties(|(n, start)| {
assert_eq!(n.get_bits(start, start), U::ZERO);
assert_eq!(
n.get_bits(start + S::WIDTH, start + (S::WIDTH << 1)),
if n >= S::ZERO { U::ZERO } else { U::MAX }
);
});
unsigned_pair_gen_var_7().test_properties(|(start, end)| {
assert_eq!(S::ZERO.get_bits(start, end), U::ZERO);
});
unsigned_gen_var_5().test_properties(|start| {
assert_eq!(S::NEGATIVE_ONE.get_bits(start, start + S::WIDTH), U::MAX);
});
}
#[test]
fn get_bits_properties() {
apply_fn_to_unsigneds!(properties_helper_unsigned);
apply_fn_to_unsigned_signed_pairs!(properties_helper_signed);
}