use crate::integer::Integer;
use crate::integer_polynomial::arithmetic::mul::kronecker::mul_to_out_kronecker;
use crate::integer_polynomial::arithmetic::mul::schonhage_strassen::*;
use crate::integer_polynomial::arithmetic::mul_high::classical::mul_high_to_out_classical;
use crate::integer_polynomial::arithmetic::mul_high::karatsuba::mul_high_to_out_karatsuba_n;
use crate::integer_polynomial::arithmetic::vec::max_limbs::vec_max_limbs;
use crate::platform::Limb;
use core::cmp::max;
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::conversion::traits::ExactFrom;
pub mod classical;
pub mod karatsuba;
crate_test_fn! {mul_high_to_out(out: &mut [Integer], xs: &[Integer], ys: &[Integer], start: usize) {
let limbs1 = vec_max_limbs(xs);
let limbs2 = vec_max_limbs(ys);
let limbsx = max(limbs1, limbs2);
if start < 5 {
mul_high_to_out_classical(out, xs, ys, start);
return;
}
if limbsx > 4 && start < 17 && xs.len() == start + 1 && ys.len() == start + 1 {
mul_high_to_out_karatsuba_n(out, xs, ys);
} else {
let limbs = limbs1 + limbs2;
let len = u64::exact_from(xs.len() + ys.len());
if limbs <= 8 || limbs >> 11 > len || (limbs << Limb::LOG_WIDTH << 2) < len {
mul_to_out_kronecker(out, xs, ys);
} else {
mul_to_out_schonhage_strassen(out, xs, ys);
}
}
}}