// 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 itertools::repeat_n; use malachite_base::num::basic::unsigneds::PrimitiveUnsigned; use malachite_base::num::conversion::traits::{Digits, SaturatingFrom}; use malachite_base::slices::{slice_leading_zeros, slice_trailing_zeros}; use malachite_base::test_util::generators::{ unsigned_pair_gen_var_10, unsigned_vec_unsigned_pair_gen_var_7, unsigned_vec_unsigned_pair_gen_var_8, unsigned_vec_unsigned_pair_gen_var_9, }; use std::panic::catch_unwind; #[test] pub fn test_from_digits_asc() { fn test_ok + PrimitiveUnsigned, U: PrimitiveUnsigned>( base: U, digits: &[U], out: T, ) { assert_eq!(T::from_digits_asc(&base, digits.iter().copied()), Some(out)); } test_ok::(64, &[], 0); test_ok::(64, &[0, 0, 0], 0); test_ok::(64, &[2], 2); test_ok::(8, &[3, 7, 1], 123); test_ok::(256, &[64, 66, 15], 1000000); test_ok::(256, &[64, 66, 15], 1000000); test_ok::(2, &[0, 0, 0, 1, 0, 1, 1, 1, 1, 1], 1000); test_ok::(3, &[], 0); test_ok::(3, &[2], 2); test_ok::(3, &[0, 1, 1, 0, 0, 1, 1, 2, 0, 0, 2], 123456); test_ok::(10, &[6, 5, 4, 3, 2, 1], 123456); test_ok::(100, &[56, 34, 12], 123456); test_ok::(123, &[87, 19, 8], 123456); test_ok::(123, &[87, 19, 8, 0, 0, 0], 123456); fn test_err + PrimitiveUnsigned, U: PrimitiveUnsigned>(base: U, digits: &[U]) { assert_eq!(T::from_digits_asc(&base, digits.iter().copied()), None); } test_err::(64, &[1; 1000]); test_err::(2, &[2]); test_err::(1000, &[1, 2, 3]); } fn from_digits_asc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_asc(&U::ZERO, digits.iter().copied()); }); assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_asc(&U::ONE, digits.iter().copied()); }); } #[test] pub fn test_from_digits_desc() { fn test_ok + PrimitiveUnsigned, U: PrimitiveUnsigned>( base: U, digits: &[U], out: T, ) { assert_eq!( T::from_digits_desc(&base, digits.iter().copied()), Some(out) ); } test_ok::(64, &[], 0); test_ok::(64, &[0, 0, 0], 0); test_ok::(64, &[2], 2); test_ok::(8, &[1, 7, 3], 123); test_ok::(256, &[15, 66, 64], 1000000); test_ok::(256, &[15, 66, 64], 1000000); test_ok::(2, &[1, 1, 1, 1, 1, 0, 1, 0, 0, 0], 1000); test_ok::(3, &[], 0); test_ok::(3, &[2], 2); test_ok::(3, &[2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0], 123456); test_ok::(10, &[1, 2, 3, 4, 5, 6], 123456); test_ok::(100, &[12, 34, 56], 123456); test_ok::(123, &[8, 19, 87], 123456); test_ok::(123, &[0, 0, 0, 8, 19, 87], 123456); fn test_err + PrimitiveUnsigned, U: PrimitiveUnsigned>(base: U, digits: &[U]) { assert_eq!(T::from_digits_desc(&base, digits.iter().copied()), None); } test_err::(64, &[1; 1000]); test_err::(2, &[2]); test_err::(1000, &[1, 2, 3]); } fn from_digits_desc_fail_helper + PrimitiveUnsigned, U: PrimitiveUnsigned>() { assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_desc(&U::ZERO, digits.iter().copied()); }); assert_panic!({ let digits: &[U] = &[U::ONE]; T::from_digits_desc(&U::ONE, digits.iter().copied()); }); } #[test] fn from_digits_asc_fail() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_asc_fail_helper); } #[test] fn from_digits_desc_fail() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_desc_fail_helper); } fn from_digits_asc_helper< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() { unsigned_vec_unsigned_pair_gen_var_9::().test_properties(|(digits, base)| { T::from_digits_asc(&base, digits.iter().copied()); }); unsigned_vec_unsigned_pair_gen_var_8::().test_properties(|(digits, base)| { let n = T::from_digits_asc(&base, digits.iter().copied()).unwrap(); assert_eq!( T::from_digits_desc(&base, digits.iter().rev().copied()).unwrap(), n ); let trailing_zeros = slice_trailing_zeros(&digits); assert_eq!( Digits::::to_digits_asc(&n, &base), &digits[..digits.len() - trailing_zeros] ); }); unsigned_pair_gen_var_10::().test_properties(|(base, u)| { assert_eq!( T::from_digits_asc(&base, repeat_n(U::ZERO, u)).unwrap(), T::ZERO ); }); } #[test] fn from_digits_asc_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_asc_helper); } fn from_digits_desc_helper< T: Digits + PrimitiveUnsigned, U: PrimitiveUnsigned + SaturatingFrom, >() { unsigned_vec_unsigned_pair_gen_var_9::().test_properties(|(digits, base)| { T::from_digits_asc(&base, digits.iter().copied()); }); unsigned_vec_unsigned_pair_gen_var_7::().test_properties(|(digits, base)| { let n = T::from_digits_desc(&base, digits.iter().copied()).unwrap(); assert_eq!( T::from_digits_asc(&base, digits.iter().rev().copied()).unwrap(), n ); let leading_zeros = slice_leading_zeros(&digits); assert_eq!( Digits::::to_digits_desc(&n, &base), &digits[leading_zeros..] ); }); unsigned_pair_gen_var_10::().test_properties(|(base, u)| { assert_eq!( T::from_digits_desc(&base, repeat_n(U::ZERO, u)).unwrap(), T::ZERO ); }); } #[test] fn from_digits_desc_properties() { apply_fn_to_unsigneds_and_unsigneds!(from_digits_desc_helper); }